aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-11-17 20:59:50 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 14:50:12 -0500
commit312d3e56119a4bc5c36a96818f87f650c069ddc2 (patch)
treed8cf7586656301ff1c4e5a49f9cbddde61e3e561 /drivers/scsi/isci
parentb1124cd3ec97406c767b90bf7e93ecd2d2915592 (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.c3
-rw-r--r--drivers/scsi/isci/task.c6
-rw-r--r--drivers/scsi/isci/task.h36
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*/
338static 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_) */