summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-03-31 13:10:34 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:00:36 -0700
commitf219f010a355487638bf2fff4724a420e7158fd2 (patch)
treeb35a711226078cdfb8a8c4c730a1d05832a5791e
parentde728b7d72089330603819a74255a0469780fd0e (diff)
downloadlinux-f219f010a355487638bf2fff4724a420e7158fd2.tar.gz
linux-f219f010a355487638bf2fff4724a420e7158fd2.tar.bz2
linux-f219f010a355487638bf2fff4724a420e7158fd2.zip
isci: Properly handle requests in the "aborting" state.
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>
-rw-r--r--drivers/scsi/isci/request.h2
-rw-r--r--drivers/scsi/isci/task.c14
2 files changed, 12 insertions, 4 deletions
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
index 4a63bb6de44e..0c08da6bcd8a 100644
--- a/drivers/scsi/isci/request.h
+++ b/drivers/scsi/isci/request.h
@@ -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;
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 7e9668402559..338f08ec4d8e 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -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);