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>
This commit is contained in:
parent
61aaff49e2
commit
cde76fbf1f
|
@ -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;
|
||||
|
|
|
@ -301,6 +301,27 @@ isci_task_set_completion_status(
|
|||
task->task_status.stat = status;
|
||||
|
||||
switch (task_notification_selection) {
|
||||
|
||||
case isci_perform_error_io_completion:
|
||||
|
||||
if (task->task_proto == SAS_PROTOCOL_SMP) {
|
||||
/* There is no error escalation in the SMP case.
|
||||
* Convert to a normal completion to avoid the
|
||||
* timeout in the discovery path and to let the
|
||||
* next action take place quickly.
|
||||
*/
|
||||
task_notification_selection
|
||||
= isci_perform_normal_io_completion;
|
||||
|
||||
/* Fall through to the normal case... */
|
||||
} else {
|
||||
/* Use sas_task_abort */
|
||||
/* Leave SAS_TASK_STATE_DONE clear
|
||||
* Leave SAS_TASK_AT_INITIATOR set.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
case isci_perform_aborted_io_completion:
|
||||
/* This path can occur with task-managed requests as well as
|
||||
* requests terminated because of LUN or device resets.
|
||||
|
@ -313,12 +334,6 @@ isci_task_set_completion_status(
|
|||
default:
|
||||
WARN_ONCE(1, "unknown task_notification_selection: %d\n",
|
||||
task_notification_selection);
|
||||
/* Fall through to the error case... */
|
||||
case isci_perform_error_io_completion:
|
||||
/* Use sas_task_abort */
|
||||
/* Leave SAS_TASK_STATE_DONE clear
|
||||
* Leave SAS_TASK_AT_INITIATOR set.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue