]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/scsi_error.c
[SCSI] lpfc 8.2.8 : Update driver to use new Host byte error code DID_TRANSPORT_DISRUPTED
[linux-2.6-omap-h63xx.git] / drivers / scsi / scsi_error.c
index fecefa05cb62c4f586a1f1ed7183c4f93cbac902..ad019ece21391c8dc1c653fdc92703a94e7149dc 100644 (file)
@@ -1218,6 +1218,40 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q,
        return;
 }
 
+/**
+ * scsi_noretry_cmd - determinte if command should be failed fast
+ * @scmd:      SCSI cmd to examine.
+ */
+int scsi_noretry_cmd(struct scsi_cmnd *scmd)
+{
+       switch (host_byte(scmd->result)) {
+       case DID_OK:
+               break;
+       case DID_BUS_BUSY:
+               return blk_failfast_transport(scmd->request);
+       case DID_PARITY:
+               return blk_failfast_dev(scmd->request);
+       case DID_ERROR:
+               if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
+                   status_byte(scmd->result) == RESERVATION_CONFLICT)
+                       return 0;
+               /* fall through */
+       case DID_SOFT_ERROR:
+               return blk_failfast_driver(scmd->request);
+       }
+
+       switch (status_byte(scmd->result)) {
+       case CHECK_CONDITION:
+               /*
+                * assume caller has checked sense and determinted
+                * the check condition was retryable.
+                */
+               return blk_failfast_dev(scmd->request);
+       }
+
+       return 0;
+}
+
 /**
  * scsi_decide_disposition - Disposition a cmd on return from LLD.
  * @scmd:      SCSI cmd to examine.
@@ -1290,7 +1324,20 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 
        case DID_REQUEUE:
                return ADD_TO_MLQUEUE;
-
+       case DID_TRANSPORT_DISRUPTED:
+               /*
+                * LLD/transport was disrupted during processing of the IO.
+                * The transport class is now blocked/blocking,
+                * and the transport will decide what to do with the IO
+                * based on its timers and recovery capablilities.
+                */
+               return ADD_TO_MLQUEUE;
+       case DID_TRANSPORT_FAILFAST:
+               /*
+                * The transport decided to failfast the IO (most likely
+                * the fast io fail tmo fired), so send IO directly upwards.
+                */
+               return SUCCESS;
        case DID_ERROR:
                if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
                    status_byte(scmd->result) == RESERVATION_CONFLICT)
@@ -1383,7 +1430,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
         * even if the request is marked fast fail, we still requeue
         * for queue congestion conditions (QUEUE_FULL or BUSY) */
        if ((++scmd->retries) <= scmd->allowed
-           && !blk_noretry_request(scmd->request)) {
+           && !scsi_noretry_cmd(scmd)) {
                return NEEDS_RETRY;
        } else {
                /*
@@ -1508,7 +1555,7 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
        list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
                list_del_init(&scmd->eh_entry);
                if (scsi_device_online(scmd->device) &&
-                   !blk_noretry_request(scmd->request) &&
+                   !scsi_noretry_cmd(scmd) &&
                    (++scmd->retries <= scmd->allowed)) {
                        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush"
                                                          " retry cmd: %p\n",