diff options
author | Jeff Skirvin <jeffrey.d.skirvin@intel.com> | 2011-06-20 14:09:06 -0700 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 04:04:50 -0700 |
commit | cde76fbf1f27551a08860227765ae8d5026ac0d9 (patch) | |
tree | 15b05ab39908e634cd633232025025d54a94a0ed /drivers/scsi/isci/request.c | |
parent | 61aaff49e20fdb700f1300a49962bc76effc77fc (diff) |
isci: Add decode for SMP request retry error condition
There are situations with slow expanders in which a first attempt
to execute an SMP request will fail with a timeout. Immediate
subsequent retries will generally succeed. This change makes sure
SMP I/O failures are immediately failed to libsas so that retries
happen with no discovery process timeout delay.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r-- | drivers/scsi/isci/request.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 8bd1f7dbad3..3a891d32c33 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -2508,9 +2508,16 @@ static void isci_request_handle_controller_specific_errors( /* Task in the target is not done. */ *response_ptr = SAS_TASK_UNDELIVERED; *status_ptr = SAM_STAT_TASK_ABORTED; - request->complete_in_target = false; - *complete_to_host_ptr = isci_perform_error_io_completion; + if (task->task_proto == SAS_PROTOCOL_SMP) { + request->complete_in_target = true; + + *complete_to_host_ptr = isci_perform_normal_io_completion; + } else { + request->complete_in_target = false; + + *complete_to_host_ptr = isci_perform_error_io_completion; + } break; } } @@ -2882,6 +2889,21 @@ static void isci_request_io_request_complete(struct isci_host *isci_host, request->complete_in_target = false; break; + case SCI_FAILURE_RETRY_REQUIRED: + + /* Fail the I/O so it can be retried. */ + response = SAS_TASK_UNDELIVERED; + if ((isci_device->status == isci_stopping) || + (isci_device->status == isci_stopped)) + status = SAS_DEVICE_UNKNOWN; + else + status = SAS_ABORTED_TASK; + + complete_to_host = isci_perform_normal_io_completion; + request->complete_in_target = true; + break; + + default: /* Catch any otherwise unhandled error codes here. */ dev_warn(&isci_host->pdev->dev, @@ -2901,8 +2923,13 @@ static void isci_request_io_request_complete(struct isci_host *isci_host, else status = SAS_ABORTED_TASK; - complete_to_host = isci_perform_error_io_completion; - request->complete_in_target = false; + if (SAS_PROTOCOL_SMP == task->task_proto) { + request->complete_in_target = true; + complete_to_host = isci_perform_normal_io_completion; + } else { + request->complete_in_target = false; + complete_to_host = isci_perform_error_io_completion; + } break; } break; |