summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.h
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-03-31 22:10:40 +0200
committerDan Williams <dan.j.williams@intel.com>2011-07-03 13:00:36 +0200
commited8a72d108bd951909b28fa4a89aad6489f414e1 (patch)
treed93a624b0677c756c77a2bf3846b69f6209221e8 /drivers/scsi/isci/task.h
parentisci: Fix use of SATA soft reset state machine. (diff)
downloadlinux-ed8a72d108bd951909b28fa4a89aad6489f414e1.tar.xz
linux-ed8a72d108bd951909b28fa4a89aad6489f414e1.zip
isci: Qualify when the host lock is managed for STP/SATA callbacks.
In the case of internal discovery related STP/SATA I/O started through sas_execute_task the host lock is not taken by libsas before calling lldd_execute_task, so the lock should not be managed before calling back to libsas through task->task_done or sas_task_abort. Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/task.h')
-rw-r--r--drivers/scsi/isci/task.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index d7cb6fe268c4..c5afd1cfbde7 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -56,6 +56,8 @@
#if !defined(_ISCI_TASK_H_)
#define _ISCI_TASK_H_
+#include <scsi/sas_ata.h>
+
struct isci_request;
struct isci_host;
@@ -332,5 +334,40 @@ isci_task_set_completion_status(
return task_notification_selection;
}
+/**
+* isci_execpath_callback() - This function is called from the task
+* execute path when the task needs to callback libsas about the submit-time
+* task failure. The callback occurs either through the task's done function
+* or through sas_task_abort. In the case of regular non-discovery SATA/STP I/O
+* requests, libsas takes the host lock before calling execute task. Therefore
+* in this situation the host lock must be managed before calling the func.
+*
+* @ihost: This parameter is the controller to which the I/O request was sent.
+* @task: This parameter is the I/O request.
+* @func: This parameter is the function to call in the correct context.
+* @status: This parameter is the status code for the completed task.
+*
+*/
+static inline void isci_execpath_callback(
+ struct isci_host *ihost,
+ struct sas_task *task,
+ void (*func)(struct sas_task *))
+{
+ unsigned long flags;
+
+ if (dev_is_sata(task->dev) && task->uldd_task) {
+ /* Since we are still in the submit path, and since
+ * libsas takes the host lock on behalf of SATA
+ * devices before I/O starts (in the non-discovery case),
+ * we need to unlock before we can call the callback function.
+ */
+ raw_local_irq_save(flags);
+ spin_unlock(ihost->shost->host_lock);
+ func(task);
+ spin_lock(ihost->shost->host_lock);
+ raw_local_irq_restore(flags);
+ } else
+ func(task);
+}
#endif /* !defined(_SCI_TASK_H_) */