From ed8a72d108bd951909b28fa4a89aad6489f414e1 Mon Sep 17 00:00:00 2001 From: Jeff Skirvin Date: Thu, 31 Mar 2011 13:10:40 -0700 Subject: 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 Signed-off-by: Dan Williams --- drivers/scsi/isci/task.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'drivers/scsi/isci/task.h') diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h index d7cb6fe268c..c5afd1cfbde 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 + 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_) */ -- cgit v1.2.2