Skip to content

Commit

Permalink
[SCSI] convert sd to scsi_execute_req (and update the scsi_execute_re…
Browse files Browse the repository at this point in the history
…q API)

This one removes struct scsi_request entirely from sd.  In the process,
I noticed we have no callers of scsi_wait_req who don't immediately
normalise the sense, so I updated the API to make it take a struct
scsi_sense_hdr instead of simply a big sense buffer.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
James Bottomley committed Aug 28, 2005
1 parent 33aa687 commit ea73a9f
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 173 deletions.
48 changes: 26 additions & 22 deletions drivers/scsi/constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -1156,15 +1156,38 @@ scsi_show_extd_sense(unsigned char asc, unsigned char ascq)
}
}

void
scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr)
{
const char *sense_txt;
/* An example of deferred is when an earlier write to disk cache
* succeeded, but now the disk discovers that it cannot write the
* data to the magnetic media.
*/
const char *error = scsi_sense_is_deferred(sshdr) ?
"<<DEFERRED>>" : "Current";
printk(KERN_INFO "%s: %s", name, error);
if (sshdr->response_code >= 0x72)
printk(" [descriptor]");

sense_txt = scsi_sense_key_string(sshdr->sense_key);
if (sense_txt)
printk(": sense key: %s\n", sense_txt);
else
printk(": sense key=0x%x\n", sshdr->sense_key);
printk(KERN_INFO " ");
scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
printk("\n");
}
EXPORT_SYMBOL(scsi_print_sense_hdr);

/* Print sense information */
void
__scsi_print_sense(const char *name, const unsigned char *sense_buffer,
int sense_len)
{
int k, num, res;
unsigned int info;
const char *error;
const char *sense_txt;
struct scsi_sense_hdr ssh;

res = scsi_normalize_sense(sense_buffer, sense_len, &ssh);
Expand All @@ -1182,26 +1205,7 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
printk("\n");
return;
}

/* An example of deferred is when an earlier write to disk cache
* succeeded, but now the disk discovers that it cannot write the
* data to the magnetic media.
*/
error = scsi_sense_is_deferred(&ssh) ?
"<<DEFERRED>>" : "Current";
printk(KERN_INFO "%s: %s", name, error);
if (ssh.response_code >= 0x72)
printk(" [descriptor]");

sense_txt = scsi_sense_key_string(ssh.sense_key);
if (sense_txt)
printk(": sense key: %s\n", sense_txt);
else
printk(": sense key=0x%x\n", ssh.sense_key);
printk(KERN_INFO " ");
scsi_show_extd_sense(ssh.asc, ssh.ascq);
printk("\n");

scsi_print_sense_hdr(name, &ssh);
if (ssh.response_code < 0x72) {
/* only decode extras for "fixed" format now */
char buff[80];
Expand Down
15 changes: 6 additions & 9 deletions drivers/scsi/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,16 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
{
int result;
struct scsi_sense_hdr sshdr;
char sense[SCSI_SENSE_BUFFERSIZE];

SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));


memset(sense, 0, sizeof(*sense));
result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
sense, timeout, retries);
&sshdr, timeout, retries);

SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", result));

if ((driver_byte(result) & DRIVER_SENSE) &&
(scsi_normalize_sense(sense, sizeof(*sense), &sshdr))) {
(scsi_sense_valid(&sshdr))) {
switch (sshdr.sense_key) {
case ILLEGAL_REQUEST:
if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
Expand Down Expand Up @@ -132,7 +129,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
sdev->id,
sdev->lun,
result);
__scsi_print_sense(" ", sense, sizeof(*sense));
scsi_print_sense_hdr(" ", &sshdr);
break;
}
}
Expand Down Expand Up @@ -315,9 +312,9 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
break;
}

result = scsi_execute_req(sdev, cmd, data_direction, buf, needed,
sense, timeout, retries);
result = scsi_execute(sdev, cmd, data_direction, buf, needed,
sense, timeout, retries, 0);

/*
* If there was an error condition, pass the info back to the user.
*/
Expand Down
67 changes: 39 additions & 28 deletions drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ EXPORT_SYMBOL(scsi_wait_req);
* @retries: number of times to retry request
* @flags: or into request flags;
*
* scsi_execute_req returns the req->errors value which is the
* the scsi_cmnd result field.
* returns the req->errors value which is the the scsi_cmnd result
* field.
**/
int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen,
Expand Down Expand Up @@ -328,9 +328,31 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,

return ret;
}

EXPORT_SYMBOL(scsi_execute);


int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen,
struct scsi_sense_hdr *sshdr, int timeout, int retries)
{
char *sense = NULL;

if (sshdr) {
sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
if (!sense)
return DRIVER_ERROR << 24;
memset(sense, 0, sizeof(*sense));
}
int result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
sense, timeout, retries, 0);
if (sshdr)
scsi_normalize_sense(sense, sizeof(*sense), sshdr);

kfree(sense);
return result;
}
EXPORT_SYMBOL(scsi_execute_req);

/*
* Function: scsi_init_cmd_errh()
*
Expand Down Expand Up @@ -1614,7 +1636,7 @@ void scsi_exit_queue(void)
}
}
/**
* __scsi_mode_sense - issue a mode sense, falling back from 10 to
* scsi_mode_sense - issue a mode sense, falling back from 10 to
* six bytes if necessary.
* @sdev: SCSI device to be queried
* @dbd: set if mode sense will allow block descriptors to be returned
Expand All @@ -1634,26 +1656,22 @@ void scsi_exit_queue(void)
int
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
unsigned char *buffer, int len, int timeout, int retries,
struct scsi_mode_data *data, char *sense) {
struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) {
unsigned char cmd[12];
int use_10_for_ms;
int header_length;
int result;
char *sense_buffer = NULL;
struct scsi_sense_hdr my_sshdr;

memset(data, 0, sizeof(*data));
memset(&cmd[0], 0, 12);
cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
cmd[2] = modepage;

if (!sense) {
sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
if (!sense_buffer) {
dev_printk(KERN_ERR, &sdev->sdev_gendev, "failed to allocate sense buffer\n");
return 0;
}
sense = sense_buffer;
}
/* caller might not be interested in sense, but we need it */
if (!sshdr)
sshdr = &my_sshdr;

retry:
use_10_for_ms = sdev->use_10_for_ms;

Expand All @@ -1673,12 +1691,10 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
header_length = 4;
}

memset(sense, 0, SCSI_SENSE_BUFFERSIZE);

memset(buffer, 0, len);

result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
sense, timeout, retries);
sshdr, timeout, retries);

/* This code looks awful: what it's doing is making sure an
* ILLEGAL REQUEST sense return identifies the actual command
Expand All @@ -1687,11 +1703,9 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,

if (use_10_for_ms && !scsi_status_is_good(result) &&
(driver_byte(result) & DRIVER_SENSE)) {
struct scsi_sense_hdr sshdr;

if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) {
if ((sshdr.sense_key == ILLEGAL_REQUEST) &&
(sshdr.asc == 0x20) && (sshdr.ascq == 0)) {
if (scsi_sense_valid(sshdr)) {
if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
(sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
/*
* Invalid command operation code
*/
Expand All @@ -1718,7 +1732,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
}
}

kfree(sense_buffer);
return result;
}
EXPORT_SYMBOL(scsi_mode_sense);
Expand All @@ -1729,17 +1742,15 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
char cmd[] = {
TEST_UNIT_READY, 0, 0, 0, 0, 0,
};
char sense[SCSI_SENSE_BUFFERSIZE];
struct scsi_sense_hdr sshdr;
int result;

result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sense,
result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, &sshdr,
timeout, retries);

if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) {
struct scsi_sense_hdr sshdr;

if ((scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE,
&sshdr)) &&
if ((scsi_sense_valid(&sshdr)) &&
((sshdr.sense_key == UNIT_ATTENTION) ||
(sshdr.sense_key == NOT_READY))) {
sdev->changed = 1;
Expand Down
13 changes: 4 additions & 9 deletions drivers/scsi/scsi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,6 @@ void scsi_target_reap(struct scsi_target *starget)
static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
int result_len, int *bflags)
{
char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
int first_inquiry_len, try_inquiry_len, next_inquiry_len;
int response_len = 0;
Expand Down Expand Up @@ -474,11 +473,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = (unsigned char) try_inquiry_len;

memset(sense, 0, sizeof(sense));
memset(inq_result, 0, try_inquiry_len);

result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
inq_result, try_inquiry_len, sense,
inq_result, try_inquiry_len, &sshdr,
HZ / 2 + HZ * scsi_inq_timeout, 3);

SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
Expand All @@ -493,8 +491,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
* but many buggy devices do so anyway.
*/
if ((driver_byte(result) & DRIVER_SENSE) &&
scsi_normalize_sense(sense, sizeof(sense),
&sshdr)) {
scsi_sense_valid(&sshdr)) {
if ((sshdr.sense_key == UNIT_ATTENTION) &&
((sshdr.asc == 0x28) ||
(sshdr.asc == 0x29)) &&
Expand Down Expand Up @@ -1057,7 +1054,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
int rescan)
{
char devname[64];
char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
unsigned int length;
unsigned int lun;
Expand Down Expand Up @@ -1134,17 +1130,16 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
" REPORT LUNS to %s (try %d)\n", devname,
retries));

memset(sense, 0, sizeof(sense));
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
lun_data, length, sense,
lun_data, length, &sshdr,
SCSI_TIMEOUT + 4 * HZ, 3);

SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
" %s (try %d) result 0x%x\n", result
? "failed" : "successful", retries, result));
if (result == 0)
break;
else if (scsi_normalize_sense(sense, sizeof(sense), &sshdr)) {
else if (scsi_sense_valid(&sshdr)) {
if (sshdr.sense_key != UNIT_ATTENTION)
break;
}
Expand Down
Loading

0 comments on commit ea73a9f

Please sign in to comment.