]> err.no Git - linux-2.6/blobdiff - drivers/scsi/scsi_lib.c
[PATCH] dvb: usb: digitv: support for nxt6000 demod
[linux-2.6] / drivers / scsi / scsi_lib.c
index 3f3accd6cd46141d2b08af77787590d75c8728ec..77f2d444f7e0c7b6d297db390fcc2561d14ec36b 100644 (file)
@@ -282,7 +282,7 @@ void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer,
 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
@@ -291,13 +291,14 @@ EXPORT_SYMBOL(scsi_wait_req);
  * @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);
@@ -314,7 +315,7 @@ int scsi_execute_req(struct scsi_device *sdev, unsigned char *cmd,
        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
@@ -327,7 +328,30 @@ int scsi_execute_req(struct scsi_device *sdev, 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;
+       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);
 
 /*
@@ -903,17 +927,20 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
                                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:
@@ -930,15 +957,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
                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
@@ -1613,7 +1638,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
@@ -1633,26 +1658,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;
 
@@ -1672,12 +1693,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
@@ -1686,11 +1705,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
                                 */
@@ -1717,7 +1734,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
                }
        }
 
-       kfree(sense_buffer);
        return result;
 }
 EXPORT_SYMBOL(scsi_mode_sense);
@@ -1728,17 +1744,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;