isci: Properly handle requests in the "aborting" state.
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>
Thu, 31 Mar 2011 20:10:34 +0000 (13:10 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sun, 3 Jul 2011 11:00:36 +0000 (04:00 -0700)
When a TMF times-out, the request is set back to "aborting".
Requests in the "aborting" state must be terminated when
LUN and device resets occur.

Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/scsi/isci/request.h
drivers/scsi/isci/task.c

index 4a63bb6de44eb01b4529890572a345c85a71bc85..0c08da6bcd8a9c4995b7a07fc0c89250e72de2e5 100644 (file)
@@ -199,7 +199,7 @@ static inline enum isci_request_status isci_request_change_started_to_newstate(
 
        old_state = isci_request->status;
 
-       if (old_state == started) {
+       if (old_state == started || old_state == aborting) {
                BUG_ON(isci_request->io_request_completion != NULL);
 
                isci_request->io_request_completion = completion_ptr;
index 7e9668402559937a22db6f67de84d1be69388297..338f08ec4d8eb13208e3fc13071dced470cdc0ff 100644 (file)
@@ -903,7 +903,9 @@ static void isci_terminate_request(
                new_request_state
                );
 
-       if ((old_state == started) || (old_state == completed)) {
+       if ((old_state == started) ||
+           (old_state == completed) ||
+           (old_state == aborting)) {
 
                /* If the old_state is started:
                 * This request was not already being aborted. If it had been,
@@ -920,6 +922,10 @@ static void isci_terminate_request(
                 * This request completed from the SCU hardware perspective
                 * and now just needs cleaning up in terms of freeing the
                 * request and potentially calling up to libsas.
+                *
+                * If old_state == aborting:
+                * This request has already gone through a TMF timeout, but may
+                * not have been terminated; needs cleaning up at least.
                 */
                isci_terminate_request_core(isci_host, isci_device,
                                            isci_request);
@@ -1297,14 +1303,16 @@ int isci_task_abort_task(struct sas_task *task)
 
        spin_lock_irqsave(&isci_host->scic_lock, flags);
 
-       /* Check the request status and change to "aborting" if currently
+       /* Check the request status and change to "aborted" if currently
         * "starting"; if true then set the I/O kernel completion
         * struct that will be triggered when the request completes.
         */
        old_state = isci_task_validate_request_to_abort(
                                old_request, isci_host, isci_device,
                                &aborted_io_completion);
-       if ((old_state != started) && (old_state != completed)) {
+       if ((old_state != started) &&
+           (old_state != completed) &&
+           (old_state != aborting)) {
 
                spin_unlock_irqrestore(&isci_host->scic_lock, flags);