diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-03-10 06:27:46 +0100 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 12:55:30 +0200 |
commit | 50e7f9b5a9ae4a763b2c27500807cf237faca9b0 (patch) | |
tree | 2275230176a12f2f0a5f7a395100b5a4f2c3e134 /drivers/scsi/isci/task.c | |
parent | isci: Fixed BUG_ON in isci_abort_task_process_cb callback. (diff) | |
download | linux-50e7f9b5a9ae4a763b2c27500807cf237faca9b0.tar.xz linux-50e7f9b5a9ae4a763b2c27500807cf237faca9b0.zip |
isci: Errors in the submit path for SATA devices manage the ap lock.
Since libsas takes the domain device sata_dev.ap->lock before submitting
a task, error completions in the submit path for SATA devices must
unlock/relock when completing the sas_task back to libsas.
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.c')
-rw-r--r-- | drivers/scsi/isci/task.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index a1234e42937e..d00b4c97b85b 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c @@ -54,6 +54,8 @@ */ #include <linux/completion.h> +#include <linux/irqflags.h> +#include <scsi/sas_ata.h> #include "scic_task_request.h" #include "scic_remote_device.h" #include "scic_io_request.h" @@ -64,6 +66,91 @@ #include "sata.h" #include "task.h" +/** +* isci_task_complete_for_upper_layer() - This function completes the request +* to the upper layer driver in the case where an I/O needs to be completed +* back in the submit path. +* @host: This parameter is a pointer to the host on which the the request +* should be queued (either as an error or success). +* @task: This parameter is the completed request. +* @response: This parameter is the response code for the completed task. +* @status: This parameter is the status code for the completed task. +* +* none. +*/ +static void isci_task_complete_for_upper_layer(struct sas_task *task, + enum service_response response, + enum exec_status status, + enum isci_completion_selection task_notification_selection) +{ + unsigned long flags = 0; + struct Scsi_Host *host = NULL; + + task_notification_selection + = isci_task_set_completion_status(task, response, status, + task_notification_selection); + + /* Tasks aborted specifically by a call to the lldd_abort_task + * function should not be completed to the host in the regular path. + */ + switch (task_notification_selection) { + case isci_perform_normal_io_completion: + /* Normal notification (task_done) */ + dev_dbg(task->dev->port->ha->dev, + "%s: Normal - task = %p, response=%d, status=%d\n", + __func__, task, response, status); + + if (dev_is_sata(task->dev)) { + /* Since we are still in the submit path, and since + * libsas takes the host lock on behalf of SATA + * devices before I/O starts, we need to unlock + * before we can call back and report the I/O + * submission error. + */ + if (task->dev + && task->dev->port + && task->dev->port->ha) { + + host = task->dev->port->ha->core.shost; + raw_local_irq_save(flags); + spin_unlock(host->host_lock); + } + task->task_done(task); + if (host) { + spin_lock(host->host_lock); + raw_local_irq_restore(flags); + } + } else + task->task_done(task); + + task->lldd_task = NULL; + break; + + case isci_perform_aborted_io_completion: + /* No notification because this request is already in the + * abort path. + */ + dev_warn(task->dev->port->ha->dev, + "%s: Aborted - task = %p, response=%d, status=%d\n", + __func__, task, response, status); + break; + + case isci_perform_error_io_completion: + /* Use sas_task_abort */ + dev_warn(task->dev->port->ha->dev, + "%s: Error - task = %p, response=%d, status=%d\n", + __func__, task, response, status); + sas_task_abort(task); + break; + + default: + dev_warn(task->dev->port->ha->dev, + "%s: isci task notification default case!", + __func__); + sas_task_abort(task); + break; + } +} /** * isci_task_execute_task() - This function is one of the SAS Domain Template |