aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-06-20 17:09:06 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:50 -0400
commitcde76fbf1f27551a08860227765ae8d5026ac0d9 (patch)
tree15b05ab39908e634cd633232025025d54a94a0ed /drivers/scsi
parent61aaff49e20fdb700f1300a49962bc76effc77fc (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')
-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 8bd1f7dbad37..3a891d32c331 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(
2508 /* Task in the target is not done. */ 2508 /* Task in the target is not done. */
2509 *response_ptr = SAS_TASK_UNDELIVERED; 2509 *response_ptr = SAS_TASK_UNDELIVERED;
2510 *status_ptr = SAM_STAT_TASK_ABORTED; 2510 *status_ptr = SAM_STAT_TASK_ABORTED;
2511 request->complete_in_target = false;
2512 2511
2513 *complete_to_host_ptr = isci_perform_error_io_completion; 2512 if (task->task_proto == SAS_PROTOCOL_SMP) {
2513 request->complete_in_target = true;
2514
2515 *complete_to_host_ptr = isci_perform_normal_io_completion;
2516 } else {
2517 request->complete_in_target = false;
2518
2519 *complete_to_host_ptr = isci_perform_error_io_completion;
2520 }
2514 break; 2521 break;
2515 } 2522 }
2516} 2523}
@@ -2882,6 +2889,21 @@ static void isci_request_io_request_complete(struct isci_host *isci_host,
2882 request->complete_in_target = false; 2889 request->complete_in_target = false;
2883 break; 2890 break;
2884 2891
2892 case SCI_FAILURE_RETRY_REQUIRED:
2893
2894 /* Fail the I/O so it can be retried. */
2895 response = SAS_TASK_UNDELIVERED;
2896 if ((isci_device->status == isci_stopping) ||
2897 (isci_device->status == isci_stopped))
2898 status = SAS_DEVICE_UNKNOWN;
2899 else
2900 status = SAS_ABORTED_TASK;
2901
2902 complete_to_host = isci_perform_normal_io_completion;
2903 request->complete_in_target = true;
2904 break;
2905
2906
2885 default: 2907 default:
2886 /* Catch any otherwise unhandled error codes here. */ 2908 /* Catch any otherwise unhandled error codes here. */
2887 dev_warn(&isci_host->pdev->dev, 2909 dev_warn(&isci_host->pdev->dev,
@@ -2901,8 +2923,13 @@ static void isci_request_io_request_complete(struct isci_host *isci_host,
2901 else 2923 else
2902 status = SAS_ABORTED_TASK; 2924 status = SAS_ABORTED_TASK;
2903 2925
2904 complete_to_host = isci_perform_error_io_completion; 2926 if (SAS_PROTOCOL_SMP == task->task_proto) {
2905 request->complete_in_target = false; 2927 request->complete_in_target = true;
2928 complete_to_host = isci_perform_normal_io_completion;
2929 } else {
2930 request->complete_in_target = false;
2931 complete_to_host = isci_perform_error_io_completion;
2932 }
2906 break; 2933 break;
2907 } 2934 }
2908 break; 2935 break;
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index 432b81aecd47..c8dd075d2be2 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -301,6 +301,27 @@ isci_task_set_completion_status(
301 task->task_status.stat = status; 301 task->task_status.stat = status;
302 302
303 switch (task_notification_selection) { 303 switch (task_notification_selection) {
304
305 case isci_perform_error_io_completion:
306
307 if (task->task_proto == SAS_PROTOCOL_SMP) {
308 /* There is no error escalation in the SMP case.
309 * Convert to a normal completion to avoid the
310 * timeout in the discovery path and to let the
311 * next action take place quickly.
312 */
313 task_notification_selection
314 = isci_perform_normal_io_completion;
315
316 /* Fall through to the normal case... */
317 } else {
318 /* Use sas_task_abort */
319 /* Leave SAS_TASK_STATE_DONE clear
320 * Leave SAS_TASK_AT_INITIATOR set.
321 */
322 break;
323 }
324
304 case isci_perform_aborted_io_completion: 325 case isci_perform_aborted_io_completion:
305 /* This path can occur with task-managed requests as well as 326 /* This path can occur with task-managed requests as well as
306 * requests terminated because of LUN or device resets. 327 * requests terminated because of LUN or device resets.
@@ -313,12 +334,6 @@ isci_task_set_completion_status(
313 default: 334 default:
314 WARN_ONCE(1, "unknown task_notification_selection: %d\n", 335 WARN_ONCE(1, "unknown task_notification_selection: %d\n",
315 task_notification_selection); 336 task_notification_selection);
316 /* Fall through to the error case... */
317 case isci_perform_error_io_completion:
318 /* Use sas_task_abort */
319 /* Leave SAS_TASK_STATE_DONE clear
320 * Leave SAS_TASK_AT_INITIATOR set.
321 */
322 break; 337 break;
323 } 338 }
324 339