diff options
author | Jeff Skirvin <jeffrey.d.skirvin@intel.com> | 2012-03-09 01:42:03 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2012-05-17 17:33:41 -0400 |
commit | 621120ca56850249554996c94efe75f8200a2cc0 (patch) | |
tree | 892326cd79b25e0741ee271c01cc04aadb1af8ef | |
parent | 033d19d298b4245da2d3d6c795ea97e419f9ac61 (diff) |
isci: Manage tag releases differently when aborting tasks.
When an individual request is being terminated, the request's tag
is managed in the terminate function.
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/host.c | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 11 | ||||
-rw-r--r-- | drivers/scsi/isci/request.h | 1 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 3 |
4 files changed, 12 insertions, 6 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 53c3ad64c998..ef2790faeab8 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -1141,7 +1141,8 @@ void isci_host_completion_routine(unsigned long data) | |||
1141 | if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &request->flags)) | 1141 | if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &request->flags)) |
1142 | wake_up_all(&ihost->eventq); | 1142 | wake_up_all(&ihost->eventq); |
1143 | 1143 | ||
1144 | isci_free_tag(ihost, request->io_tag); | 1144 | if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &request->flags)) |
1145 | isci_free_tag(ihost, request->io_tag); | ||
1145 | } | 1146 | } |
1146 | spin_unlock_irq(&ihost->scic_lock); | 1147 | spin_unlock_irq(&ihost->scic_lock); |
1147 | 1148 | ||
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 21a9800a9bec..adeda64e512a 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -104,15 +104,15 @@ static enum sci_status sci_remote_device_terminate_req( | |||
104 | int check_abort, | 104 | int check_abort, |
105 | struct isci_request *ireq) | 105 | struct isci_request *ireq) |
106 | { | 106 | { |
107 | dev_dbg(&ihost->pdev->dev, | ||
108 | "%s: idev=%p; flags=%lx; req=%p; req target=%p\n", | ||
109 | __func__, idev, idev->flags, ireq, ireq->target_device); | ||
110 | |||
111 | if (!test_bit(IREQ_ACTIVE, &ireq->flags) || | 107 | if (!test_bit(IREQ_ACTIVE, &ireq->flags) || |
112 | (ireq->target_device != idev) || | 108 | (ireq->target_device != idev) || |
113 | (check_abort && !test_bit(IREQ_PENDING_ABORT, &ireq->flags))) | 109 | (check_abort && !test_bit(IREQ_PENDING_ABORT, &ireq->flags))) |
114 | return SCI_SUCCESS; | 110 | return SCI_SUCCESS; |
115 | 111 | ||
112 | dev_dbg(&ihost->pdev->dev, | ||
113 | "%s: idev=%p; flags=%lx; req=%p; req target=%p\n", | ||
114 | __func__, idev, idev->flags, ireq, ireq->target_device); | ||
115 | |||
116 | set_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags); | 116 | set_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags); |
117 | 117 | ||
118 | return sci_controller_terminate_request(ihost, idev, ireq); | 118 | return sci_controller_terminate_request(ihost, idev, ireq); |
@@ -209,11 +209,14 @@ enum sci_status isci_remote_device_terminate_requests( | |||
209 | rnc_suspend_count, idev->rnc.suspend_count); | 209 | rnc_suspend_count, idev->rnc.suspend_count); |
210 | if (ireq) { | 210 | if (ireq) { |
211 | /* Terminate a specific TC. */ | 211 | /* Terminate a specific TC. */ |
212 | set_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags); | ||
212 | sci_remote_device_terminate_req(ihost, idev, 0, ireq); | 213 | sci_remote_device_terminate_req(ihost, idev, 0, ireq); |
213 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 214 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
214 | wait_event(ihost->eventq, | 215 | wait_event(ihost->eventq, |
215 | isci_check_reqterm(ihost, idev, ireq, | 216 | isci_check_reqterm(ihost, idev, ireq, |
216 | rnc_suspend_count)); | 217 | rnc_suspend_count)); |
218 | clear_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags); | ||
219 | isci_free_tag(ihost, ireq->io_tag); | ||
217 | } else { | 220 | } else { |
218 | /* Terminate all TCs. */ | 221 | /* Terminate all TCs. */ |
219 | sci_remote_device_terminate_requests(idev); | 222 | sci_remote_device_terminate_requests(idev); |
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index d12e97531da8..1a651579bb33 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -87,6 +87,7 @@ struct isci_request { | |||
87 | #define IREQ_PENDING_ABORT 4 /* Set == device was not suspended yet */ | 87 | #define IREQ_PENDING_ABORT 4 /* Set == device was not suspended yet */ |
88 | #define IREQ_TC_ABORT_POSTED 5 | 88 | #define IREQ_TC_ABORT_POSTED 5 |
89 | #define IREQ_ABORT_PATH_ACTIVE 6 | 89 | #define IREQ_ABORT_PATH_ACTIVE 6 |
90 | #define IREQ_NO_AUTO_FREE_TAG 7 /* Set when being explicitly managed */ | ||
90 | unsigned long flags; | 91 | unsigned long flags; |
91 | /* XXX kill ttype and ttype_ptr, allocate full sas_task */ | 92 | /* XXX kill ttype and ttype_ptr, allocate full sas_task */ |
92 | union ttype_ptr_union { | 93 | union ttype_ptr_union { |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index c1c6dd0473ae..e798c6ae9592 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -719,7 +719,8 @@ isci_task_request_complete(struct isci_host *ihost, | |||
719 | */ | 719 | */ |
720 | set_bit(IREQ_TERMINATED, &ireq->flags); | 720 | set_bit(IREQ_TERMINATED, &ireq->flags); |
721 | 721 | ||
722 | isci_free_tag(ihost, ireq->io_tag); | 722 | if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags)) |
723 | isci_free_tag(ihost, ireq->io_tag); | ||
723 | 724 | ||
724 | /* The task management part completes last. */ | 725 | /* The task management part completes last. */ |
725 | if (tmf_complete) | 726 | if (tmf_complete) |