[PATCH] ratelimit the ieee1394 IR legacy activated messages
[powerpc.git] / drivers / scsi / scsi_error.c
index 173abb8..ceb4e0c 100644 (file)
@@ -79,11 +79,6 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
         */
        scmd->owner = SCSI_OWNER_ERROR_HANDLER;
        scmd->state = SCSI_STATE_FAILED;
-       /*
-        * Set the serial_number_at_timeout to the current
-        * serial_number
-        */
-       scmd->serial_number_at_timeout = scmd->serial_number;
        list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
        set_bit(SHOST_RECOVERY, &shost->shost_state);
        shost->host_failed++;
@@ -439,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);
 }
 
 /**
@@ -462,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);
        }
 }
 
@@ -481,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;
@@ -492,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.
@@ -532,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;
@@ -588,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)) {
@@ -741,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
@@ -756,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);
 }
 
 /**
@@ -774,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));
@@ -784,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;
@@ -798,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.
@@ -869,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;
@@ -900,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;
@@ -912,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;
@@ -926,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.
@@ -1061,14 +1049,11 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
                                          __FUNCTION__));
        scmd->owner = SCSI_OWNER_LOWLEVEL;
-       scmd->serial_number_at_timeout = scmd->serial_number;
 
        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)
@@ -1093,14 +1078,11 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
                                          __FUNCTION__));
        scmd->owner = SCSI_OWNER_LOWLEVEL;
-       scmd->serial_number_at_timeout = scmd->serial_number;
 
        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)
@@ -1313,6 +1295,9 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
        case DID_IMM_RETRY:
                return NEEDS_RETRY;
 
+       case DID_REQUEUE:
+               return ADD_TO_MLQUEUE;
+
        case DID_ERROR:
                if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
                    status_byte(scmd->result) == RESERVATION_CONFLICT)
@@ -1564,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"
@@ -1873,7 +1863,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
                rtn = FAILED;
        }
 
-       scsi_delete_timer(scmd);
        scsi_next_command(scmd);
        return rtn;
 }