diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-11-17 20:59:50 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 14:50:12 -0500 |
commit | 312d3e56119a4bc5c36a96818f87f650c069ddc2 (patch) | |
tree | d8cf7586656301ff1c4e5a49f9cbddde61e3e561 /drivers/scsi/isci | |
parent | b1124cd3ec97406c767b90bf7e93ecd2d2915592 (diff) |
[SCSI] libsas: remove ata_port.lock management duties from lldds
Each libsas driver (mvsas, pm8001, and isci) has invented a different
method for managing the ap->lock. The lock is held by the ata
->queuecommand() path. mvsas drops it prior to acquiring any internal
locks which allows it to hold its internal lock across calls to
task->task_done(). This capability is important as it is the only way
the driver can flush task->task_done() instances to guarantee that it no
longer has any in-flight references to a domain_device at
->lldd_dev_gone() time.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r-- | drivers/scsi/isci/request.c | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 6 | ||||
-rw-r--r-- | drivers/scsi/isci/task.h | 36 |
3 files changed, 3 insertions, 42 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 751368b46b44..788daeedc89f 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -3796,8 +3796,7 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide | |||
3796 | /* Cause this task to be scheduled in the SCSI error | 3796 | /* Cause this task to be scheduled in the SCSI error |
3797 | * handler thread. | 3797 | * handler thread. |
3798 | */ | 3798 | */ |
3799 | isci_execpath_callback(ihost, task, | 3799 | sas_task_abort(task); |
3800 | sas_task_abort); | ||
3801 | 3800 | ||
3802 | /* Change the status, since we are holding | 3801 | /* Change the status, since we are holding |
3803 | * the I/O until it is managed by the SCSI | 3802 | * the I/O until it is managed by the SCSI |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index f5a3f7d2bdab..4bd88ef83cdf 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -96,8 +96,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task, | |||
96 | __func__, task, response, status); | 96 | __func__, task, response, status); |
97 | 97 | ||
98 | task->lldd_task = NULL; | 98 | task->lldd_task = NULL; |
99 | 99 | task->task_done(task); | |
100 | isci_execpath_callback(ihost, task, task->task_done); | ||
101 | break; | 100 | break; |
102 | 101 | ||
103 | case isci_perform_aborted_io_completion: | 102 | case isci_perform_aborted_io_completion: |
@@ -117,8 +116,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task, | |||
117 | "%s: Error - task = %p, response=%d, " | 116 | "%s: Error - task = %p, response=%d, " |
118 | "status=%d\n", | 117 | "status=%d\n", |
119 | __func__, task, response, status); | 118 | __func__, task, response, status); |
120 | 119 | sas_task_abort(task); | |
121 | isci_execpath_callback(ihost, task, sas_task_abort); | ||
122 | break; | 120 | break; |
123 | 121 | ||
124 | default: | 122 | default: |
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h index 1b27b3797c6c..bb472c339523 100644 --- a/drivers/scsi/isci/task.h +++ b/drivers/scsi/isci/task.h | |||
@@ -321,40 +321,4 @@ isci_task_set_completion_status( | |||
321 | return task_notification_selection; | 321 | return task_notification_selection; |
322 | 322 | ||
323 | } | 323 | } |
324 | /** | ||
325 | * isci_execpath_callback() - This function is called from the task | ||
326 | * execute path when the task needs to callback libsas about the submit-time | ||
327 | * task failure. The callback occurs either through the task's done function | ||
328 | * or through sas_task_abort. In the case of regular non-discovery SATA/STP I/O | ||
329 | * requests, libsas takes the host lock before calling execute task. Therefore | ||
330 | * in this situation the host lock must be managed before calling the func. | ||
331 | * | ||
332 | * @ihost: This parameter is the controller to which the I/O request was sent. | ||
333 | * @task: This parameter is the I/O request. | ||
334 | * @func: This parameter is the function to call in the correct context. | ||
335 | * @status: This parameter is the status code for the completed task. | ||
336 | * | ||
337 | */ | ||
338 | static inline void isci_execpath_callback(struct isci_host *ihost, | ||
339 | struct sas_task *task, | ||
340 | void (*func)(struct sas_task *)) | ||
341 | { | ||
342 | struct domain_device *dev = task->dev; | ||
343 | |||
344 | if (dev_is_sata(dev) && task->uldd_task) { | ||
345 | unsigned long flags; | ||
346 | |||
347 | /* Since we are still in the submit path, and since | ||
348 | * libsas takes the host lock on behalf of SATA | ||
349 | * devices before I/O starts (in the non-discovery case), | ||
350 | * we need to unlock before we can call the callback function. | ||
351 | */ | ||
352 | raw_local_irq_save(flags); | ||
353 | spin_unlock(dev->sata_dev.ap->lock); | ||
354 | func(task); | ||
355 | spin_lock(dev->sata_dev.ap->lock); | ||
356 | raw_local_irq_restore(flags); | ||
357 | } else | ||
358 | func(task); | ||
359 | } | ||
360 | #endif /* !defined(_SCI_TASK_H_) */ | 324 | #endif /* !defined(_SCI_TASK_H_) */ |