Commit ea73a9f2 authored by James Bottomley's avatar James Bottomley

[SCSI] convert sd to scsi_execute_req (and update the scsi_execute_req 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: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 33aa687d
...@@ -1156,6 +1156,31 @@ scsi_show_extd_sense(unsigned char asc, unsigned char ascq) ...@@ -1156,6 +1156,31 @@ 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 */ /* Print sense information */
void void
__scsi_print_sense(const char *name, const unsigned char *sense_buffer, __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
...@@ -1163,8 +1188,6 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, ...@@ -1163,8 +1188,6 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
{ {
int k, num, res; int k, num, res;
unsigned int info; unsigned int info;
const char *error;
const char *sense_txt;
struct scsi_sense_hdr ssh; struct scsi_sense_hdr ssh;
res = scsi_normalize_sense(sense_buffer, sense_len, &ssh); res = scsi_normalize_sense(sense_buffer, sense_len, &ssh);
...@@ -1182,26 +1205,7 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, ...@@ -1182,26 +1205,7 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
printk("\n"); printk("\n");
return; return;
} }
scsi_print_sense_hdr(name, &ssh);
/* 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");
if (ssh.response_code < 0x72) { if (ssh.response_code < 0x72) {
/* only decode extras for "fixed" format now */ /* only decode extras for "fixed" format now */
char buff[80]; char buff[80];
......
...@@ -90,19 +90,16 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, ...@@ -90,19 +90,16 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
{ {
int result; int result;
struct scsi_sense_hdr sshdr; struct scsi_sense_hdr sshdr;
char sense[SCSI_SENSE_BUFFERSIZE];
SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd)); 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, 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)); SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", result));
if ((driver_byte(result) & DRIVER_SENSE) && if ((driver_byte(result) & DRIVER_SENSE) &&
(scsi_normalize_sense(sense, sizeof(*sense), &sshdr))) { (scsi_sense_valid(&sshdr))) {
switch (sshdr.sense_key) { switch (sshdr.sense_key) {
case ILLEGAL_REQUEST: case ILLEGAL_REQUEST:
if (cmd[0] == ALLOW_MEDIUM_REMOVAL) if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
...@@ -132,7 +129,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, ...@@ -132,7 +129,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
sdev->id, sdev->id,
sdev->lun, sdev->lun,
result); result);
__scsi_print_sense(" ", sense, sizeof(*sense)); scsi_print_sense_hdr(" ", &sshdr);
break; break;
} }
} }
...@@ -315,9 +312,9 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, ...@@ -315,9 +312,9 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
break; break;
} }
result = scsi_execute_req(sdev, cmd, data_direction, buf, needed, result = scsi_execute(sdev, cmd, data_direction, buf, needed,
sense, timeout, retries); sense, timeout, retries, 0);
/* /*
* If there was an error condition, pass the info back to the user. * If there was an error condition, pass the info back to the user.
*/ */
......
...@@ -293,8 +293,8 @@ EXPORT_SYMBOL(scsi_wait_req); ...@@ -293,8 +293,8 @@ EXPORT_SYMBOL(scsi_wait_req);
* @retries: number of times to retry request * @retries: number of times to retry request
* @flags: or into request flags; * @flags: or into request flags;
* *
* scsi_execute_req returns the req->errors value which is the * returns the req->errors value which is the the scsi_cmnd result
* the scsi_cmnd result field. * field.
**/ **/
int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen, int data_direction, void *buffer, unsigned bufflen,
...@@ -328,9 +328,31 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, ...@@ -328,9 +328,31 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
return ret; return ret;
} }
EXPORT_SYMBOL(scsi_execute); 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() * Function: scsi_init_cmd_errh()
* *
...@@ -1614,7 +1636,7 @@ void scsi_exit_queue(void) ...@@ -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. * six bytes if necessary.
* @sdev: SCSI device to be queried * @sdev: SCSI device to be queried
* @dbd: set if mode sense will allow block descriptors to be returned * @dbd: set if mode sense will allow block descriptors to be returned
...@@ -1634,26 +1656,22 @@ void scsi_exit_queue(void) ...@@ -1634,26 +1656,22 @@ void scsi_exit_queue(void)
int int
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
unsigned char *buffer, int len, int timeout, int retries, 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]; unsigned char cmd[12];
int use_10_for_ms; int use_10_for_ms;
int header_length; int header_length;
int result; int result;
char *sense_buffer = NULL; struct scsi_sense_hdr my_sshdr;
memset(data, 0, sizeof(*data)); memset(data, 0, sizeof(*data));
memset(&cmd[0], 0, 12); memset(&cmd[0], 0, 12);
cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */ cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
cmd[2] = modepage; cmd[2] = modepage;
if (!sense) { /* caller might not be interested in sense, but we need it */
sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); if (!sshdr)
if (!sense_buffer) { sshdr = &my_sshdr;
dev_printk(KERN_ERR, &sdev->sdev_gendev, "failed to allocate sense buffer\n");
return 0;
}
sense = sense_buffer;
}
retry: retry:
use_10_for_ms = sdev->use_10_for_ms; use_10_for_ms = sdev->use_10_for_ms;
...@@ -1673,12 +1691,10 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, ...@@ -1673,12 +1691,10 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
header_length = 4; header_length = 4;
} }
memset(sense, 0, SCSI_SENSE_BUFFERSIZE);
memset(buffer, 0, len); memset(buffer, 0, len);
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, 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 /* This code looks awful: what it's doing is making sure an
* ILLEGAL REQUEST sense return identifies the actual command * ILLEGAL REQUEST sense return identifies the actual command
...@@ -1687,11 +1703,9 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, ...@@ -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) && if (use_10_for_ms && !scsi_status_is_good(result) &&
(driver_byte(result) & DRIVER_SENSE)) { (driver_byte(result) & DRIVER_SENSE)) {
struct scsi_sense_hdr sshdr; if (scsi_sense_valid(sshdr)) {
if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { (sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
if ((sshdr.sense_key == ILLEGAL_REQUEST) &&
(sshdr.asc == 0x20) && (sshdr.ascq == 0)) {
/* /*
* Invalid command operation code * Invalid command operation code
*/ */
...@@ -1718,7 +1732,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, ...@@ -1718,7 +1732,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
} }
} }
kfree(sense_buffer);
return result; return result;
} }
EXPORT_SYMBOL(scsi_mode_sense); EXPORT_SYMBOL(scsi_mode_sense);
...@@ -1729,17 +1742,15 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries) ...@@ -1729,17 +1742,15 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
char cmd[] = { char cmd[] = {
TEST_UNIT_READY, 0, 0, 0, 0, 0, TEST_UNIT_READY, 0, 0, 0, 0, 0,
}; };
char sense[SCSI_SENSE_BUFFERSIZE]; struct scsi_sense_hdr sshdr;
int result; 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); timeout, retries);
if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) { if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) {
struct scsi_sense_hdr sshdr;
if ((scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, if ((scsi_sense_valid(&sshdr)) &&
&sshdr)) &&
((sshdr.sense_key == UNIT_ATTENTION) || ((sshdr.sense_key == UNIT_ATTENTION) ||
(sshdr.sense_key == NOT_READY))) { (sshdr.sense_key == NOT_READY))) {
sdev->changed = 1; sdev->changed = 1;
......
...@@ -446,7 +446,6 @@ void scsi_target_reap(struct scsi_target *starget) ...@@ -446,7 +446,6 @@ void scsi_target_reap(struct scsi_target *starget)
static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
int result_len, int *bflags) int result_len, int *bflags)
{ {
char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char scsi_cmd[MAX_COMMAND_SIZE]; unsigned char scsi_cmd[MAX_COMMAND_SIZE];
int first_inquiry_len, try_inquiry_len, next_inquiry_len; int first_inquiry_len, try_inquiry_len, next_inquiry_len;
int response_len = 0; int response_len = 0;
...@@ -474,11 +473,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, ...@@ -474,11 +473,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
scsi_cmd[0] = INQUIRY; scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = (unsigned char) try_inquiry_len; scsi_cmd[4] = (unsigned char) try_inquiry_len;
memset(sense, 0, sizeof(sense));
memset(inq_result, 0, try_inquiry_len); memset(inq_result, 0, try_inquiry_len);
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, 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); HZ / 2 + HZ * scsi_inq_timeout, 3);
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s " SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
...@@ -493,8 +491,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, ...@@ -493,8 +491,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
* but many buggy devices do so anyway. * but many buggy devices do so anyway.
*/ */
if ((driver_byte(result) & DRIVER_SENSE) && if ((driver_byte(result) & DRIVER_SENSE) &&
scsi_normalize_sense(sense, sizeof(sense), scsi_sense_valid(&sshdr)) {
&sshdr)) {
if ((sshdr.sense_key == UNIT_ATTENTION) && if ((sshdr.sense_key == UNIT_ATTENTION) &&
((sshdr.asc == 0x28) || ((sshdr.asc == 0x28) ||
(sshdr.asc == 0x29)) && (sshdr.asc == 0x29)) &&
...@@ -1057,7 +1054,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1057,7 +1054,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
int rescan) int rescan)
{ {
char devname[64]; char devname[64];
char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char scsi_cmd[MAX_COMMAND_SIZE]; unsigned char scsi_cmd[MAX_COMMAND_SIZE];
unsigned int length; unsigned int length;
unsigned int lun; unsigned int lun;
...@@ -1134,9 +1130,8 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1134,9 +1130,8 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
" REPORT LUNS to %s (try %d)\n", devname, " REPORT LUNS to %s (try %d)\n", devname,
retries)); retries));
memset(sense, 0, sizeof(sense));
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
lun_data, length, sense, lun_data, length, &sshdr,
SCSI_TIMEOUT + 4 * HZ, 3); SCSI_TIMEOUT + 4 * HZ, 3);
SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS" SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
...@@ -1144,7 +1139,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1144,7 +1139,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
? "failed" : "successful", retries, result)); ? "failed" : "successful", retries, result));
if (result == 0) if (result == 0)
break; break;
else if (scsi_normalize_sense(sense, sizeof(sense), &sshdr)) { else if (scsi_sense_valid(&sshdr)) {
if (sshdr.sense_key != UNIT_ATTENTION) if (sshdr.sense_key != UNIT_ATTENTION)
break; break;
} }
......
...@@ -59,7 +59,6 @@ ...@@ -59,7 +59,6 @@
#include <scsi/scsi_eh.h> #include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/scsi_request.h>
#include <scsi/scsicam.h> #include <scsi/scsicam.h>
#include "scsi_logging.h" #include "scsi_logging.h"
...@@ -125,7 +124,7 @@ static int sd_issue_flush(struct device *, sector_t *); ...@@ -125,7 +124,7 @@ static int sd_issue_flush(struct device *, sector_t *);
static void sd_end_flush(request_queue_t *, struct request *); static void sd_end_flush(request_queue_t *, struct request *);
static int sd_prepare_flush(request_queue_t *, struct request *); static int sd_prepare_flush(request_queue_t *, struct request *);
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer); unsigned char *buffer);
static struct scsi_driver sd_template = { static struct scsi_driver sd_template = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -682,19 +681,13 @@ static int sd_media_changed(struct gendisk *disk) ...@@ -682,19 +681,13 @@ static int sd_media_changed(struct gendisk *disk)
static int sd_sync_cache(struct scsi_device *sdp) static int sd_sync_cache(struct scsi_device *sdp)
{ {
struct scsi_request *sreq;
int retries, res; int retries, res;
struct scsi_sense_hdr sshdr;
if (!scsi_device_online(sdp)) if (!scsi_device_online(sdp))
return -ENODEV; return -ENODEV;
sreq = scsi_allocate_request(sdp, GFP_KERNEL);
if (!sreq) {
printk("FAILED\n No memory for request\n");
return -ENOMEM;
}
sreq->sr_data_direction = DMA_NONE;
for (retries = 3; retries > 0; --retries) { for (retries = 3; retries > 0; --retries) {
unsigned char cmd[10] = { 0 }; unsigned char cmd[10] = { 0 };
...@@ -703,22 +696,20 @@ static int sd_sync_cache(struct scsi_device *sdp) ...@@ -703,22 +696,20 @@ static int sd_sync_cache(struct scsi_device *sdp)
* Leave the rest of the command zero to indicate * Leave the rest of the command zero to indicate
* flush everything. * flush everything.
*/ */
scsi_wait_req(sreq, cmd, NULL, 0, SD_TIMEOUT, SD_MAX_RETRIES); res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
if (sreq->sr_result == 0) SD_TIMEOUT, SD_MAX_RETRIES);
if (res == 0)
break; break;
} }
res = sreq->sr_result; if (res) { printk(KERN_WARNING "FAILED\n status = %x, message = %02x, "
if (res) {
printk(KERN_WARNING "FAILED\n status = %x, message = %02x, "
"host = %d, driver = %02x\n ", "host = %d, driver = %02x\n ",
status_byte(res), msg_byte(res), status_byte(res), msg_byte(res),
host_byte(res), driver_byte(res)); host_byte(res), driver_byte(res));
if (driver_byte(res) & DRIVER_SENSE) if (driver_byte(res) & DRIVER_SENSE)
scsi_print_req_sense("sd", sreq); scsi_print_sense_hdr("sd", &sshdr);
} }
scsi_release_request(sreq);
return res; return res;
} }
...@@ -957,22 +948,19 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) ...@@ -957,22 +948,19 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); scsi_io_completion(SCpnt, good_bytes, block_sectors << 9);
} }
static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp) static int media_not_present(struct scsi_disk *sdkp,
struct scsi_sense_hdr *sshdr)
{ {
struct scsi_sense_hdr sshdr;
if (!srp->sr_result) if (!scsi_sense_valid(sshdr))
return 0;
if (!(driver_byte(srp->sr_result) & DRIVER_SENSE))
return 0; return 0;
/* not invoked for commands that could return deferred errors */ /* not invoked for commands that could return deferred errors */
if (scsi_request_normalize_sense(srp, &sshdr)) { if (sshdr->sense_key != NOT_READY &&
if (sshdr.sense_key != NOT_READY && sshdr->sense_key != UNIT_ATTENTION)
sshdr.sense_key != UNIT_ATTENTION) return 0;
return 0; if (sshdr->asc != 0x3A) /* medium not present */
if (sshdr.asc != 0x3A) /* medium not present */ return 0;
return 0;
}
set_media_not_present(sdkp); set_media_not_present(sdkp);
return 1; return 1;
} }
...@@ -981,8 +969,8 @@ static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp) ...@@ -981,8 +969,8 @@ static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp)
* spinup disk - called only in sd_revalidate_disk() * spinup disk - called only in sd_revalidate_disk()
*/ */
static void static void
sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
struct scsi_request *SRpnt, unsigned char *buffer) { {
unsigned char cmd[10]; unsigned char cmd[10];
unsigned long spintime_value = 0; unsigned long spintime_value = 0;
int retries, spintime; int retries, spintime;
...@@ -1001,18 +989,13 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -1001,18 +989,13 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
cmd[0] = TEST_UNIT_READY; cmd[0] = TEST_UNIT_READY;
memset((void *) &cmd[1], 0, 9); memset((void *) &cmd[1], 0, 9);
SRpnt->sr_cmd_len = 0; the_result = scsi_execute_req(sdkp->device, cmd,
memset(SRpnt->sr_sense_buffer, 0, DMA_NONE, NULL, 0,
SCSI_SENSE_BUFFERSIZE); &sshdr, SD_TIMEOUT,
SRpnt->sr_data_direction = DMA_NONE; SD_MAX_RETRIES);
scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES);
the_result = SRpnt->sr_result;
if (the_result) if (the_result)
sense_valid = scsi_request_normalize_sense( sense_valid = scsi_sense_valid(&sshdr);
SRpnt, &sshdr);
retries++; retries++;
} while (retries < 3 && } while (retries < 3 &&
(!scsi_status_is_good(the_result) || (!scsi_status_is_good(the_result) ||
...@@ -1024,7 +1007,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -1024,7 +1007,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
* any media in it, don't bother with any of the rest of * any media in it, don't bother with any of the rest of
* this crap. * this crap.
*/ */
if (media_not_present(sdkp, SRpnt)) if (media_not_present(sdkp, &sshdr))
return; return;
if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { if ((driver_byte(the_result) & DRIVER_SENSE) == 0) {
...@@ -1063,14 +1046,9 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -1063,14 +1046,9 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
cmd[1] = 1; /* Return immediately */ cmd[1] = 1; /* Return immediately */
memset((void *) &cmd[2], 0, 8); memset((void *) &cmd[2], 0, 8);
cmd[4] = 1; /* Start spin cycle */ cmd[4] = 1; /* Start spin cycle */
SRpnt->sr_cmd_len = 0; scsi_execute_req(sdkp->device, cmd, DMA_NONE,
memset(SRpnt->sr_sense_buffer, 0, NULL, 0, &sshdr,
SCSI_SENSE_BUFFERSIZE); SD_TIMEOUT, SD_MAX_RETRIES);
SRpnt->sr_data_direction = DMA_NONE;
scsi_wait_req(SRpnt, (void *)cmd,
(void *) buffer, 0/*512*/,
SD_TIMEOUT, SD_MAX_RETRIES);
spintime_value = jiffies; spintime_value = jiffies;
} }
spintime = 1; spintime = 1;
...@@ -1083,7 +1061,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -1083,7 +1061,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
if(!spintime) { if(!spintime) {
printk(KERN_NOTICE "%s: Unit Not Ready, " printk(KERN_NOTICE "%s: Unit Not Ready, "
"sense:\n", diskname); "sense:\n", diskname);
scsi_print_req_sense("", SRpnt); scsi_print_sense_hdr("", &sshdr);
} }
break; break;
} }
...@@ -1104,14 +1082,15 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, ...@@ -1104,14 +1082,15 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
*/ */
static void static void
sd_read_capacity(struct scsi_disk *sdkp, char *diskname, sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) { unsigned char *buffer)
{
unsigned char cmd[16]; unsigned char cmd[16];
struct scsi_device *sdp = sdkp->device;
int the_result, retries; int the_result, retries;
int sector_size = 0; int sector_size = 0;
int longrc = 0; int longrc = 0;
struct scsi_sense_hdr sshdr; struct scsi_sense_hdr sshdr;
int sense_valid = 0; int sense_valid = 0;
struct scsi_device *sdp = sdkp->device;
repeat: repeat:
retries = 3; retries = 3;
...@@ -1128,20 +1107,15 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1128,20 +1107,15 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
memset((void *) buffer, 0, 8); memset((void *) buffer, 0, 8);
} }
SRpnt->sr_cmd_len = 0; the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
memset(SRpnt->sr_sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); buffer, longrc ? 12 : 8, &sshdr,
SRpnt->sr_data_direction = DMA_FROM_DEVICE; SD_TIMEOUT, SD_MAX_RETRIES);
scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
longrc ? 12 : 8, SD_TIMEOUT, SD_MAX_RETRIES);
if (media_not_present(sdkp, SRpnt)) if (media_not_present(sdkp, &sshdr))
return; return;
the_result = SRpnt->sr_result;
if (the_result) if (the_result)
sense_valid = scsi_request_normalize_sense(SRpnt, sense_valid = scsi_sense_valid(&sshdr);
&sshdr);
retries--; retries--;
} while (the_result && retries); } while (the_result && retries);
...@@ -1156,7 +1130,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1156,7 +1130,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
driver_byte(the_result)); driver_byte(the_result));
if (driver_byte(the_result) & DRIVER_SENSE) if (driver_byte(the_result) & DRIVER_SENSE)
scsi_print_req_sense("sd", SRpnt); scsi_print_sense_hdr("sd", &sshdr);
else else
printk("%s : sense not available. \n", diskname); printk("%s : sense not available. \n", diskname);
...@@ -1296,12 +1270,13 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1296,12 +1270,13 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
/* called with buffer of length 512 */ /* called with buffer of length 512 */
static inline int static inline int
sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage, sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage,
unsigned char *buffer, int len, struct scsi_mode_data *data) unsigned char *buffer, int len, struct scsi_mode_data *data,
struct scsi_sense_hdr *sshdr)
{ {
return scsi_mode_sense(SRpnt->sr_device, dbd, modepage, buffer, len, return scsi_mode_sense(sdp, dbd, modepage, buffer, len,
SD_TIMEOUT, SD_MAX_RETRIES, data, SD_TIMEOUT, SD_MAX_RETRIES, data,
SRpnt->sr_sense_buffer); sshdr);
} }
/* /*
...@@ -1310,25 +1285,27 @@ sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage, ...@@ -1310,25 +1285,27 @@ sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
*/ */
static void static void
sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) { unsigned char *buffer)
{
int res; int res;
struct scsi_device *sdp = sdkp->device;
struct scsi_mode_data data; struct scsi_mode_data data;
set_disk_ro(sdkp->disk, 0); set_disk_ro(sdkp->disk, 0);
if (sdkp->device->skip_ms_page_3f) { if (sdp->skip_ms_page_3f) {
printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname); printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname);
return; return;
} }
if (sdkp->device->use_192_bytes_for_3f) { if (sdp->use_192_bytes_for_3f) {
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 192, &data); res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 192, &data, NULL);
} else { } else {
/* /*
* First attempt: ask for all pages (0x3F), but only 4 bytes. * First attempt: ask for all pages (0x3F), but only 4 bytes.
* We have to start carefully: some devices hang if we ask * We have to start carefully: some devices hang if we ask
* for more than is available. * for more than is available.
*/ */
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4, &data); res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 4, &data, NULL);
/* /*
* Second attempt: ask for page 0 When only page 0 is * Second attempt: ask for page 0 When only page 0 is
...@@ -1337,14 +1314,14 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, ...@@ -1337,14 +1314,14 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
* CDB. * CDB.
*/ */
if (!scsi_status_is_good(res)) if (!scsi_status_is_good(res))
res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4, &data); res = sd_do_mode_sense(sdp, 0, 0, buffer, 4, &data, NULL);
/* /*
* Third attempt: ask 255 bytes, as we did earlier. * Third attempt: ask 255 bytes, as we did earlier.
*/ */
if (!scsi_status_is_good(res)) if (!scsi_status_is_good(res))
res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255, res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 255,
&data); &data, NULL);
} }
if (!scsi_status_is_good(res)) { if (!scsi_status_is_good(res)) {
...@@ -1366,19 +1343,20 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, ...@@ -1366,19 +1343,20 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
*/ */
static void static void
sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) unsigned char *buffer)
{ {
int len = 0, res; int len = 0, res;
struct scsi_device *sdp = sdkp->device;
int dbd; int dbd;
int modepage; int modepage;
struct scsi_mode_data data; struct scsi_mode_data data;
struct scsi_sense_hdr sshdr; struct scsi_sense_hdr sshdr;
if (sdkp->device->skip_ms_page_8) if (sdp->skip_ms_page_8)
goto defaults; goto defaults;
if (sdkp->device->type == TYPE_RBC) { if (sdp->type == TYPE_RBC) {
modepage = 6; modepage = 6;
dbd = 8; dbd = 8;
} else { } else {
...@@ -1387,7 +1365,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1387,7 +1365,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
} }
/* cautiously ask */ /* cautiously ask */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data); res = sd_do_mode_sense(sdp, dbd, modepage, buffer, 4, &data, &sshdr);
if (!scsi_status_is_good(res)) if (!scsi_status_is_good(res))
goto bad_sense; goto bad_sense;
...@@ -1408,7 +1386,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1408,7 +1386,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
len += data.header_length + data.block_descriptor_length; len += data.header_length + data.block_descriptor_length;
/* Get the data */ /* Get the data */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len, &data); res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
if (scsi_status_is_good(res)) { if (scsi_status_is_good(res)) {
const char *types[] = { const char *types[] = {
...@@ -1440,7 +1418,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1440,7 +1418,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
} }
bad_sense: bad_sense:
if (scsi_request_normalize_sense(SRpnt, &sshdr) && if (scsi_sense_valid(&sshdr) &&
sshdr.sense_key == ILLEGAL_REQUEST && sshdr.sense_key == ILLEGAL_REQUEST &&
sshdr.asc == 0x24 && sshdr.ascq == 0x0) sshdr.asc == 0x24 && sshdr.ascq == 0x0)
printk(KERN_NOTICE "%s: cache data unavailable\n", printk(KERN_NOTICE "%s: cache data unavailable\n",
...@@ -1465,7 +1443,6 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -1465,7 +1443,6 @@ static int sd_revalidate_disk(struct gendisk *disk)
{ {
struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device; struct scsi_device *sdp = sdkp->device;
struct scsi_request *sreq;
unsigned char *buffer; unsigned char *buffer;
SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
...@@ -1477,18 +1454,11 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -1477,18 +1454,11 @@ static int sd_revalidate_disk(struct gendisk *disk)
if (!scsi_device_online(sdp)) if (!scsi_device_online(sdp))
goto out; goto out;
sreq = scsi_allocate_request(sdp, GFP_KERNEL);
if (!sreq) {
printk(KERN_WARNING "(sd_revalidate_disk:) Request allocation "
"failure.\n");
goto out;
}
buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA); buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA);
if (!buffer) { if (!buffer) {
printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation "
"failure.\n"); "failure.\n");
goto out_release_request; goto out;
} }
/* defaults, until the device tells us otherwise */ /* defaults, until the device tells us otherwise */
...@@ -1499,25 +1469,23 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -1499,25 +1469,23 @@ static int sd_revalidate_disk(struct gendisk *disk)
sdkp->WCE = 0; sdkp->WCE = 0;
sdkp->RCD = 0; sdkp->RCD = 0;
sd_spinup_disk(sdkp, disk->disk_name, sreq, buffer); sd_spinup_disk(sdkp, disk->disk_name);
/* /*
* Without media there is no reason to ask; moreover, some devices * Without media there is no reason to ask; moreover, some devices
* react badly if we do. * react badly if we do.
*/ */
if (sdkp->media_present) { if (sdkp->media_present) {
sd_read_capacity(sdkp, disk->disk_name, sreq, buffer); sd_read_capacity(sdkp, disk->disk_name, buffer);
if (sdp->removable) if (sdp->removable)
sd_read_write_protect_flag(sdkp, disk->disk_name, sd_read_write_protect_flag(sdkp, disk->disk_name,
sreq, buffer); buffer);
sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer); sd_read_cache_type(sdkp, disk->disk_name, buffer);
} }
set_capacity(disk, sdkp->capacity); set_capacity(disk, sdkp->capacity);
kfree(buffer); kfree(buffer);
out_release_request:
scsi_release_request(sreq);
out: out:
return 0; return 0;
} }
......
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
struct scsi_cmnd; struct scsi_cmnd;
struct scsi_request; struct scsi_request;
struct scsi_sense_hdr;
extern void scsi_print_command(struct scsi_cmnd *); extern void scsi_print_command(struct scsi_cmnd *);
extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *);
extern void __scsi_print_command(unsigned char *); extern void __scsi_print_command(unsigned char *);
extern void scsi_print_sense(const char *, struct scsi_cmnd *); extern void scsi_print_sense(const char *, struct scsi_cmnd *);
extern void scsi_print_req_sense(const char *, struct scsi_request *); extern void scsi_print_req_sense(const char *, struct scsi_request *);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
struct request_queue; struct request_queue;
struct scsi_cmnd; struct scsi_cmnd;
struct scsi_lun; struct scsi_lun;
struct scsi_sense_hdr;
struct scsi_mode_data { struct scsi_mode_data {
__u32 length; __u32 length;
...@@ -237,7 +238,7 @@ extern int scsi_set_medium_removal(struct scsi_device *, char); ...@@ -237,7 +238,7 @@ extern int scsi_set_medium_removal(struct scsi_device *, char);
extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
unsigned char *buffer, int len, int timeout, unsigned char *buffer, int len, int timeout,
int retries, struct scsi_mode_data *data, int retries, struct scsi_mode_data *data,
char *sense); struct scsi_sense_hdr *);
extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
int retries); int retries);
extern int scsi_device_set_state(struct scsi_device *sdev, extern int scsi_device_set_state(struct scsi_device *sdev,
...@@ -260,15 +261,10 @@ extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, ...@@ -260,15 +261,10 @@ extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen, int data_direction, void *buffer, unsigned bufflen,
unsigned char *sense, int timeout, int retries, unsigned char *sense, int timeout, int retries,
int flag); int flag);
extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen,
struct scsi_sense_hdr *, int timeout, int retries);
static inline int
scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen,
unsigned char *sense, int timeout, int retries)
{
return scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense,
timeout, retries, 0);
}
static inline int scsi_device_online(struct scsi_device *sdev) static inline int scsi_device_online(struct scsi_device *sdev)
{ {
return sdev->sdev_state != SDEV_OFFLINE; return sdev->sdev_state != SDEV_OFFLINE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment