]> err.no Git - linux-2.6/blobdiff - drivers/scsi/scsi_error.c
Merge with rsync://fileserver/linux
[linux-2.6] / drivers / scsi / scsi_error.c
index 203a0812508a1962c2c9d58020d3a6a9bc61aaf5..ceb4e0c99b37eeac59e1f30a2316ad750f732e95 100644 (file)
@@ -434,8 +434,7 @@ static void scsi_eh_times_out(struct scsi_cmnd *scmd)
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
                                          scmd));
 
-       if (scmd->device->host->eh_action)
-               up(scmd->device->host->eh_action);
+       up(scmd->device->host->eh_action);
 }
 
 /**
@@ -457,8 +456,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
                SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
                                           __FUNCTION__, scmd, scmd->result));
 
-               if (scmd->device->host->eh_action)
-                       up(scmd->device->host->eh_action);
+               up(scmd->device->host->eh_action);
        }
 }
 
@@ -476,7 +474,8 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
  **/
 static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
 {
-       struct Scsi_Host *host = scmd->device->host;
+       struct scsi_device *sdev = scmd->device;
+       struct Scsi_Host *shost = sdev->host;
        DECLARE_MUTEX_LOCKED(sem);
        unsigned long flags;
        int rtn = SUCCESS;
@@ -487,27 +486,27 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
         */
        scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-       if (scmd->device->scsi_level <= SCSI_2)
+       if (sdev->scsi_level <= SCSI_2)
                scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
-                       (scmd->device->lun << 5 & 0xe0);
+                       (sdev->lun << 5 & 0xe0);
 
        scsi_add_timer(scmd, timeout, scsi_eh_times_out);
 
        /*
         * set up the semaphore so we wait for the command to complete.
         */
-       scmd->device->host->eh_action = &sem;
+       shost->eh_action = &sem;
        scmd->request->rq_status = RQ_SCSI_BUSY;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
+       spin_lock_irqsave(shost->host_lock, flags);
        scsi_log_send(scmd);
-       host->hostt->queuecommand(scmd, scsi_eh_done);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+       shost->hostt->queuecommand(scmd, scsi_eh_done);
+       spin_unlock_irqrestore(shost->host_lock, flags);
 
        down(&sem);
        scsi_log_completion(scmd, SUCCESS);
 
-       scmd->device->host->eh_action = NULL;
+       shost->eh_action = NULL;
 
        /*
         * see if timeout.  if so, tell the host to forget about it.
@@ -527,10 +526,8 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
                 * abort a timed out command or not.  not sure how
                 * we should treat them differently anyways.
                 */
-               spin_lock_irqsave(scmd->device->host->host_lock, flags);
-               if (scmd->device->host->hostt->eh_abort_handler)
-                       scmd->device->host->hostt->eh_abort_handler(scmd);
-               spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+               if (shost->hostt->eh_abort_handler)
+                       shost->hostt->eh_abort_handler(scmd);
                        
                scmd->request->rq_status = RQ_SCSI_DONE;
                scmd->owner = SCSI_OWNER_ERROR_HANDLER;
@@ -583,7 +580,7 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
 
        memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
 
-       scsi_result = kmalloc(252, GFP_ATOMIC | (scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0);
+       scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
 
 
        if (unlikely(!scsi_result)) {
@@ -736,11 +733,8 @@ static int scsi_eh_get_sense(struct list_head *work_q,
  **/
 static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
 {
-       unsigned long flags;
-       int rtn = FAILED;
-
        if (!scmd->device->host->hostt->eh_abort_handler)
-               return rtn;
+               return FAILED;
 
        /*
         * scsi_done was called just after the command timed out and before
@@ -751,11 +745,7 @@ static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
 
        scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
-       rtn = scmd->device->host->hostt->eh_abort_handler(scmd);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
-
-       return rtn;
+       return scmd->device->host->hostt->eh_abort_handler(scmd);
 }
 
 /**
@@ -769,6 +759,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
 {
        static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
        int retry_cnt = 1, rtn;
+       int saved_result;
 
 retry_tur:
        memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
@@ -779,6 +770,7 @@ retry_tur:
         */
        memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
+       saved_result = scmd->result;
        scmd->request_buffer = NULL;
        scmd->request_bufflen = 0;
        scmd->use_sg = 0;
@@ -793,6 +785,7 @@ retry_tur:
         * the original request, so let's restore the original data. (db)
         */
        scsi_setup_cmd_retry(scmd);
+       scmd->result = saved_result;
 
        /*
         * hey, we are done.  let's look to see what happened.
@@ -864,17 +857,14 @@ static int scsi_eh_abort_cmds(struct list_head *work_q,
  **/
 static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 {
-       unsigned long flags;
-       int rtn = FAILED;
+       int rtn;
 
        if (!scmd->device->host->hostt->eh_device_reset_handler)
-               return rtn;
+               return FAILED;
 
        scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
        rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
                scmd->device->was_reset = 1;
@@ -895,6 +885,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
 {
        static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
        int rtn;
+       int saved_result;
 
        if (!scmd->device->allow_restart)
                return 1;
@@ -907,6 +898,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
         */
        memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
+       saved_result = scmd->result;
        scmd->request_buffer = NULL;
        scmd->request_bufflen = 0;
        scmd->use_sg = 0;
@@ -921,6 +913,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
         * the original request, so let's restore the original data. (db)
         */
        scsi_setup_cmd_retry(scmd);
+       scmd->result = saved_result;
 
        /*
         * hey, we are done.  let's look to see what happened.
@@ -1060,9 +1053,7 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
        if (!scmd->device->host->hostt->eh_bus_reset_handler)
                return FAILED;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
        rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
                if (!scmd->device->host->hostt->skip_settle_delay)
@@ -1091,9 +1082,7 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
        if (!scmd->device->host->hostt->eh_host_reset_handler)
                return FAILED;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
        rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
                if (!scmd->device->host->hostt->skip_settle_delay)
@@ -1560,6 +1549,11 @@ static void scsi_eh_flush_done_q(struct list_head *done_q)
                                                          scmd));
                                scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
                } else {
+                       /*
+                        * If just we got sense for the device (called
+                        * scsi_eh_get_sense), scmd->result is already
+                        * set, do not set DRIVER_TIMEOUT.
+                        */
                        if (!scmd->result)
                                scmd->result |= (DRIVER_TIMEOUT << 24);
                        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush finish"
@@ -1869,7 +1863,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
                rtn = FAILED;
        }
 
-       scsi_delete_timer(scmd);
        scsi_next_command(scmd);
        return rtn;
 }