EXPORT_SYMBOL(scsi_wait_req);
/**
- * scsi_execute_req - insert request and wait for the result
+ * scsi_execute - insert request and wait for the result
* @sdev: scsi device
* @cmd: scsi command
* @data_direction: data direction
* @sense: optional sense buffer
* @timeout: request timeout in seconds
* @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_req(struct scsi_device *sdev, unsigned char *cmd,
- int data_direction, void *buffer, unsigned bufflen,
- unsigned char *sense, int timeout, int retries)
+int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
+ int data_direction, void *buffer, unsigned bufflen,
+ unsigned char *sense, int timeout, int retries, int flags)
{
struct request *req;
int write = (data_direction == DMA_TO_DEVICE);
req->sense = sense;
req->sense_len = 0;
req->timeout = timeout;
- req->flags |= REQ_BLOCK_PC | REQ_SPECIAL;
+ req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET;
/*
* head injection *required* here otherwise quiesce won't work
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;
+ int result;
+
+ if (sshdr) {
+ sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+ if (!sense)
+ return DRIVER_ERROR << 24;
+ memset(sense, 0, SCSI_SENSE_BUFFERSIZE);
+ }
+ result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
+ sense, timeout, retries, 0);
+ if (sshdr)
+ scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr);
+ kfree(sense);
+ return result;
+}
EXPORT_SYMBOL(scsi_execute_req);
/*
scsi_requeue_command(q, cmd);
return;
}
- printk(KERN_INFO "Device %s not ready.\n",
- req->rq_disk ? req->rq_disk->disk_name : "");
+ if (!(req->flags & REQ_QUIET))
+ dev_printk(KERN_INFO,
+ &cmd->device->sdev_gendev,
+ "Device not ready.\n");
cmd = scsi_end_request(cmd, 0, this_count, 1);
return;
case VOLUME_OVERFLOW:
- printk(KERN_INFO "Volume overflow <%d %d %d %d> CDB: ",
- cmd->device->host->host_no,
- (int)cmd->device->channel,
- (int)cmd->device->id, (int)cmd->device->lun);
- __scsi_print_command(cmd->data_cmnd);
- scsi_print_sense("", cmd);
+ if (!(req->flags & REQ_QUIET)) {
+ dev_printk(KERN_INFO,
+ &cmd->device->sdev_gendev,
+ "Volume overflow, CDB: ");
+ __scsi_print_command(cmd->data_cmnd);
+ scsi_print_sense("", cmd);
+ }
cmd = scsi_end_request(cmd, 0, block_bytes, 1);
return;
default:
return;
}
if (result) {
- if (!(req->flags & REQ_SPECIAL))
- printk(KERN_INFO "SCSI error : <%d %d %d %d> return code "
- "= 0x%x\n", cmd->device->host->host_no,
- cmd->device->channel,
- cmd->device->id,
- cmd->device->lun, result);
-
- if (driver_byte(result) & DRIVER_SENSE)
- scsi_print_sense("", cmd);
+ if (!(req->flags & REQ_QUIET)) {
+ dev_printk(KERN_INFO, &cmd->device->sdev_gendev,
+ "SCSI error: return code = 0x%x\n", result);
+
+ if (driver_byte(result) & DRIVER_SENSE)
+ scsi_print_sense("", cmd);
+ }
/*
* Mark a single buffer as not uptodate. Queue the remainder.
* We sometimes get this cruft in the event that a medium error
}
}
/**
- * __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
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;
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
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
*/
}
}
- kfree(sense_buffer);
return result;
}
EXPORT_SYMBOL(scsi_mode_sense);
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;