aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-10 00:27:46 -0500
committerDan Williams <dan.j.williams@intel.com>2011-07-03 06:55:30 -0400
commit50e7f9b5a9ae4a763b2c27500807cf237faca9b0 (patch)
tree2275230176a12f2f0a5f7a395100b5a4f2c3e134 /drivers/scsi/isci/task.c
parent70957a94d70cb82459bd3aea171c54d0a5cd6dbb (diff)
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.c87
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 @@
54 */ 54 */
55 55
56#include <linux/completion.h> 56#include <linux/completion.h>
57#include <linux/irqflags.h>
58#include <scsi/sas_ata.h>
57#include "scic_task_request.h" 59#include "scic_task_request.h"
58#include "scic_remote_device.h" 60#include "scic_remote_device.h"
59#include "scic_io_request.h" 61#include "scic_io_request.h"
@@ -64,6 +66,91 @@
64#include "sata.h" 66#include "sata.h"
65#include "task.h" 67#include "task.h"
66 68
69/**
70* isci_task_complete_for_upper_layer() - This function completes the request
71* to the upper layer driver in the case where an I/O needs to be completed
72* back in the submit path.
73* @host: This parameter is a pointer to the host on which the the request
74* should be queued (either as an error or success).
75* @task: This parameter is the completed request.
76* @response: This parameter is the response code for the completed task.
77* @status: This parameter is the status code for the completed task.
78*
79* none.
80*/
81static void isci_task_complete_for_upper_layer(struct sas_task *task,
82 enum service_response response,
83 enum exec_status status,
84 enum isci_completion_selection task_notification_selection)
85{
86 unsigned long flags = 0;
87 struct Scsi_Host *host = NULL;
88
89 task_notification_selection
90 = isci_task_set_completion_status(task, response, status,
91 task_notification_selection);
92
93 /* Tasks aborted specifically by a call to the lldd_abort_task
94 * function should not be completed to the host in the regular path.
95 */
96 switch (task_notification_selection) {
97 case isci_perform_normal_io_completion:
98 /* Normal notification (task_done) */
99 dev_dbg(task->dev->port->ha->dev,
100 "%s: Normal - task = %p, response=%d, status=%d\n",
101 __func__, task, response, status);
102
103 if (dev_is_sata(task->dev)) {
104 /* Since we are still in the submit path, and since
105 * libsas takes the host lock on behalf of SATA
106 * devices before I/O starts, we need to unlock
107 * before we can call back and report the I/O
108 * submission error.
109 */
110 if (task->dev
111 && task->dev->port
112 && task->dev->port->ha) {
113
114 host = task->dev->port->ha->core.shost;
115 raw_local_irq_save(flags);
116 spin_unlock(host->host_lock);
117 }
118 task->task_done(task);
119 if (host) {
120 spin_lock(host->host_lock);
121 raw_local_irq_restore(flags);
122 }
123 } else
124 task->task_done(task);
125
126 task->lldd_task = NULL;
127 break;
128
129 case isci_perform_aborted_io_completion:
130 /* No notification because this request is already in the
131 * abort path.
132 */
133 dev_warn(task->dev->port->ha->dev,
134 "%s: Aborted - task = %p, response=%d, status=%d\n",
135 __func__, task, response, status);
136 break;
137
138 case isci_perform_error_io_completion:
139 /* Use sas_task_abort */
140 dev_warn(task->dev->port->ha->dev,
141 "%s: Error - task = %p, response=%d, status=%d\n",
142 __func__, task, response, status);
143 sas_task_abort(task);
144 break;
145
146 default:
147 dev_warn(task->dev->port->ha->dev,
148 "%s: isci task notification default case!",
149 __func__);
150 sas_task_abort(task);
151 break;
152 }
153}
67 154
68/** 155/**
69 * isci_task_execute_task() - This function is one of the SAS Domain Template 156 * isci_task_execute_task() - This function is one of the SAS Domain Template