summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/request.c35
-rw-r--r--drivers/scsi/isci/task.h27
2 files changed, 52 insertions, 10 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;
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index 432b81aecd4..c8dd075d2be 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -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;
}