blob: 7c500bb6a8e0b3ee792825012496032a89678856 [file] [log] [blame]
Dan Williams6f231dd2011-07-02 22:56:22 -07001/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
Dan Williams6f231dd2011-07-02 22:56:22 -070057#include "task.h"
58#include "request.h"
59#include "sata.h"
60#include "scu_completion_codes.h"
Dan Williams5dec6f42011-05-10 02:28:49 -070061#include "scu_event_codes.h"
Dave Jiang2ec53eb2011-05-04 18:01:22 -070062#include "sas.h"
Dan Williams6f231dd2011-07-02 22:56:22 -070063
Dan Williams5076a1a2011-06-27 14:57:03 -070064static struct scu_sgl_element_pair *to_sgl_element_pair(struct isci_request *ireq,
Dan Williams312e0c22011-06-28 13:47:09 -070065 int idx)
66{
67 if (idx == 0)
Dan Williams5076a1a2011-06-27 14:57:03 -070068 return &ireq->tc->sgl_pair_ab;
Dan Williams312e0c22011-06-28 13:47:09 -070069 else if (idx == 1)
Dan Williams5076a1a2011-06-27 14:57:03 -070070 return &ireq->tc->sgl_pair_cd;
Dan Williams312e0c22011-06-28 13:47:09 -070071 else if (idx < 0)
72 return NULL;
73 else
Dan Williams5076a1a2011-06-27 14:57:03 -070074 return &ireq->sg_table[idx - 2];
Dan Williams6f231dd2011-07-02 22:56:22 -070075}
76
Dan Williamsd9dcb4b2011-06-30 17:38:32 -070077static dma_addr_t to_sgl_element_pair_dma(struct isci_host *ihost,
Dan Williams5076a1a2011-06-27 14:57:03 -070078 struct isci_request *ireq, u32 idx)
Dan Williams312e0c22011-06-28 13:47:09 -070079{
80 u32 offset;
81
82 if (idx == 0) {
Dan Williams5076a1a2011-06-27 14:57:03 -070083 offset = (void *) &ireq->tc->sgl_pair_ab -
Dan Williamsd9dcb4b2011-06-30 17:38:32 -070084 (void *) &ihost->task_context_table[0];
85 return ihost->task_context_dma + offset;
Dan Williams312e0c22011-06-28 13:47:09 -070086 } else if (idx == 1) {
Dan Williams5076a1a2011-06-27 14:57:03 -070087 offset = (void *) &ireq->tc->sgl_pair_cd -
Dan Williamsd9dcb4b2011-06-30 17:38:32 -070088 (void *) &ihost->task_context_table[0];
89 return ihost->task_context_dma + offset;
Dan Williams312e0c22011-06-28 13:47:09 -070090 }
91
Dan Williams89a73012011-06-30 19:14:33 -070092 return sci_io_request_get_dma_addr(ireq, &ireq->sg_table[idx - 2]);
Dan Williams312e0c22011-06-28 13:47:09 -070093}
94
95static void init_sgl_element(struct scu_sgl_element *e, struct scatterlist *sg)
96{
97 e->length = sg_dma_len(sg);
98 e->address_upper = upper_32_bits(sg_dma_address(sg));
99 e->address_lower = lower_32_bits(sg_dma_address(sg));
100 e->address_modifier = 0;
101}
102
Dan Williams89a73012011-06-30 19:14:33 -0700103static void sci_request_build_sgl(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700104{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700105 struct isci_host *ihost = ireq->isci_host;
Dan Williams5076a1a2011-06-27 14:57:03 -0700106 struct sas_task *task = isci_request_access_task(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700107 struct scatterlist *sg = NULL;
108 dma_addr_t dma_addr;
109 u32 sg_idx = 0;
110 struct scu_sgl_element_pair *scu_sg = NULL;
111 struct scu_sgl_element_pair *prev_sg = NULL;
112
113 if (task->num_scatter > 0) {
114 sg = task->scatter;
115
116 while (sg) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700117 scu_sg = to_sgl_element_pair(ireq, sg_idx);
Dan Williams312e0c22011-06-28 13:47:09 -0700118 init_sgl_element(&scu_sg->A, sg);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700119 sg = sg_next(sg);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700120 if (sg) {
Dan Williams312e0c22011-06-28 13:47:09 -0700121 init_sgl_element(&scu_sg->B, sg);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700122 sg = sg_next(sg);
123 } else
Dan Williams312e0c22011-06-28 13:47:09 -0700124 memset(&scu_sg->B, 0, sizeof(scu_sg->B));
Dan Williamsf1f52e72011-05-10 02:28:45 -0700125
126 if (prev_sg) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700127 dma_addr = to_sgl_element_pair_dma(ihost,
Dan Williams5076a1a2011-06-27 14:57:03 -0700128 ireq,
Dan Williams312e0c22011-06-28 13:47:09 -0700129 sg_idx);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700130
131 prev_sg->next_pair_upper =
132 upper_32_bits(dma_addr);
133 prev_sg->next_pair_lower =
134 lower_32_bits(dma_addr);
135 }
136
137 prev_sg = scu_sg;
138 sg_idx++;
139 }
140 } else { /* handle when no sg */
Dan Williams5076a1a2011-06-27 14:57:03 -0700141 scu_sg = to_sgl_element_pair(ireq, sg_idx);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700142
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700143 dma_addr = dma_map_single(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700144 task->scatter,
145 task->total_xfer_len,
146 task->data_dir);
147
Dan Williams5076a1a2011-06-27 14:57:03 -0700148 ireq->zero_scatter_daddr = dma_addr;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700149
150 scu_sg->A.length = task->total_xfer_len;
151 scu_sg->A.address_upper = upper_32_bits(dma_addr);
152 scu_sg->A.address_lower = lower_32_bits(dma_addr);
153 }
154
155 if (scu_sg) {
156 scu_sg->next_pair_upper = 0;
157 scu_sg->next_pair_lower = 0;
158 }
159}
160
Dan Williams89a73012011-06-30 19:14:33 -0700161static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700162{
163 struct ssp_cmd_iu *cmd_iu;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700164 struct sas_task *task = isci_request_access_task(ireq);
165
Dan Williams5076a1a2011-06-27 14:57:03 -0700166 cmd_iu = &ireq->ssp.cmd;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700167
168 memcpy(cmd_iu->LUN, task->ssp_task.LUN, 8);
169 cmd_iu->add_cdb_len = 0;
170 cmd_iu->_r_a = 0;
171 cmd_iu->_r_b = 0;
172 cmd_iu->en_fburst = 0; /* unsupported */
173 cmd_iu->task_prio = task->ssp_task.task_prio;
174 cmd_iu->task_attr = task->ssp_task.task_attr;
175 cmd_iu->_r_c = 0;
176
177 sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
178 sizeof(task->ssp_task.cdb) / sizeof(u32));
179}
180
Dan Williams89a73012011-06-30 19:14:33 -0700181static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700182{
183 struct ssp_task_iu *task_iu;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700184 struct sas_task *task = isci_request_access_task(ireq);
185 struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
186
Dan Williams5076a1a2011-06-27 14:57:03 -0700187 task_iu = &ireq->ssp.tmf;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700188
189 memset(task_iu, 0, sizeof(struct ssp_task_iu));
190
191 memcpy(task_iu->LUN, task->ssp_task.LUN, 8);
192
193 task_iu->task_func = isci_tmf->tmf_code;
194 task_iu->task_tag =
195 (ireq->ttype == tmf_task) ?
196 isci_tmf->io_tag :
197 SCI_CONTROLLER_INVALID_IO_TAG;
198}
199
200/**
201 * This method is will fill in the SCU Task Context for any type of SSP request.
202 * @sci_req:
203 * @task_context:
204 *
205 */
206static void scu_ssp_reqeust_construct_task_context(
Dan Williams5076a1a2011-06-27 14:57:03 -0700207 struct isci_request *ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700208 struct scu_task_context *task_context)
209{
210 dma_addr_t dma_addr;
Dan Williams78a6f062011-06-30 16:31:37 -0700211 struct isci_remote_device *idev;
Dan Williamsffe191c2011-06-29 13:09:25 -0700212 struct isci_port *iport;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700213
Dan Williams34a99152011-07-01 02:25:15 -0700214 idev = ireq->target_device;
215 iport = idev->owning_port;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700216
217 /* Fill in the TC with the its required data */
218 task_context->abort = 0;
219 task_context->priority = 0;
220 task_context->initiator_request = 1;
Dan Williams78a6f062011-06-30 16:31:37 -0700221 task_context->connection_rate = idev->connection_rate;
Dan Williams34a99152011-07-01 02:25:15 -0700222 task_context->protocol_engine_index = ISCI_PEG;
223 task_context->logical_port_index = iport->physical_port_index;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700224 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
225 task_context->valid = SCU_TASK_CONTEXT_VALID;
226 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
227
Dan Williams34a99152011-07-01 02:25:15 -0700228 task_context->remote_node_index = idev->rnc.remote_node_index;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700229 task_context->command_code = 0;
230
231 task_context->link_layer_control = 0;
232 task_context->do_not_dma_ssp_good_response = 1;
233 task_context->strict_ordering = 0;
234 task_context->control_frame = 0;
235 task_context->timeout_enable = 0;
236 task_context->block_guard_enable = 0;
237
238 task_context->address_modifier = 0;
239
Dan Williams5076a1a2011-06-27 14:57:03 -0700240 /* task_context->type.ssp.tag = ireq->io_tag; */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700241 task_context->task_phase = 0x01;
242
Dan Williams5076a1a2011-06-27 14:57:03 -0700243 ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
Dan Williams34a99152011-07-01 02:25:15 -0700244 (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
245 (iport->physical_port_index <<
Dan Williamsffe191c2011-06-29 13:09:25 -0700246 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
247 ISCI_TAG_TCI(ireq->io_tag));
Dan Williamsf1f52e72011-05-10 02:28:45 -0700248
249 /*
250 * Copy the physical address for the command buffer to the
251 * SCU Task Context
252 */
Dan Williams89a73012011-06-30 19:14:33 -0700253 dma_addr = sci_io_request_get_dma_addr(ireq, &ireq->ssp.cmd);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700254
255 task_context->command_iu_upper = upper_32_bits(dma_addr);
256 task_context->command_iu_lower = lower_32_bits(dma_addr);
257
258 /*
259 * Copy the physical address for the response buffer to the
260 * SCU Task Context
261 */
Dan Williams89a73012011-06-30 19:14:33 -0700262 dma_addr = sci_io_request_get_dma_addr(ireq, &ireq->ssp.rsp);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700263
264 task_context->response_iu_upper = upper_32_bits(dma_addr);
265 task_context->response_iu_lower = lower_32_bits(dma_addr);
266}
267
268/**
269 * This method is will fill in the SCU Task Context for a SSP IO request.
270 * @sci_req:
271 *
272 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700273static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
Dan Williams312e0c22011-06-28 13:47:09 -0700274 enum dma_data_direction dir,
275 u32 len)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700276{
Dan Williams5076a1a2011-06-27 14:57:03 -0700277 struct scu_task_context *task_context = ireq->tc;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700278
Dan Williams5076a1a2011-06-27 14:57:03 -0700279 scu_ssp_reqeust_construct_task_context(ireq, task_context);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700280
281 task_context->ssp_command_iu_length =
282 sizeof(struct ssp_cmd_iu) / sizeof(u32);
283 task_context->type.ssp.frame_type = SSP_COMMAND;
284
285 switch (dir) {
286 case DMA_FROM_DEVICE:
287 case DMA_NONE:
288 default:
289 task_context->task_type = SCU_TASK_TYPE_IOREAD;
290 break;
291 case DMA_TO_DEVICE:
292 task_context->task_type = SCU_TASK_TYPE_IOWRITE;
293 break;
294 }
295
296 task_context->transfer_length_bytes = len;
297
298 if (task_context->transfer_length_bytes > 0)
Dan Williams89a73012011-06-30 19:14:33 -0700299 sci_request_build_sgl(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700300}
301
Dan Williamsf1f52e72011-05-10 02:28:45 -0700302/**
303 * This method will fill in the SCU Task Context for a SSP Task request. The
304 * following important settings are utilized: -# priority ==
305 * SCU_TASK_PRIORITY_HIGH. This ensures that the task request is issued
306 * ahead of other task destined for the same Remote Node. -# task_type ==
307 * SCU_TASK_TYPE_IOREAD. This simply indicates that a normal request type
308 * (i.e. non-raw frame) is being utilized to perform task management. -#
309 * control_frame == 1. This ensures that the proper endianess is set so
310 * that the bytes are transmitted in the right order for a task frame.
311 * @sci_req: This parameter specifies the task request object being
312 * constructed.
313 *
314 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700315static void scu_ssp_task_request_construct_task_context(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700316{
Dan Williams5076a1a2011-06-27 14:57:03 -0700317 struct scu_task_context *task_context = ireq->tc;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700318
Dan Williams5076a1a2011-06-27 14:57:03 -0700319 scu_ssp_reqeust_construct_task_context(ireq, task_context);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700320
321 task_context->control_frame = 1;
322 task_context->priority = SCU_TASK_PRIORITY_HIGH;
323 task_context->task_type = SCU_TASK_TYPE_RAW_FRAME;
324 task_context->transfer_length_bytes = 0;
325 task_context->type.ssp.frame_type = SSP_TASK;
326 task_context->ssp_command_iu_length =
327 sizeof(struct ssp_task_iu) / sizeof(u32);
328}
329
Dan Williamsf1f52e72011-05-10 02:28:45 -0700330/**
Dan Williams5dec6f42011-05-10 02:28:49 -0700331 * This method is will fill in the SCU Task Context for any type of SATA
332 * request. This is called from the various SATA constructors.
333 * @sci_req: The general IO request object which is to be used in
334 * constructing the SCU task context.
335 * @task_context: The buffer pointer for the SCU task context which is being
336 * constructed.
Dan Williamsf1f52e72011-05-10 02:28:45 -0700337 *
Dan Williams5dec6f42011-05-10 02:28:49 -0700338 * The general io request construction is complete. The buffer assignment for
339 * the command buffer is complete. none Revisit task context construction to
340 * determine what is common for SSP/SMP/STP task context structures.
Dan Williamsf1f52e72011-05-10 02:28:45 -0700341 */
Dan Williams5dec6f42011-05-10 02:28:49 -0700342static void scu_sata_reqeust_construct_task_context(
Dan Williams5076a1a2011-06-27 14:57:03 -0700343 struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700344 struct scu_task_context *task_context)
345{
346 dma_addr_t dma_addr;
Dan Williams78a6f062011-06-30 16:31:37 -0700347 struct isci_remote_device *idev;
Dan Williamsffe191c2011-06-29 13:09:25 -0700348 struct isci_port *iport;
Dan Williams5dec6f42011-05-10 02:28:49 -0700349
Dan Williams34a99152011-07-01 02:25:15 -0700350 idev = ireq->target_device;
351 iport = idev->owning_port;
Dan Williams5dec6f42011-05-10 02:28:49 -0700352
353 /* Fill in the TC with the its required data */
354 task_context->abort = 0;
355 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
356 task_context->initiator_request = 1;
Dan Williams78a6f062011-06-30 16:31:37 -0700357 task_context->connection_rate = idev->connection_rate;
Dan Williams34a99152011-07-01 02:25:15 -0700358 task_context->protocol_engine_index = ISCI_PEG;
359 task_context->logical_port_index = iport->physical_port_index;
Dan Williams5dec6f42011-05-10 02:28:49 -0700360 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
361 task_context->valid = SCU_TASK_CONTEXT_VALID;
362 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
363
Dan Williams34a99152011-07-01 02:25:15 -0700364 task_context->remote_node_index = idev->rnc.remote_node_index;
Dan Williams5dec6f42011-05-10 02:28:49 -0700365 task_context->command_code = 0;
366
367 task_context->link_layer_control = 0;
368 task_context->do_not_dma_ssp_good_response = 1;
369 task_context->strict_ordering = 0;
370 task_context->control_frame = 0;
371 task_context->timeout_enable = 0;
372 task_context->block_guard_enable = 0;
373
374 task_context->address_modifier = 0;
375 task_context->task_phase = 0x01;
376
377 task_context->ssp_command_iu_length =
378 (sizeof(struct host_to_dev_fis) - sizeof(u32)) / sizeof(u32);
379
380 /* Set the first word of the H2D REG FIS */
Dan Williams5076a1a2011-06-27 14:57:03 -0700381 task_context->type.words[0] = *(u32 *)&ireq->stp.cmd;
Dan Williams5dec6f42011-05-10 02:28:49 -0700382
Dan Williams5076a1a2011-06-27 14:57:03 -0700383 ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
Dan Williams34a99152011-07-01 02:25:15 -0700384 (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
385 (iport->physical_port_index <<
386 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
387 ISCI_TAG_TCI(ireq->io_tag));
Dan Williams5dec6f42011-05-10 02:28:49 -0700388 /*
389 * Copy the physical address for the command buffer to the SCU Task
390 * Context. We must offset the command buffer by 4 bytes because the
391 * first 4 bytes are transfered in the body of the TC.
392 */
Dan Williams89a73012011-06-30 19:14:33 -0700393 dma_addr = sci_io_request_get_dma_addr(ireq,
Dan Williams5076a1a2011-06-27 14:57:03 -0700394 ((char *) &ireq->stp.cmd) +
Dan Williams5dec6f42011-05-10 02:28:49 -0700395 sizeof(u32));
396
397 task_context->command_iu_upper = upper_32_bits(dma_addr);
398 task_context->command_iu_lower = lower_32_bits(dma_addr);
399
400 /* SATA Requests do not have a response buffer */
401 task_context->response_iu_upper = 0;
402 task_context->response_iu_lower = 0;
403}
404
Dan Williams5076a1a2011-06-27 14:57:03 -0700405static void scu_stp_raw_request_construct_task_context(struct isci_request *ireq)
Dan Williams5dec6f42011-05-10 02:28:49 -0700406{
Dan Williams5076a1a2011-06-27 14:57:03 -0700407 struct scu_task_context *task_context = ireq->tc;
Dan Williams5dec6f42011-05-10 02:28:49 -0700408
Dan Williams5076a1a2011-06-27 14:57:03 -0700409 scu_sata_reqeust_construct_task_context(ireq, task_context);
Dan Williams5dec6f42011-05-10 02:28:49 -0700410
411 task_context->control_frame = 0;
412 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
413 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME;
414 task_context->type.stp.fis_type = FIS_REGH2D;
415 task_context->transfer_length_bytes = sizeof(struct host_to_dev_fis) - sizeof(u32);
416}
417
Dan Williams89a73012011-06-30 19:14:33 -0700418static enum sci_status sci_stp_pio_request_construct(struct isci_request *ireq,
Dan Williams5076a1a2011-06-27 14:57:03 -0700419 bool copy_rx_frame)
Dan Williams5dec6f42011-05-10 02:28:49 -0700420{
Dan Williams5076a1a2011-06-27 14:57:03 -0700421 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williams5dec6f42011-05-10 02:28:49 -0700422
Dan Williams5076a1a2011-06-27 14:57:03 -0700423 scu_stp_raw_request_construct_task_context(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700424
Dan Williamsba7cb222011-06-27 11:56:41 -0700425 stp_req->status = 0;
426 stp_req->sgl.offset = 0;
427 stp_req->sgl.set = SCU_SGL_ELEMENT_PAIR_A;
Dan Williams5dec6f42011-05-10 02:28:49 -0700428
429 if (copy_rx_frame) {
Dan Williams89a73012011-06-30 19:14:33 -0700430 sci_request_build_sgl(ireq);
Dan Williamsba7cb222011-06-27 11:56:41 -0700431 stp_req->sgl.index = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -0700432 } else {
433 /* The user does not want the data copied to the SGL buffer location */
Dan Williamsba7cb222011-06-27 11:56:41 -0700434 stp_req->sgl.index = -1;
Dan Williams5dec6f42011-05-10 02:28:49 -0700435 }
436
437 return SCI_SUCCESS;
438}
439
440/**
441 *
442 * @sci_req: This parameter specifies the request to be constructed as an
443 * optimized request.
444 * @optimized_task_type: This parameter specifies whether the request is to be
445 * an UDMA request or a NCQ request. - A value of 0 indicates UDMA. - A
446 * value of 1 indicates NCQ.
447 *
448 * This method will perform request construction common to all types of STP
449 * requests that are optimized by the silicon (i.e. UDMA, NCQ). This method
450 * returns an indication as to whether the construction was successful.
451 */
Dan Williams89a73012011-06-30 19:14:33 -0700452static void sci_stp_optimized_request_construct(struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700453 u8 optimized_task_type,
454 u32 len,
455 enum dma_data_direction dir)
456{
Dan Williams5076a1a2011-06-27 14:57:03 -0700457 struct scu_task_context *task_context = ireq->tc;
Dan Williams5dec6f42011-05-10 02:28:49 -0700458
459 /* Build the STP task context structure */
Dan Williams5076a1a2011-06-27 14:57:03 -0700460 scu_sata_reqeust_construct_task_context(ireq, task_context);
Dan Williams5dec6f42011-05-10 02:28:49 -0700461
462 /* Copy over the SGL elements */
Dan Williams89a73012011-06-30 19:14:33 -0700463 sci_request_build_sgl(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700464
465 /* Copy over the number of bytes to be transfered */
466 task_context->transfer_length_bytes = len;
467
468 if (dir == DMA_TO_DEVICE) {
469 /*
470 * The difference between the DMA IN and DMA OUT request task type
471 * values are consistent with the difference between FPDMA READ
472 * and FPDMA WRITE values. Add the supplied task type parameter
473 * to this difference to set the task type properly for this
474 * DATA OUT (WRITE) case. */
475 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
476 - SCU_TASK_TYPE_DMA_IN);
477 } else {
478 /*
479 * For the DATA IN (READ) case, simply save the supplied
480 * optimized task type. */
481 task_context->task_type = optimized_task_type;
482 }
483}
484
485
486
Dan Williamsf1f52e72011-05-10 02:28:45 -0700487static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -0700488sci_io_request_construct_sata(struct isci_request *ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700489 u32 len,
490 enum dma_data_direction dir,
491 bool copy)
Dan Williams6f231dd2011-07-02 22:56:22 -0700492{
Dan Williams6f231dd2011-07-02 22:56:22 -0700493 enum sci_status status = SCI_SUCCESS;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700494 struct sas_task *task = isci_request_access_task(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700495
Dan Williamsf1f52e72011-05-10 02:28:45 -0700496 /* check for management protocols */
497 if (ireq->ttype == tmf_task) {
498 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700499
Dan Williamsf1f52e72011-05-10 02:28:45 -0700500 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
Dan Williams5dec6f42011-05-10 02:28:49 -0700501 tmf->tmf_code == isci_tmf_sata_srst_low) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700502 scu_stp_raw_request_construct_task_context(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700503 return SCI_SUCCESS;
504 } else {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700505 dev_err(&ireq->owning_controller->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700506 "%s: Request 0x%p received un-handled SAT "
507 "management protocol 0x%x.\n",
Dan Williams5076a1a2011-06-27 14:57:03 -0700508 __func__, ireq, tmf->tmf_code);
Dan Williams6f231dd2011-07-02 22:56:22 -0700509
Dan Williamsf1f52e72011-05-10 02:28:45 -0700510 return SCI_FAILURE;
511 }
Dan Williams6f231dd2011-07-02 22:56:22 -0700512 }
513
Dan Williamsf1f52e72011-05-10 02:28:45 -0700514 if (!sas_protocol_ata(task->task_proto)) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700515 dev_err(&ireq->owning_controller->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700516 "%s: Non-ATA protocol in SATA path: 0x%x\n",
517 __func__,
518 task->task_proto);
Dan Williams6f231dd2011-07-02 22:56:22 -0700519 return SCI_FAILURE;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700520
Dan Williams6f231dd2011-07-02 22:56:22 -0700521 }
522
Dan Williamsf1f52e72011-05-10 02:28:45 -0700523 /* non data */
Dan Williams5dec6f42011-05-10 02:28:49 -0700524 if (task->data_dir == DMA_NONE) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700525 scu_stp_raw_request_construct_task_context(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700526 return SCI_SUCCESS;
527 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700528
529 /* NCQ */
Dan Williams5dec6f42011-05-10 02:28:49 -0700530 if (task->ata_task.use_ncq) {
Dan Williams89a73012011-06-30 19:14:33 -0700531 sci_stp_optimized_request_construct(ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700532 SCU_TASK_TYPE_FPDMAQ_READ,
533 len, dir);
534 return SCI_SUCCESS;
535 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700536
537 /* DMA */
Dan Williams5dec6f42011-05-10 02:28:49 -0700538 if (task->ata_task.dma_xfer) {
Dan Williams89a73012011-06-30 19:14:33 -0700539 sci_stp_optimized_request_construct(ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700540 SCU_TASK_TYPE_DMA_IN,
541 len, dir);
542 return SCI_SUCCESS;
543 } else /* PIO */
Dan Williams89a73012011-06-30 19:14:33 -0700544 return sci_stp_pio_request_construct(ireq, copy);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700545
546 return status;
547}
548
Dan Williams89a73012011-06-30 19:14:33 -0700549static enum sci_status sci_io_request_construct_basic_ssp(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700550{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700551 struct sas_task *task = isci_request_access_task(ireq);
552
Dan Williams5076a1a2011-06-27 14:57:03 -0700553 ireq->protocol = SCIC_SSP_PROTOCOL;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700554
Dan Williams5076a1a2011-06-27 14:57:03 -0700555 scu_ssp_io_request_construct_task_context(ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700556 task->data_dir,
557 task->total_xfer_len);
558
Dan Williams89a73012011-06-30 19:14:33 -0700559 sci_io_request_build_ssp_command_iu(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700560
Dan Williams5076a1a2011-06-27 14:57:03 -0700561 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700562
563 return SCI_SUCCESS;
564}
565
Dan Williams89a73012011-06-30 19:14:33 -0700566enum sci_status sci_task_request_construct_ssp(
Dan Williams5076a1a2011-06-27 14:57:03 -0700567 struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700568{
569 /* Construct the SSP Task SCU Task Context */
Dan Williams5076a1a2011-06-27 14:57:03 -0700570 scu_ssp_task_request_construct_task_context(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700571
572 /* Fill in the SSP Task IU */
Dan Williams89a73012011-06-30 19:14:33 -0700573 sci_task_request_build_ssp_task_iu(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700574
Dan Williams5076a1a2011-06-27 14:57:03 -0700575 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williams6f231dd2011-07-02 22:56:22 -0700576
577 return SCI_SUCCESS;
578}
579
Dan Williams89a73012011-06-30 19:14:33 -0700580static enum sci_status sci_io_request_construct_basic_sata(struct isci_request *ireq)
Dan Williams6f231dd2011-07-02 22:56:22 -0700581{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700582 enum sci_status status;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700583 bool copy = false;
Dan Williams5076a1a2011-06-27 14:57:03 -0700584 struct sas_task *task = isci_request_access_task(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700585
Dan Williams5076a1a2011-06-27 14:57:03 -0700586 ireq->protocol = SCIC_STP_PROTOCOL;
Dan Williams6f231dd2011-07-02 22:56:22 -0700587
Dan Williamsf1f52e72011-05-10 02:28:45 -0700588 copy = (task->data_dir == DMA_NONE) ? false : true;
Dan Williams6f231dd2011-07-02 22:56:22 -0700589
Dan Williams89a73012011-06-30 19:14:33 -0700590 status = sci_io_request_construct_sata(ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700591 task->total_xfer_len,
592 task->data_dir,
593 copy);
Dan Williams6f231dd2011-07-02 22:56:22 -0700594
Dan Williamsf1f52e72011-05-10 02:28:45 -0700595 if (status == SCI_SUCCESS)
Dan Williams5076a1a2011-06-27 14:57:03 -0700596 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williams6f231dd2011-07-02 22:56:22 -0700597
Dan Williamsf1f52e72011-05-10 02:28:45 -0700598 return status;
Dan Williams6f231dd2011-07-02 22:56:22 -0700599}
600
Dan Williams89a73012011-06-30 19:14:33 -0700601enum sci_status sci_task_request_construct_sata(struct isci_request *ireq)
Dan Williams6f231dd2011-07-02 22:56:22 -0700602{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700603 enum sci_status status = SCI_SUCCESS;
Dan Williams6f231dd2011-07-02 22:56:22 -0700604
Dan Williamsf1f52e72011-05-10 02:28:45 -0700605 /* check for management protocols */
606 if (ireq->ttype == tmf_task) {
607 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700608
Dan Williamsf1f52e72011-05-10 02:28:45 -0700609 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
610 tmf->tmf_code == isci_tmf_sata_srst_low) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700611 scu_stp_raw_request_construct_task_context(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700612 } else {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700613 dev_err(&ireq->owning_controller->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700614 "%s: Request 0x%p received un-handled SAT "
615 "Protocol 0x%x.\n",
Dan Williams5076a1a2011-06-27 14:57:03 -0700616 __func__, ireq, tmf->tmf_code);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700617
618 return SCI_FAILURE;
619 }
Dan Williams6f231dd2011-07-02 22:56:22 -0700620 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700621
Dan Williams5dec6f42011-05-10 02:28:49 -0700622 if (status != SCI_SUCCESS)
623 return status;
Dan Williams5076a1a2011-06-27 14:57:03 -0700624 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700625
626 return status;
Dan Williams6f231dd2011-07-02 22:56:22 -0700627}
628
629/**
Dan Williamsf1f52e72011-05-10 02:28:45 -0700630 * sci_req_tx_bytes - bytes transferred when reply underruns request
631 * @sci_req: request that was terminated early
Dan Williams6f231dd2011-07-02 22:56:22 -0700632 */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700633#define SCU_TASK_CONTEXT_SRAM 0x200000
Dan Williams5076a1a2011-06-27 14:57:03 -0700634static u32 sci_req_tx_bytes(struct isci_request *ireq)
Dan Williams6f231dd2011-07-02 22:56:22 -0700635{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700636 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700637 u32 ret_val = 0;
Dan Williams6f231dd2011-07-02 22:56:22 -0700638
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700639 if (readl(&ihost->smu_registers->address_modifier) == 0) {
640 void __iomem *scu_reg_base = ihost->scu_registers;
Dan Williams6f231dd2011-07-02 22:56:22 -0700641
Dan Williamsf1f52e72011-05-10 02:28:45 -0700642 /* get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where
643 * BAR1 is the scu_registers
644 * 0x20002C = 0x200000 + 0x2c
645 * = start of task context SRAM + offset of (type.ssp.data_offset)
Dan Williams89a73012011-06-30 19:14:33 -0700646 * TCi is the io_tag of struct sci_request
Dan Williams67ea8382011-05-08 11:47:15 -0700647 */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700648 ret_val = readl(scu_reg_base +
649 (SCU_TASK_CONTEXT_SRAM + offsetof(struct scu_task_context, type.ssp.data_offset)) +
Dan Williams5076a1a2011-06-27 14:57:03 -0700650 ((sizeof(struct scu_task_context)) * ISCI_TAG_TCI(ireq->io_tag)));
Dan Williams67ea8382011-05-08 11:47:15 -0700651 }
Dan Williams6f231dd2011-07-02 22:56:22 -0700652
Dan Williamsf1f52e72011-05-10 02:28:45 -0700653 return ret_val;
Dan Williams6f231dd2011-07-02 22:56:22 -0700654}
655
Dan Williams89a73012011-06-30 19:14:33 -0700656enum sci_status sci_request_start(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700657{
Piotr Sawickif4636a72011-05-10 23:50:32 +0000658 enum sci_base_request_states state;
Dan Williams5076a1a2011-06-27 14:57:03 -0700659 struct scu_task_context *tc = ireq->tc;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700660 struct isci_host *ihost = ireq->owning_controller;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000661
Dan Williams5076a1a2011-06-27 14:57:03 -0700662 state = ireq->sm.current_state_id;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000663 if (state != SCI_REQ_CONSTRUCTED) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700664 dev_warn(&ihost->pdev->dev,
Piotr Sawickif4636a72011-05-10 23:50:32 +0000665 "%s: SCIC IO Request requested to start while in wrong "
666 "state %d\n", __func__, state);
667 return SCI_FAILURE_INVALID_STATE;
668 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700669
Dan Williams5076a1a2011-06-27 14:57:03 -0700670 tc->task_index = ISCI_TAG_TCI(ireq->io_tag);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700671
Dan Williams312e0c22011-06-28 13:47:09 -0700672 switch (tc->protocol_type) {
673 case SCU_TASK_CONTEXT_PROTOCOL_SMP:
674 case SCU_TASK_CONTEXT_PROTOCOL_SSP:
675 /* SSP/SMP Frame */
Dan Williams5076a1a2011-06-27 14:57:03 -0700676 tc->type.ssp.tag = ireq->io_tag;
Dan Williams312e0c22011-06-28 13:47:09 -0700677 tc->type.ssp.target_port_transfer_tag = 0xFFFF;
678 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000679
Dan Williams312e0c22011-06-28 13:47:09 -0700680 case SCU_TASK_CONTEXT_PROTOCOL_STP:
681 /* STP/SATA Frame
Dan Williams5076a1a2011-06-27 14:57:03 -0700682 * tc->type.stp.ncq_tag = ireq->ncq_tag;
Dan Williams312e0c22011-06-28 13:47:09 -0700683 */
684 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000685
Dan Williams312e0c22011-06-28 13:47:09 -0700686 case SCU_TASK_CONTEXT_PROTOCOL_NONE:
687 /* / @todo When do we set no protocol type? */
688 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000689
Dan Williams312e0c22011-06-28 13:47:09 -0700690 default:
691 /* This should never happen since we build the IO
692 * requests */
693 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000694 }
695
Dan Williams312e0c22011-06-28 13:47:09 -0700696 /* Add to the post_context the io tag value */
Dan Williams5076a1a2011-06-27 14:57:03 -0700697 ireq->post_context |= ISCI_TAG_TCI(ireq->io_tag);
Dan Williams312e0c22011-06-28 13:47:09 -0700698
699 /* Everything is good go ahead and change state */
Dan Williams5076a1a2011-06-27 14:57:03 -0700700 sci_change_state(&ireq->sm, SCI_REQ_STARTED);
Dan Williams312e0c22011-06-28 13:47:09 -0700701
702 return SCI_SUCCESS;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700703}
704
705enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -0700706sci_io_request_terminate(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700707{
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700708 enum sci_base_request_states state;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700709
Dan Williams5076a1a2011-06-27 14:57:03 -0700710 state = ireq->sm.current_state_id;
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700711
712 switch (state) {
Edmund Nadolskie3013702011-06-02 00:10:43 +0000713 case SCI_REQ_CONSTRUCTED:
Dan Williams34a99152011-07-01 02:25:15 -0700714 ireq->scu_status = SCU_TASK_DONE_TASK_ABORT;
715 ireq->sci_status = SCI_FAILURE_IO_TERMINATED;
Dan Williams5076a1a2011-06-27 14:57:03 -0700716 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700717 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000718 case SCI_REQ_STARTED:
719 case SCI_REQ_TASK_WAIT_TC_COMP:
720 case SCI_REQ_SMP_WAIT_RESP:
721 case SCI_REQ_SMP_WAIT_TC_COMP:
722 case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
723 case SCI_REQ_STP_UDMA_WAIT_D2H:
724 case SCI_REQ_STP_NON_DATA_WAIT_H2D:
725 case SCI_REQ_STP_NON_DATA_WAIT_D2H:
726 case SCI_REQ_STP_PIO_WAIT_H2D:
727 case SCI_REQ_STP_PIO_WAIT_FRAME:
728 case SCI_REQ_STP_PIO_DATA_IN:
729 case SCI_REQ_STP_PIO_DATA_OUT:
730 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
731 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
732 case SCI_REQ_STP_SOFT_RESET_WAIT_D2H:
Dan Williams5076a1a2011-06-27 14:57:03 -0700733 sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700734 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000735 case SCI_REQ_TASK_WAIT_TC_RESP:
Dan Williams5076a1a2011-06-27 14:57:03 -0700736 sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
737 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700738 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000739 case SCI_REQ_ABORTING:
Dan Williams5076a1a2011-06-27 14:57:03 -0700740 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700741 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000742 case SCI_REQ_COMPLETED:
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700743 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700744 dev_warn(&ireq->owning_controller->pdev->dev,
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700745 "%s: SCIC IO Request requested to abort while in wrong "
746 "state %d\n",
747 __func__,
Dan Williams5076a1a2011-06-27 14:57:03 -0700748 ireq->sm.current_state_id);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700749 break;
750 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700751
752 return SCI_FAILURE_INVALID_STATE;
753}
754
Dan Williams89a73012011-06-30 19:14:33 -0700755enum sci_status sci_request_complete(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700756{
Dan Williams79e2b6b2011-05-11 08:29:56 -0700757 enum sci_base_request_states state;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700758 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700759
Dan Williams5076a1a2011-06-27 14:57:03 -0700760 state = ireq->sm.current_state_id;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000761 if (WARN_ONCE(state != SCI_REQ_COMPLETED,
Dan Williams79e2b6b2011-05-11 08:29:56 -0700762 "isci: request completion from wrong state (%d)\n", state))
763 return SCI_FAILURE_INVALID_STATE;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700764
Dan Williams5076a1a2011-06-27 14:57:03 -0700765 if (ireq->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX)
Dan Williams89a73012011-06-30 19:14:33 -0700766 sci_controller_release_frame(ihost,
Dan Williams5076a1a2011-06-27 14:57:03 -0700767 ireq->saved_rx_frame_index);
Dan Williams79e2b6b2011-05-11 08:29:56 -0700768
769 /* XXX can we just stop the machine and remove the 'final' state? */
Dan Williams5076a1a2011-06-27 14:57:03 -0700770 sci_change_state(&ireq->sm, SCI_REQ_FINAL);
Dan Williams79e2b6b2011-05-11 08:29:56 -0700771 return SCI_SUCCESS;
772}
773
Dan Williams89a73012011-06-30 19:14:33 -0700774enum sci_status sci_io_request_event_handler(struct isci_request *ireq,
Dan Williams79e2b6b2011-05-11 08:29:56 -0700775 u32 event_code)
776{
777 enum sci_base_request_states state;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700778 struct isci_host *ihost = ireq->owning_controller;
Dan Williams79e2b6b2011-05-11 08:29:56 -0700779
Dan Williams5076a1a2011-06-27 14:57:03 -0700780 state = ireq->sm.current_state_id;
Dan Williams79e2b6b2011-05-11 08:29:56 -0700781
Edmund Nadolskie3013702011-06-02 00:10:43 +0000782 if (state != SCI_REQ_STP_PIO_DATA_IN) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700783 dev_warn(&ihost->pdev->dev, "%s: (%x) in wrong state %d\n",
Dan Williams79e2b6b2011-05-11 08:29:56 -0700784 __func__, event_code, state);
785
786 return SCI_FAILURE_INVALID_STATE;
787 }
788
789 switch (scu_get_event_specifier(event_code)) {
790 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
791 /* We are waiting for data and the SCU has R_ERR the data frame.
792 * Go back to waiting for the D2H Register FIS
793 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700794 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williams79e2b6b2011-05-11 08:29:56 -0700795 return SCI_SUCCESS;
796 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700797 dev_err(&ihost->pdev->dev,
Dan Williams79e2b6b2011-05-11 08:29:56 -0700798 "%s: pio request unexpected event %#x\n",
799 __func__, event_code);
800
801 /* TODO Should we fail the PIO request when we get an
802 * unexpected event?
803 */
804 return SCI_FAILURE;
805 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700806}
807
Dan Williamsf1f52e72011-05-10 02:28:45 -0700808/*
809 * This function copies response data for requests returning response data
810 * instead of sense data.
811 * @sci_req: This parameter specifies the request object for which to copy
812 * the response data.
813 */
Dan Williams89a73012011-06-30 19:14:33 -0700814static void sci_io_request_copy_response(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700815{
816 void *resp_buf;
817 u32 len;
818 struct ssp_response_iu *ssp_response;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700819 struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
820
Dan Williams5076a1a2011-06-27 14:57:03 -0700821 ssp_response = &ireq->ssp.rsp;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700822
823 resp_buf = &isci_tmf->resp.resp_iu;
824
825 len = min_t(u32,
826 SSP_RESP_IU_MAX_SIZE,
827 be32_to_cpu(ssp_response->response_data_len));
828
829 memcpy(resp_buf, ssp_response->resp_data, len);
830}
831
Edmund Nadolskie3013702011-06-02 00:10:43 +0000832static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -0700833request_started_state_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +0000834 u32 completion_code)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700835{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700836 struct ssp_response_iu *resp_iu;
Dan Williamsa7e255a2011-05-11 08:27:47 -0700837 u8 datapres;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700838
Dan Williamsa7e255a2011-05-11 08:27:47 -0700839 /* TODO: Any SDMA return code of other than 0 is bad decode 0x003C0000
840 * to determine SDMA status
Dan Williamsf1f52e72011-05-10 02:28:45 -0700841 */
842 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
843 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -0700844 ireq->scu_status = SCU_TASK_DONE_GOOD;
845 ireq->sci_status = SCI_SUCCESS;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700846 break;
Dan Williamsa7e255a2011-05-11 08:27:47 -0700847 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP): {
848 /* There are times when the SCU hardware will return an early
Dan Williamsf1f52e72011-05-10 02:28:45 -0700849 * response because the io request specified more data than is
850 * returned by the target device (mode pages, inquiry data,
851 * etc.). We must check the response stats to see if this is
852 * truly a failed request or a good request that just got
853 * completed early.
854 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700855 struct ssp_response_iu *resp = &ireq->ssp.rsp;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700856 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
857
Dan Williams5076a1a2011-06-27 14:57:03 -0700858 sci_swab32_cpy(&ireq->ssp.rsp,
859 &ireq->ssp.rsp,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700860 word_cnt);
861
862 if (resp->status == 0) {
Dan Williams34a99152011-07-01 02:25:15 -0700863 ireq->scu_status = SCU_TASK_DONE_GOOD;
864 ireq->sci_status = SCI_SUCCESS_IO_DONE_EARLY;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700865 } else {
Dan Williams34a99152011-07-01 02:25:15 -0700866 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
867 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700868 }
Dan Williamsa7e255a2011-05-11 08:27:47 -0700869 break;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700870 }
Dan Williamsa7e255a2011-05-11 08:27:47 -0700871 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE): {
Dan Williamsf1f52e72011-05-10 02:28:45 -0700872 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
873
Dan Williams5076a1a2011-06-27 14:57:03 -0700874 sci_swab32_cpy(&ireq->ssp.rsp,
875 &ireq->ssp.rsp,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700876 word_cnt);
877
Dan Williams34a99152011-07-01 02:25:15 -0700878 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
879 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700880 break;
881 }
882
883 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
Dan Williamsa7e255a2011-05-11 08:27:47 -0700884 /* TODO With TASK_DONE_RESP_LEN_ERR is the response frame
Dan Williamsf1f52e72011-05-10 02:28:45 -0700885 * guaranteed to be received before this completion status is
886 * posted?
887 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700888 resp_iu = &ireq->ssp.rsp;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700889 datapres = resp_iu->datapres;
890
Dan Williamsa7e255a2011-05-11 08:27:47 -0700891 if (datapres == 1 || datapres == 2) {
Dan Williams34a99152011-07-01 02:25:15 -0700892 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
893 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
894 } else {
895 ireq->scu_status = SCU_TASK_DONE_GOOD;
896 ireq->sci_status = SCI_SUCCESS;
897 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700898 break;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700899 /* only stp device gets suspended. */
900 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
901 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR):
902 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR):
903 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR):
904 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR):
905 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN):
906 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
907 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP):
908 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS):
909 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
910 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR):
Dan Williams5076a1a2011-06-27 14:57:03 -0700911 if (ireq->protocol == SCIC_STP_PROTOCOL) {
Dan Williams34a99152011-07-01 02:25:15 -0700912 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
913 SCU_COMPLETION_TL_STATUS_SHIFT;
914 ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700915 } else {
Dan Williams34a99152011-07-01 02:25:15 -0700916 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
917 SCU_COMPLETION_TL_STATUS_SHIFT;
918 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700919 }
920 break;
921
922 /* both stp/ssp device gets suspended */
923 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR):
924 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION):
925 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1):
926 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2):
927 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3):
928 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION):
929 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION):
930 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY):
931 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED):
932 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
Dan Williams34a99152011-07-01 02:25:15 -0700933 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
934 SCU_COMPLETION_TL_STATUS_SHIFT;
935 ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700936 break;
937
938 /* neither ssp nor stp gets suspended. */
939 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR):
940 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR):
941 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR):
942 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR):
943 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR):
944 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA):
945 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
946 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
947 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
948 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
949 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA):
950 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL):
951 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV):
952 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV):
953 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND):
954 default:
Dan Williams34a99152011-07-01 02:25:15 -0700955 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
956 SCU_COMPLETION_TL_STATUS_SHIFT;
957 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700958 break;
959 }
960
961 /*
962 * TODO: This is probably wrong for ACK/NAK timeout conditions
963 */
964
965 /* In all cases we will treat this as the completion of the IO req. */
Dan Williams5076a1a2011-06-27 14:57:03 -0700966 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700967 return SCI_SUCCESS;
968}
969
Edmund Nadolskie3013702011-06-02 00:10:43 +0000970static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -0700971request_aborting_state_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +0000972 u32 completion_code)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700973{
974 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
975 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
976 case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT):
Dan Williams34a99152011-07-01 02:25:15 -0700977 ireq->scu_status = SCU_TASK_DONE_TASK_ABORT;
978 ireq->sci_status = SCI_FAILURE_IO_TERMINATED;
Dan Williams5076a1a2011-06-27 14:57:03 -0700979 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700980 break;
981
982 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -0700983 /* Unless we get some strange error wait for the task abort to complete
984 * TODO: Should there be a state change for this completion?
985 */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700986 break;
987 }
988
989 return SCI_SUCCESS;
990}
991
Dan Williams5076a1a2011-06-27 14:57:03 -0700992static enum sci_status ssp_task_request_await_tc_event(struct isci_request *ireq,
Dan Williamsa7e255a2011-05-11 08:27:47 -0700993 u32 completion_code)
Dan Williamsf1393032011-05-10 02:28:47 -0700994{
995 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
996 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -0700997 ireq->scu_status = SCU_TASK_DONE_GOOD;
998 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -0700999 sci_change_state(&ireq->sm, SCI_REQ_TASK_WAIT_TC_RESP);
Dan Williamsf1393032011-05-10 02:28:47 -07001000 break;
Dan Williamsf1393032011-05-10 02:28:47 -07001001 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001002 /* Currently, the decision is to simply allow the task request
1003 * to timeout if the task IU wasn't received successfully.
1004 * There is a potential for receiving multiple task responses if
1005 * we decide to send the task IU again.
1006 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001007 dev_warn(&ireq->owning_controller->pdev->dev,
Dan Williamsf1393032011-05-10 02:28:47 -07001008 "%s: TaskRequest:0x%p CompletionCode:%x - "
Dan Williams5076a1a2011-06-27 14:57:03 -07001009 "ACK/NAK timeout\n", __func__, ireq,
Dan Williamsf1393032011-05-10 02:28:47 -07001010 completion_code);
1011
Dan Williams5076a1a2011-06-27 14:57:03 -07001012 sci_change_state(&ireq->sm, SCI_REQ_TASK_WAIT_TC_RESP);
Dan Williamsf1393032011-05-10 02:28:47 -07001013 break;
Dan Williamsf1393032011-05-10 02:28:47 -07001014 default:
Edmund Nadolskie3013702011-06-02 00:10:43 +00001015 /*
1016 * All other completion status cause the IO to be complete.
1017 * If a NAK was received, then it is up to the user to retry
1018 * the request.
Dan Williamsa7e255a2011-05-11 08:27:47 -07001019 */
Dan Williams34a99152011-07-01 02:25:15 -07001020 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1021 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001022 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf1393032011-05-10 02:28:47 -07001023 break;
1024 }
1025
1026 return SCI_SUCCESS;
1027}
1028
Edmund Nadolskie3013702011-06-02 00:10:43 +00001029static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001030smp_request_await_response_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001031 u32 completion_code)
Dan Williamsc72086e2011-05-10 02:28:48 -07001032{
1033 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1034 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001035 /* In the AWAIT RESPONSE state, any TC completion is
1036 * unexpected. but if the TC has success status, we
1037 * complete the IO anyway.
1038 */
Dan Williams34a99152011-07-01 02:25:15 -07001039 ireq->scu_status = SCU_TASK_DONE_GOOD;
1040 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001041 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001042 break;
Dan Williamsc72086e2011-05-10 02:28:48 -07001043 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
1044 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
1045 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
1046 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001047 /* These status has been seen in a specific LSI
1048 * expander, which sometimes is not able to send smp
1049 * response within 2 ms. This causes our hardware break
1050 * the connection and set TC completion with one of
1051 * these SMP_XXX_XX_ERR status. For these type of error,
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001052 * we ask ihost user to retry the request.
Dan Williamsa7e255a2011-05-11 08:27:47 -07001053 */
Dan Williams34a99152011-07-01 02:25:15 -07001054 ireq->scu_status = SCU_TASK_DONE_SMP_RESP_TO_ERR;
1055 ireq->sci_status = SCI_FAILURE_RETRY_REQUIRED;
Dan Williams5076a1a2011-06-27 14:57:03 -07001056 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001057 break;
Dan Williamsc72086e2011-05-10 02:28:48 -07001058 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001059 /* All other completion status cause the IO to be complete. If a NAK
1060 * was received, then it is up to the user to retry the request
1061 */
Dan Williams34a99152011-07-01 02:25:15 -07001062 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1063 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001064 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001065 break;
1066 }
1067
1068 return SCI_SUCCESS;
1069}
1070
Edmund Nadolskie3013702011-06-02 00:10:43 +00001071static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001072smp_request_await_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001073 u32 completion_code)
Dan Williamsc72086e2011-05-10 02:28:48 -07001074{
1075 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1076 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001077 ireq->scu_status = SCU_TASK_DONE_GOOD;
1078 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001079 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001080 break;
Dan Williamsc72086e2011-05-10 02:28:48 -07001081 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001082 /* All other completion status cause the IO to be
1083 * complete. If a NAK was received, then it is up to
1084 * the user to retry the request.
1085 */
Dan Williams34a99152011-07-01 02:25:15 -07001086 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1087 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001088 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001089 break;
1090 }
1091
1092 return SCI_SUCCESS;
1093}
1094
Dan Williams89a73012011-06-30 19:14:33 -07001095void sci_stp_io_request_set_ncq_tag(struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -07001096 u16 ncq_tag)
1097{
1098 /**
1099 * @note This could be made to return an error to the user if the user
1100 * attempts to set the NCQ tag in the wrong state.
1101 */
Dan Williams5076a1a2011-06-27 14:57:03 -07001102 ireq->tc->type.stp.ncq_tag = ncq_tag;
Dan Williams5dec6f42011-05-10 02:28:49 -07001103}
1104
Dan Williamsba7cb222011-06-27 11:56:41 -07001105static struct scu_sgl_element *pio_sgl_next(struct isci_stp_request *stp_req)
Dan Williams5dec6f42011-05-10 02:28:49 -07001106{
Dan Williams312e0c22011-06-28 13:47:09 -07001107 struct scu_sgl_element *sgl;
1108 struct scu_sgl_element_pair *sgl_pair;
Dan Williams5076a1a2011-06-27 14:57:03 -07001109 struct isci_request *ireq = to_ireq(stp_req);
Dan Williamsba7cb222011-06-27 11:56:41 -07001110 struct isci_stp_pio_sgl *pio_sgl = &stp_req->sgl;
Dan Williams5dec6f42011-05-10 02:28:49 -07001111
Dan Williams5076a1a2011-06-27 14:57:03 -07001112 sgl_pair = to_sgl_element_pair(ireq, pio_sgl->index);
Dan Williams312e0c22011-06-28 13:47:09 -07001113 if (!sgl_pair)
1114 sgl = NULL;
Dan Williamsba7cb222011-06-27 11:56:41 -07001115 else if (pio_sgl->set == SCU_SGL_ELEMENT_PAIR_A) {
Dan Williams312e0c22011-06-28 13:47:09 -07001116 if (sgl_pair->B.address_lower == 0 &&
1117 sgl_pair->B.address_upper == 0) {
1118 sgl = NULL;
Dan Williams5dec6f42011-05-10 02:28:49 -07001119 } else {
Dan Williamsba7cb222011-06-27 11:56:41 -07001120 pio_sgl->set = SCU_SGL_ELEMENT_PAIR_B;
Dan Williams312e0c22011-06-28 13:47:09 -07001121 sgl = &sgl_pair->B;
Dan Williams5dec6f42011-05-10 02:28:49 -07001122 }
1123 } else {
Dan Williams312e0c22011-06-28 13:47:09 -07001124 if (sgl_pair->next_pair_lower == 0 &&
1125 sgl_pair->next_pair_upper == 0) {
1126 sgl = NULL;
Dan Williams5dec6f42011-05-10 02:28:49 -07001127 } else {
Dan Williamsba7cb222011-06-27 11:56:41 -07001128 pio_sgl->index++;
1129 pio_sgl->set = SCU_SGL_ELEMENT_PAIR_A;
Dan Williams5076a1a2011-06-27 14:57:03 -07001130 sgl_pair = to_sgl_element_pair(ireq, pio_sgl->index);
Dan Williams312e0c22011-06-28 13:47:09 -07001131 sgl = &sgl_pair->A;
Dan Williams5dec6f42011-05-10 02:28:49 -07001132 }
1133 }
1134
Dan Williams312e0c22011-06-28 13:47:09 -07001135 return sgl;
Dan Williams5dec6f42011-05-10 02:28:49 -07001136}
1137
Edmund Nadolskie3013702011-06-02 00:10:43 +00001138static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001139stp_request_non_data_await_h2d_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001140 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001141{
1142 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1143 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001144 ireq->scu_status = SCU_TASK_DONE_GOOD;
1145 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001146 sci_change_state(&ireq->sm, SCI_REQ_STP_NON_DATA_WAIT_D2H);
Dan Williams5dec6f42011-05-10 02:28:49 -07001147 break;
1148
1149 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001150 /* All other completion status cause the IO to be
1151 * complete. If a NAK was received, then it is up to
1152 * the user to retry the request.
1153 */
Dan Williams34a99152011-07-01 02:25:15 -07001154 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1155 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001156 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001157 break;
1158 }
1159
1160 return SCI_SUCCESS;
1161}
1162
Dan Williams5dec6f42011-05-10 02:28:49 -07001163#define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */
1164
1165/* transmit DATA_FIS from (current sgl + offset) for input
1166 * parameter length. current sgl and offset is alreay stored in the IO request
1167 */
Dan Williams89a73012011-06-30 19:14:33 -07001168static enum sci_status sci_stp_request_pio_data_out_trasmit_data_frame(
Dan Williams5076a1a2011-06-27 14:57:03 -07001169 struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -07001170 u32 length)
1171{
Dan Williams5076a1a2011-06-27 14:57:03 -07001172 struct isci_stp_request *stp_req = &ireq->stp.req;
1173 struct scu_task_context *task_context = ireq->tc;
Dan Williams312e0c22011-06-28 13:47:09 -07001174 struct scu_sgl_element_pair *sgl_pair;
Dan Williams5dec6f42011-05-10 02:28:49 -07001175 struct scu_sgl_element *current_sgl;
1176
1177 /* Recycle the TC and reconstruct it for sending out DATA FIS containing
1178 * for the data from current_sgl+offset for the input length
1179 */
Dan Williams5076a1a2011-06-27 14:57:03 -07001180 sgl_pair = to_sgl_element_pair(ireq, stp_req->sgl.index);
Dan Williamsba7cb222011-06-27 11:56:41 -07001181 if (stp_req->sgl.set == SCU_SGL_ELEMENT_PAIR_A)
Dan Williams312e0c22011-06-28 13:47:09 -07001182 current_sgl = &sgl_pair->A;
Dan Williams5dec6f42011-05-10 02:28:49 -07001183 else
Dan Williams312e0c22011-06-28 13:47:09 -07001184 current_sgl = &sgl_pair->B;
Dan Williams5dec6f42011-05-10 02:28:49 -07001185
1186 /* update the TC */
1187 task_context->command_iu_upper = current_sgl->address_upper;
1188 task_context->command_iu_lower = current_sgl->address_lower;
1189 task_context->transfer_length_bytes = length;
1190 task_context->type.stp.fis_type = FIS_DATA;
1191
1192 /* send the new TC out. */
Dan Williams89a73012011-06-30 19:14:33 -07001193 return sci_controller_continue_io(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -07001194}
1195
Dan Williams89a73012011-06-30 19:14:33 -07001196static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_request *ireq)
Dan Williams5dec6f42011-05-10 02:28:49 -07001197{
Dan Williams5076a1a2011-06-27 14:57:03 -07001198 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williams312e0c22011-06-28 13:47:09 -07001199 struct scu_sgl_element_pair *sgl_pair;
Dan Williamsba7cb222011-06-27 11:56:41 -07001200 struct scu_sgl_element *sgl;
1201 enum sci_status status;
1202 u32 offset;
1203 u32 len = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07001204
Dan Williamsba7cb222011-06-27 11:56:41 -07001205 offset = stp_req->sgl.offset;
Dan Williams5076a1a2011-06-27 14:57:03 -07001206 sgl_pair = to_sgl_element_pair(ireq, stp_req->sgl.index);
Dan Williams312e0c22011-06-28 13:47:09 -07001207 if (WARN_ONCE(!sgl_pair, "%s: null sgl element", __func__))
1208 return SCI_FAILURE;
Dan Williams5dec6f42011-05-10 02:28:49 -07001209
Dan Williamsba7cb222011-06-27 11:56:41 -07001210 if (stp_req->sgl.set == SCU_SGL_ELEMENT_PAIR_A) {
1211 sgl = &sgl_pair->A;
1212 len = sgl_pair->A.length - offset;
Dan Williams5dec6f42011-05-10 02:28:49 -07001213 } else {
Dan Williamsba7cb222011-06-27 11:56:41 -07001214 sgl = &sgl_pair->B;
1215 len = sgl_pair->B.length - offset;
Dan Williams5dec6f42011-05-10 02:28:49 -07001216 }
1217
Dan Williamsba7cb222011-06-27 11:56:41 -07001218 if (stp_req->pio_len == 0)
1219 return SCI_SUCCESS;
Dan Williams5dec6f42011-05-10 02:28:49 -07001220
Dan Williamsba7cb222011-06-27 11:56:41 -07001221 if (stp_req->pio_len >= len) {
Dan Williams89a73012011-06-30 19:14:33 -07001222 status = sci_stp_request_pio_data_out_trasmit_data_frame(ireq, len);
Dan Williamsba7cb222011-06-27 11:56:41 -07001223 if (status != SCI_SUCCESS)
1224 return status;
1225 stp_req->pio_len -= len;
Dan Williams5dec6f42011-05-10 02:28:49 -07001226
Dan Williamsba7cb222011-06-27 11:56:41 -07001227 /* update the current sgl, offset and save for future */
1228 sgl = pio_sgl_next(stp_req);
1229 offset = 0;
1230 } else if (stp_req->pio_len < len) {
Dan Williams89a73012011-06-30 19:14:33 -07001231 sci_stp_request_pio_data_out_trasmit_data_frame(ireq, stp_req->pio_len);
Dan Williamsba7cb222011-06-27 11:56:41 -07001232
1233 /* Sgl offset will be adjusted and saved for future */
1234 offset += stp_req->pio_len;
1235 sgl->address_lower += stp_req->pio_len;
1236 stp_req->pio_len = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07001237 }
1238
Dan Williamsba7cb222011-06-27 11:56:41 -07001239 stp_req->sgl.offset = offset;
Dan Williams5dec6f42011-05-10 02:28:49 -07001240
1241 return status;
1242}
1243
1244/**
1245 *
1246 * @stp_request: The request that is used for the SGL processing.
1247 * @data_buffer: The buffer of data to be copied.
1248 * @length: The length of the data transfer.
1249 *
1250 * Copy the data from the buffer for the length specified to the IO reqeust SGL
1251 * specified data region. enum sci_status
1252 */
1253static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07001254sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req,
Dan Williams5dec6f42011-05-10 02:28:49 -07001255 u8 *data_buf, u32 len)
1256{
Dan Williams5dec6f42011-05-10 02:28:49 -07001257 struct isci_request *ireq;
1258 u8 *src_addr;
1259 int copy_len;
1260 struct sas_task *task;
1261 struct scatterlist *sg;
1262 void *kaddr;
1263 int total_len = len;
1264
Dan Williams5076a1a2011-06-27 14:57:03 -07001265 ireq = to_ireq(stp_req);
Dan Williams5dec6f42011-05-10 02:28:49 -07001266 task = isci_request_access_task(ireq);
1267 src_addr = data_buf;
1268
1269 if (task->num_scatter > 0) {
1270 sg = task->scatter;
1271
1272 while (total_len > 0) {
1273 struct page *page = sg_page(sg);
1274
1275 copy_len = min_t(int, total_len, sg_dma_len(sg));
1276 kaddr = kmap_atomic(page, KM_IRQ0);
1277 memcpy(kaddr + sg->offset, src_addr, copy_len);
1278 kunmap_atomic(kaddr, KM_IRQ0);
1279 total_len -= copy_len;
1280 src_addr += copy_len;
1281 sg = sg_next(sg);
1282 }
1283 } else {
1284 BUG_ON(task->total_xfer_len < total_len);
1285 memcpy(task->scatter, src_addr, total_len);
1286 }
1287
1288 return SCI_SUCCESS;
1289}
1290
1291/**
1292 *
1293 * @sci_req: The PIO DATA IN request that is to receive the data.
1294 * @data_buffer: The buffer to copy from.
1295 *
1296 * Copy the data buffer to the io request data region. enum sci_status
1297 */
Dan Williams89a73012011-06-30 19:14:33 -07001298static enum sci_status sci_stp_request_pio_data_in_copy_data(
Dan Williamsba7cb222011-06-27 11:56:41 -07001299 struct isci_stp_request *stp_req,
Dan Williams5dec6f42011-05-10 02:28:49 -07001300 u8 *data_buffer)
1301{
1302 enum sci_status status;
1303
1304 /*
1305 * If there is less than 1K remaining in the transfer request
1306 * copy just the data for the transfer */
Dan Williamsba7cb222011-06-27 11:56:41 -07001307 if (stp_req->pio_len < SCU_MAX_FRAME_BUFFER_SIZE) {
Dan Williams89a73012011-06-30 19:14:33 -07001308 status = sci_stp_request_pio_data_in_copy_data_buffer(
Dan Williamsba7cb222011-06-27 11:56:41 -07001309 stp_req, data_buffer, stp_req->pio_len);
Dan Williams5dec6f42011-05-10 02:28:49 -07001310
1311 if (status == SCI_SUCCESS)
Dan Williamsba7cb222011-06-27 11:56:41 -07001312 stp_req->pio_len = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07001313 } else {
1314 /* We are transfering the whole frame so copy */
Dan Williams89a73012011-06-30 19:14:33 -07001315 status = sci_stp_request_pio_data_in_copy_data_buffer(
Dan Williamsba7cb222011-06-27 11:56:41 -07001316 stp_req, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
Dan Williams5dec6f42011-05-10 02:28:49 -07001317
1318 if (status == SCI_SUCCESS)
Dan Williamsba7cb222011-06-27 11:56:41 -07001319 stp_req->pio_len -= SCU_MAX_FRAME_BUFFER_SIZE;
Dan Williams5dec6f42011-05-10 02:28:49 -07001320 }
1321
1322 return status;
1323}
1324
Edmund Nadolskie3013702011-06-02 00:10:43 +00001325static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001326stp_request_pio_await_h2d_completion_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001327 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001328{
1329 enum sci_status status = SCI_SUCCESS;
1330
1331 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1332 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001333 ireq->scu_status = SCU_TASK_DONE_GOOD;
1334 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001335 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williams5dec6f42011-05-10 02:28:49 -07001336 break;
1337
1338 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001339 /* All other completion status cause the IO to be
1340 * complete. If a NAK was received, then it is up to
1341 * the user to retry the request.
1342 */
Dan Williams34a99152011-07-01 02:25:15 -07001343 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1344 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001345 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001346 break;
1347 }
1348
1349 return status;
1350}
1351
Edmund Nadolskie3013702011-06-02 00:10:43 +00001352static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001353pio_data_out_tx_done_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001354 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001355{
1356 enum sci_status status = SCI_SUCCESS;
1357 bool all_frames_transferred = false;
Dan Williams5076a1a2011-06-27 14:57:03 -07001358 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williams5dec6f42011-05-10 02:28:49 -07001359
1360 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1361 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1362 /* Transmit data */
Dan Williamsba7cb222011-06-27 11:56:41 -07001363 if (stp_req->pio_len != 0) {
Dan Williams89a73012011-06-30 19:14:33 -07001364 status = sci_stp_request_pio_data_out_transmit_data(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -07001365 if (status == SCI_SUCCESS) {
Dan Williamsba7cb222011-06-27 11:56:41 -07001366 if (stp_req->pio_len == 0)
Dan Williams5dec6f42011-05-10 02:28:49 -07001367 all_frames_transferred = true;
1368 }
Dan Williamsba7cb222011-06-27 11:56:41 -07001369 } else if (stp_req->pio_len == 0) {
Dan Williams5dec6f42011-05-10 02:28:49 -07001370 /*
1371 * this will happen if the all data is written at the
1372 * first time after the pio setup fis is received
1373 */
1374 all_frames_transferred = true;
1375 }
1376
1377 /* all data transferred. */
1378 if (all_frames_transferred) {
1379 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001380 * Change the state to SCI_REQ_STP_PIO_DATA_IN
Dan Williams5dec6f42011-05-10 02:28:49 -07001381 * and wait for PIO_SETUP fis / or D2H REg fis. */
Dan Williams5076a1a2011-06-27 14:57:03 -07001382 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williams5dec6f42011-05-10 02:28:49 -07001383 }
1384 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001385
Dan Williams5dec6f42011-05-10 02:28:49 -07001386 default:
1387 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001388 * All other completion status cause the IO to be complete.
1389 * If a NAK was received, then it is up to the user to retry
1390 * the request.
1391 */
Dan Williams34a99152011-07-01 02:25:15 -07001392 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1393 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001394 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001395 break;
1396 }
1397
1398 return status;
1399}
1400
Dan Williams89a73012011-06-30 19:14:33 -07001401static enum sci_status sci_stp_request_udma_general_frame_handler(struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -07001402 u32 frame_index)
1403{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001404 struct isci_host *ihost = ireq->owning_controller;
Dan Williams5dec6f42011-05-10 02:28:49 -07001405 struct dev_to_host_fis *frame_header;
1406 enum sci_status status;
1407 u32 *frame_buffer;
1408
Dan Williams89a73012011-06-30 19:14:33 -07001409 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williams5dec6f42011-05-10 02:28:49 -07001410 frame_index,
1411 (void **)&frame_header);
1412
1413 if ((status == SCI_SUCCESS) &&
1414 (frame_header->fis_type == FIS_REGD2H)) {
Dan Williams89a73012011-06-30 19:14:33 -07001415 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williams5dec6f42011-05-10 02:28:49 -07001416 frame_index,
1417 (void **)&frame_buffer);
1418
Dan Williams89a73012011-06-30 19:14:33 -07001419 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williams5dec6f42011-05-10 02:28:49 -07001420 frame_header,
1421 frame_buffer);
1422 }
1423
Dan Williams89a73012011-06-30 19:14:33 -07001424 sci_controller_release_frame(ihost, frame_index);
Dan Williams5dec6f42011-05-10 02:28:49 -07001425
1426 return status;
1427}
1428
Edmund Nadolskie3013702011-06-02 00:10:43 +00001429enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07001430sci_io_request_frame_handler(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001431 u32 frame_index)
Dan Williamsd1c637c32011-05-11 08:27:47 -07001432{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001433 struct isci_host *ihost = ireq->owning_controller;
Dan Williams5076a1a2011-06-27 14:57:03 -07001434 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001435 enum sci_base_request_states state;
1436 enum sci_status status;
1437 ssize_t word_cnt;
1438
Dan Williams5076a1a2011-06-27 14:57:03 -07001439 state = ireq->sm.current_state_id;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001440 switch (state) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001441 case SCI_REQ_STARTED: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001442 struct ssp_frame_hdr ssp_hdr;
1443 void *frame_header;
1444
Dan Williams89a73012011-06-30 19:14:33 -07001445 sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001446 frame_index,
1447 &frame_header);
1448
1449 word_cnt = sizeof(struct ssp_frame_hdr) / sizeof(u32);
1450 sci_swab32_cpy(&ssp_hdr, frame_header, word_cnt);
1451
1452 if (ssp_hdr.frame_type == SSP_RESPONSE) {
1453 struct ssp_response_iu *resp_iu;
1454 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
1455
Dan Williams89a73012011-06-30 19:14:33 -07001456 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001457 frame_index,
1458 (void **)&resp_iu);
1459
Dan Williams5076a1a2011-06-27 14:57:03 -07001460 sci_swab32_cpy(&ireq->ssp.rsp, resp_iu, word_cnt);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001461
Dan Williams5076a1a2011-06-27 14:57:03 -07001462 resp_iu = &ireq->ssp.rsp;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001463
1464 if (resp_iu->datapres == 0x01 ||
1465 resp_iu->datapres == 0x02) {
Dan Williams34a99152011-07-01 02:25:15 -07001466 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1467 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
1468 } else {
1469 ireq->scu_status = SCU_TASK_DONE_GOOD;
1470 ireq->sci_status = SCI_SUCCESS;
1471 }
Dan Williamsd1c637c32011-05-11 08:27:47 -07001472 } else {
1473 /* not a response frame, why did it get forwarded? */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001474 dev_err(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001475 "%s: SCIC IO Request 0x%p received unexpected "
Dan Williams5076a1a2011-06-27 14:57:03 -07001476 "frame %d type 0x%02x\n", __func__, ireq,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001477 frame_index, ssp_hdr.frame_type);
1478 }
1479
1480 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001481 * In any case we are done with this frame buffer return it to
1482 * the controller
Dan Williamsd1c637c32011-05-11 08:27:47 -07001483 */
Dan Williams89a73012011-06-30 19:14:33 -07001484 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001485
1486 return SCI_SUCCESS;
1487 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001488
1489 case SCI_REQ_TASK_WAIT_TC_RESP:
Dan Williams89a73012011-06-30 19:14:33 -07001490 sci_io_request_copy_response(ireq);
Dan Williams5076a1a2011-06-27 14:57:03 -07001491 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams89a73012011-06-30 19:14:33 -07001492 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001493 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001494
1495 case SCI_REQ_SMP_WAIT_RESP: {
Dan Williams5076a1a2011-06-27 14:57:03 -07001496 struct smp_resp *rsp_hdr = &ireq->smp.rsp;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001497 void *frame_header;
1498
Dan Williams89a73012011-06-30 19:14:33 -07001499 sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001500 frame_index,
1501 &frame_header);
1502
1503 /* byte swap the header. */
1504 word_cnt = SMP_RESP_HDR_SZ / sizeof(u32);
1505 sci_swab32_cpy(rsp_hdr, frame_header, word_cnt);
1506
1507 if (rsp_hdr->frame_type == SMP_RESPONSE) {
1508 void *smp_resp;
1509
Dan Williams89a73012011-06-30 19:14:33 -07001510 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001511 frame_index,
1512 &smp_resp);
1513
Dan Williams5edc3342011-06-16 17:20:35 -07001514 word_cnt = (sizeof(struct smp_resp) - SMP_RESP_HDR_SZ) /
Dan Williamsd1c637c32011-05-11 08:27:47 -07001515 sizeof(u32);
1516
1517 sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ,
1518 smp_resp, word_cnt);
1519
Dan Williams34a99152011-07-01 02:25:15 -07001520 ireq->scu_status = SCU_TASK_DONE_GOOD;
1521 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001522 sci_change_state(&ireq->sm, SCI_REQ_SMP_WAIT_TC_COMP);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001523 } else {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001524 /*
1525 * This was not a response frame why did it get
1526 * forwarded?
1527 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001528 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001529 "%s: SCIC SMP Request 0x%p received unexpected "
1530 "frame %d type 0x%02x\n",
1531 __func__,
Dan Williams5076a1a2011-06-27 14:57:03 -07001532 ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001533 frame_index,
1534 rsp_hdr->frame_type);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001535
Dan Williams34a99152011-07-01 02:25:15 -07001536 ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR;
1537 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001538 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001539 }
1540
Dan Williams89a73012011-06-30 19:14:33 -07001541 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001542
1543 return SCI_SUCCESS;
1544 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001545
1546 case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
Dan Williams89a73012011-06-30 19:14:33 -07001547 return sci_stp_request_udma_general_frame_handler(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001548 frame_index);
1549
1550 case SCI_REQ_STP_UDMA_WAIT_D2H:
Dan Williamsd1c637c32011-05-11 08:27:47 -07001551 /* Use the general frame handler to copy the resposne data */
Dan Williams34a99152011-07-01 02:25:15 -07001552 status = sci_stp_request_udma_general_frame_handler(ireq, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001553
1554 if (status != SCI_SUCCESS)
1555 return status;
1556
Dan Williams34a99152011-07-01 02:25:15 -07001557 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1558 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
1559 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001560 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001561
1562 case SCI_REQ_STP_NON_DATA_WAIT_D2H: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001563 struct dev_to_host_fis *frame_header;
1564 u32 *frame_buffer;
1565
Dan Williams89a73012011-06-30 19:14:33 -07001566 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001567 frame_index,
1568 (void **)&frame_header);
1569
1570 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001571 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001572 "%s: SCIC IO Request 0x%p could not get frame "
1573 "header for frame index %d, status %x\n",
1574 __func__,
1575 stp_req,
1576 frame_index,
1577 status);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001578
1579 return status;
1580 }
1581
1582 switch (frame_header->fis_type) {
1583 case FIS_REGD2H:
Dan Williams89a73012011-06-30 19:14:33 -07001584 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001585 frame_index,
1586 (void **)&frame_buffer);
1587
Dan Williams89a73012011-06-30 19:14:33 -07001588 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001589 frame_header,
1590 frame_buffer);
1591
1592 /* The command has completed with error */
Dan Williams34a99152011-07-01 02:25:15 -07001593 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1594 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001595 break;
1596
1597 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001598 dev_warn(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001599 "%s: IO Request:0x%p Frame Id:%d protocol "
1600 "violation occurred\n", __func__, stp_req,
1601 frame_index);
1602
Dan Williams34a99152011-07-01 02:25:15 -07001603 ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
1604 ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001605 break;
1606 }
1607
Dan Williams5076a1a2011-06-27 14:57:03 -07001608 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001609
1610 /* Frame has been decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001611 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001612
1613 return status;
1614 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001615
1616 case SCI_REQ_STP_PIO_WAIT_FRAME: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001617 struct sas_task *task = isci_request_access_task(ireq);
1618 struct dev_to_host_fis *frame_header;
1619 u32 *frame_buffer;
1620
Dan Williams89a73012011-06-30 19:14:33 -07001621 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001622 frame_index,
1623 (void **)&frame_header);
1624
1625 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001626 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001627 "%s: SCIC IO Request 0x%p could not get frame "
1628 "header for frame index %d, status %x\n",
Dan Williamsd1c637c32011-05-11 08:27:47 -07001629 __func__, stp_req, frame_index, status);
1630 return status;
1631 }
1632
1633 switch (frame_header->fis_type) {
1634 case FIS_PIO_SETUP:
1635 /* Get from the frame buffer the PIO Setup Data */
Dan Williams89a73012011-06-30 19:14:33 -07001636 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001637 frame_index,
1638 (void **)&frame_buffer);
1639
Edmund Nadolskie3013702011-06-02 00:10:43 +00001640 /* Get the data from the PIO Setup The SCU Hardware
1641 * returns first word in the frame_header and the rest
1642 * of the data is in the frame buffer so we need to
1643 * back up one dword
Dan Williamsd1c637c32011-05-11 08:27:47 -07001644 */
1645
1646 /* transfer_count: first 16bits in the 4th dword */
Dan Williamsba7cb222011-06-27 11:56:41 -07001647 stp_req->pio_len = frame_buffer[3] & 0xffff;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001648
Dan Williamsba7cb222011-06-27 11:56:41 -07001649 /* status: 4th byte in the 3rd dword */
1650 stp_req->status = (frame_buffer[2] >> 24) & 0xff;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001651
Dan Williams89a73012011-06-30 19:14:33 -07001652 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001653 frame_header,
1654 frame_buffer);
1655
Dan Williams5076a1a2011-06-27 14:57:03 -07001656 ireq->stp.rsp.status = stp_req->status;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001657
1658 /* The next state is dependent on whether the
1659 * request was PIO Data-in or Data out
1660 */
1661 if (task->data_dir == DMA_FROM_DEVICE) {
Dan Williams5076a1a2011-06-27 14:57:03 -07001662 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_DATA_IN);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001663 } else if (task->data_dir == DMA_TO_DEVICE) {
1664 /* Transmit data */
Dan Williams89a73012011-06-30 19:14:33 -07001665 status = sci_stp_request_pio_data_out_transmit_data(ireq);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001666 if (status != SCI_SUCCESS)
1667 break;
Dan Williams5076a1a2011-06-27 14:57:03 -07001668 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_DATA_OUT);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001669 }
1670 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001671
Dan Williamsd1c637c32011-05-11 08:27:47 -07001672 case FIS_SETDEVBITS:
Dan Williams5076a1a2011-06-27 14:57:03 -07001673 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001674 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001675
Dan Williamsd1c637c32011-05-11 08:27:47 -07001676 case FIS_REGD2H:
1677 if (frame_header->status & ATA_BUSY) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001678 /*
1679 * Now why is the drive sending a D2H Register
1680 * FIS when it is still busy? Do nothing since
1681 * we are still in the right state.
Dan Williamsd1c637c32011-05-11 08:27:47 -07001682 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001683 dev_dbg(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001684 "%s: SCIC PIO Request 0x%p received "
1685 "D2H Register FIS with BSY status "
Edmund Nadolskie3013702011-06-02 00:10:43 +00001686 "0x%x\n",
1687 __func__,
1688 stp_req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001689 frame_header->status);
1690 break;
1691 }
1692
Dan Williams89a73012011-06-30 19:14:33 -07001693 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001694 frame_index,
1695 (void **)&frame_buffer);
1696
Dan Williams89a73012011-06-30 19:14:33 -07001697 sci_controller_copy_sata_response(&ireq->stp.req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001698 frame_header,
1699 frame_buffer);
1700
Dan Williams34a99152011-07-01 02:25:15 -07001701 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1702 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williams5076a1a2011-06-27 14:57:03 -07001703 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001704 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001705
Dan Williamsd1c637c32011-05-11 08:27:47 -07001706 default:
1707 /* FIXME: what do we do here? */
1708 break;
1709 }
1710
1711 /* Frame is decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001712 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001713
1714 return status;
1715 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001716
1717 case SCI_REQ_STP_PIO_DATA_IN: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001718 struct dev_to_host_fis *frame_header;
1719 struct sata_fis_data *frame_buffer;
1720
Dan Williams89a73012011-06-30 19:14:33 -07001721 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001722 frame_index,
1723 (void **)&frame_header);
1724
1725 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001726 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001727 "%s: SCIC IO Request 0x%p could not get frame "
1728 "header for frame index %d, status %x\n",
1729 __func__,
1730 stp_req,
1731 frame_index,
1732 status);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001733 return status;
1734 }
1735
1736 if (frame_header->fis_type != FIS_DATA) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001737 dev_err(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001738 "%s: SCIC PIO Request 0x%p received frame %d "
1739 "with fis type 0x%02x when expecting a data "
Edmund Nadolskie3013702011-06-02 00:10:43 +00001740 "fis.\n",
1741 __func__,
1742 stp_req,
1743 frame_index,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001744 frame_header->fis_type);
1745
Dan Williams34a99152011-07-01 02:25:15 -07001746 ireq->scu_status = SCU_TASK_DONE_GOOD;
1747 ireq->sci_status = SCI_FAILURE_IO_REQUIRES_SCSI_ABORT;
Dan Williams5076a1a2011-06-27 14:57:03 -07001748 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001749
1750 /* Frame is decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001751 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001752 return status;
1753 }
1754
Dan Williamsba7cb222011-06-27 11:56:41 -07001755 if (stp_req->sgl.index < 0) {
Dan Williams5076a1a2011-06-27 14:57:03 -07001756 ireq->saved_rx_frame_index = frame_index;
Dan Williamsba7cb222011-06-27 11:56:41 -07001757 stp_req->pio_len = 0;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001758 } else {
Dan Williams89a73012011-06-30 19:14:33 -07001759 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001760 frame_index,
1761 (void **)&frame_buffer);
1762
Dan Williams89a73012011-06-30 19:14:33 -07001763 status = sci_stp_request_pio_data_in_copy_data(stp_req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001764 (u8 *)frame_buffer);
1765
1766 /* Frame is decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001767 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001768 }
1769
1770 /* Check for the end of the transfer, are there more
1771 * bytes remaining for this data transfer
1772 */
Dan Williamsba7cb222011-06-27 11:56:41 -07001773 if (status != SCI_SUCCESS || stp_req->pio_len != 0)
Dan Williamsd1c637c32011-05-11 08:27:47 -07001774 return status;
1775
Dan Williamsba7cb222011-06-27 11:56:41 -07001776 if ((stp_req->status & ATA_BUSY) == 0) {
Dan Williams34a99152011-07-01 02:25:15 -07001777 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1778 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williams5076a1a2011-06-27 14:57:03 -07001779 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001780 } else {
Dan Williams5076a1a2011-06-27 14:57:03 -07001781 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001782 }
1783 return status;
1784 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001785
1786 case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001787 struct dev_to_host_fis *frame_header;
1788 u32 *frame_buffer;
1789
Dan Williams89a73012011-06-30 19:14:33 -07001790 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001791 frame_index,
1792 (void **)&frame_header);
1793 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001794 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001795 "%s: SCIC IO Request 0x%p could not get frame "
1796 "header for frame index %d, status %x\n",
1797 __func__,
1798 stp_req,
1799 frame_index,
1800 status);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001801 return status;
1802 }
1803
1804 switch (frame_header->fis_type) {
1805 case FIS_REGD2H:
Dan Williams89a73012011-06-30 19:14:33 -07001806 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001807 frame_index,
1808 (void **)&frame_buffer);
1809
Dan Williams89a73012011-06-30 19:14:33 -07001810 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001811 frame_header,
1812 frame_buffer);
1813
1814 /* The command has completed with error */
Dan Williams34a99152011-07-01 02:25:15 -07001815 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1816 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001817 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001818
Dan Williamsd1c637c32011-05-11 08:27:47 -07001819 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001820 dev_warn(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001821 "%s: IO Request:0x%p Frame Id:%d protocol "
Edmund Nadolskie3013702011-06-02 00:10:43 +00001822 "violation occurred\n",
1823 __func__,
1824 stp_req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001825 frame_index);
1826
Dan Williams34a99152011-07-01 02:25:15 -07001827 ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
1828 ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001829 break;
1830 }
1831
Dan Williams5076a1a2011-06-27 14:57:03 -07001832 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001833
1834 /* Frame has been decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001835 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001836
1837 return status;
1838 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001839 case SCI_REQ_ABORTING:
1840 /*
1841 * TODO: Is it even possible to get an unsolicited frame in the
Dan Williamsd1c637c32011-05-11 08:27:47 -07001842 * aborting state?
1843 */
Dan Williams89a73012011-06-30 19:14:33 -07001844 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001845 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001846
Dan Williamsd1c637c32011-05-11 08:27:47 -07001847 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001848 dev_warn(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001849 "%s: SCIC IO Request given unexpected frame %x while "
1850 "in state %d\n",
1851 __func__,
1852 frame_index,
1853 state);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001854
Dan Williams89a73012011-06-30 19:14:33 -07001855 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001856 return SCI_FAILURE_INVALID_STATE;
1857 }
1858}
1859
Dan Williams5076a1a2011-06-27 14:57:03 -07001860static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq,
Dan Williamsa7e255a2011-05-11 08:27:47 -07001861 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001862{
1863 enum sci_status status = SCI_SUCCESS;
1864
1865 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1866 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001867 ireq->scu_status = SCU_TASK_DONE_GOOD;
1868 ireq->sci_status = SCI_SUCCESS;
1869 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001870 break;
1871 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
1872 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001873 /* We must check ther response buffer to see if the D2H
1874 * Register FIS was received before we got the TC
1875 * completion.
1876 */
Dan Williams5076a1a2011-06-27 14:57:03 -07001877 if (ireq->stp.rsp.fis_type == FIS_REGD2H) {
Dan Williams89a73012011-06-30 19:14:33 -07001878 sci_remote_device_suspend(ireq->target_device,
Dan Williams5dec6f42011-05-10 02:28:49 -07001879 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)));
1880
Dan Williams34a99152011-07-01 02:25:15 -07001881 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1882 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
1883 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001884 } else {
Dan Williamsa7e255a2011-05-11 08:27:47 -07001885 /* If we have an error completion status for the
1886 * TC then we can expect a D2H register FIS from
1887 * the device so we must change state to wait
1888 * for it
1889 */
Dan Williams5076a1a2011-06-27 14:57:03 -07001890 sci_change_state(&ireq->sm, SCI_REQ_STP_UDMA_WAIT_D2H);
Dan Williams5dec6f42011-05-10 02:28:49 -07001891 }
1892 break;
1893
Dan Williamsa7e255a2011-05-11 08:27:47 -07001894 /* TODO Check to see if any of these completion status need to
1895 * wait for the device to host register fis.
1896 */
1897 /* TODO We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR
1898 * - this comes only for B0
1899 */
Dan Williams5dec6f42011-05-10 02:28:49 -07001900 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
1901 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
1902 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
1903 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
1904 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
Dan Williams89a73012011-06-30 19:14:33 -07001905 sci_remote_device_suspend(ireq->target_device,
Dan Williams5dec6f42011-05-10 02:28:49 -07001906 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)));
1907 /* Fall through to the default case */
1908 default:
1909 /* All other completion status cause the IO to be complete. */
Dan Williams34a99152011-07-01 02:25:15 -07001910 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1911 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
1912 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001913 break;
1914 }
1915
1916 return status;
1917}
1918
Edmund Nadolskie3013702011-06-02 00:10:43 +00001919static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001920stp_request_soft_reset_await_h2d_asserted_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001921 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001922{
1923 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1924 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001925 ireq->scu_status = SCU_TASK_DONE_GOOD;
1926 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001927 sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG);
Dan Williams5dec6f42011-05-10 02:28:49 -07001928 break;
1929
1930 default:
1931 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001932 * All other completion status cause the IO to be complete.
1933 * If a NAK was received, then it is up to the user to retry
1934 * the request.
1935 */
Dan Williams34a99152011-07-01 02:25:15 -07001936 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1937 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001938 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001939 break;
1940 }
1941
1942 return SCI_SUCCESS;
1943}
1944
Edmund Nadolskie3013702011-06-02 00:10:43 +00001945static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001946stp_request_soft_reset_await_h2d_diagnostic_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001947 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001948{
1949 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1950 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001951 ireq->scu_status = SCU_TASK_DONE_GOOD;
1952 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001953 sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_D2H);
Dan Williams5dec6f42011-05-10 02:28:49 -07001954 break;
1955
1956 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001957 /* All other completion status cause the IO to be complete. If
1958 * a NAK was received, then it is up to the user to retry the
1959 * request.
1960 */
Dan Williams34a99152011-07-01 02:25:15 -07001961 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1962 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001963 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001964 break;
1965 }
1966
1967 return SCI_SUCCESS;
1968}
1969
Dan Williamsa7e255a2011-05-11 08:27:47 -07001970enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07001971sci_io_request_tc_completion(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001972 u32 completion_code)
Dan Williamsa7e255a2011-05-11 08:27:47 -07001973{
1974 enum sci_base_request_states state;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001975 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsa7e255a2011-05-11 08:27:47 -07001976
Dan Williams5076a1a2011-06-27 14:57:03 -07001977 state = ireq->sm.current_state_id;
Dan Williamsa7e255a2011-05-11 08:27:47 -07001978
1979 switch (state) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001980 case SCI_REQ_STARTED:
Dan Williams5076a1a2011-06-27 14:57:03 -07001981 return request_started_state_tc_event(ireq, completion_code);
Edmund Nadolskie3013702011-06-02 00:10:43 +00001982
1983 case SCI_REQ_TASK_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -07001984 return ssp_task_request_await_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001985 completion_code);
1986
1987 case SCI_REQ_SMP_WAIT_RESP:
Dan Williams5076a1a2011-06-27 14:57:03 -07001988 return smp_request_await_response_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001989 completion_code);
1990
1991 case SCI_REQ_SMP_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -07001992 return smp_request_await_tc_event(ireq, completion_code);
Edmund Nadolskie3013702011-06-02 00:10:43 +00001993
1994 case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -07001995 return stp_request_udma_await_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001996 completion_code);
1997
1998 case SCI_REQ_STP_NON_DATA_WAIT_H2D:
Dan Williams5076a1a2011-06-27 14:57:03 -07001999 return stp_request_non_data_await_h2d_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002000 completion_code);
2001
2002 case SCI_REQ_STP_PIO_WAIT_H2D:
Dan Williams5076a1a2011-06-27 14:57:03 -07002003 return stp_request_pio_await_h2d_completion_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002004 completion_code);
2005
2006 case SCI_REQ_STP_PIO_DATA_OUT:
Dan Williams5076a1a2011-06-27 14:57:03 -07002007 return pio_data_out_tx_done_tc_event(ireq, completion_code);
Edmund Nadolskie3013702011-06-02 00:10:43 +00002008
2009 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
Dan Williams5076a1a2011-06-27 14:57:03 -07002010 return stp_request_soft_reset_await_h2d_asserted_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002011 completion_code);
2012
2013 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
Dan Williams5076a1a2011-06-27 14:57:03 -07002014 return stp_request_soft_reset_await_h2d_diagnostic_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002015 completion_code);
2016
2017 case SCI_REQ_ABORTING:
Dan Williams5076a1a2011-06-27 14:57:03 -07002018 return request_aborting_state_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002019 completion_code);
2020
2021 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002022 dev_warn(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002023 "%s: SCIC IO Request given task completion "
2024 "notification %x while in wrong state %d\n",
2025 __func__,
2026 completion_code,
2027 state);
2028 return SCI_FAILURE_INVALID_STATE;
Dan Williamsa7e255a2011-05-11 08:27:47 -07002029 }
2030}
2031
Dan Williams6f231dd2011-07-02 22:56:22 -07002032/**
2033 * isci_request_process_response_iu() - This function sets the status and
2034 * response iu, in the task struct, from the request object for the upper
2035 * layer driver.
2036 * @sas_task: This parameter is the task struct from the upper layer driver.
2037 * @resp_iu: This parameter points to the response iu of the completed request.
2038 * @dev: This parameter specifies the linux device struct.
2039 *
2040 * none.
2041 */
2042static void isci_request_process_response_iu(
2043 struct sas_task *task,
2044 struct ssp_response_iu *resp_iu,
2045 struct device *dev)
2046{
2047 dev_dbg(dev,
2048 "%s: resp_iu = %p "
2049 "resp_iu->status = 0x%x,\nresp_iu->datapres = %d "
2050 "resp_iu->response_data_len = %x, "
2051 "resp_iu->sense_data_len = %x\nrepsonse data: ",
2052 __func__,
2053 resp_iu,
2054 resp_iu->status,
2055 resp_iu->datapres,
2056 resp_iu->response_data_len,
2057 resp_iu->sense_data_len);
2058
2059 task->task_status.stat = resp_iu->status;
2060
2061 /* libsas updates the task status fields based on the response iu. */
2062 sas_ssp_task_response(dev, task, resp_iu);
2063}
2064
2065/**
2066 * isci_request_set_open_reject_status() - This function prepares the I/O
2067 * completion for OPEN_REJECT conditions.
2068 * @request: This parameter is the completed isci_request object.
2069 * @response_ptr: This parameter specifies the service response for the I/O.
2070 * @status_ptr: This parameter specifies the exec status for the I/O.
2071 * @complete_to_host_ptr: This parameter specifies the action to be taken by
2072 * the LLDD with respect to completing this request or forcing an abort
2073 * condition on the I/O.
2074 * @open_rej_reason: This parameter specifies the encoded reason for the
2075 * abandon-class reject.
2076 *
2077 * none.
2078 */
2079static void isci_request_set_open_reject_status(
2080 struct isci_request *request,
2081 struct sas_task *task,
2082 enum service_response *response_ptr,
2083 enum exec_status *status_ptr,
2084 enum isci_completion_selection *complete_to_host_ptr,
2085 enum sas_open_rej_reason open_rej_reason)
2086{
2087 /* Task in the target is done. */
Dan Williams38d88792011-06-23 14:33:48 -07002088 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002089 *response_ptr = SAS_TASK_UNDELIVERED;
2090 *status_ptr = SAS_OPEN_REJECT;
2091 *complete_to_host_ptr = isci_perform_normal_io_completion;
2092 task->task_status.open_rej_reason = open_rej_reason;
2093}
2094
2095/**
2096 * isci_request_handle_controller_specific_errors() - This function decodes
2097 * controller-specific I/O completion error conditions.
2098 * @request: This parameter is the completed isci_request object.
2099 * @response_ptr: This parameter specifies the service response for the I/O.
2100 * @status_ptr: This parameter specifies the exec status for the I/O.
2101 * @complete_to_host_ptr: This parameter specifies the action to be taken by
2102 * the LLDD with respect to completing this request or forcing an abort
2103 * condition on the I/O.
2104 *
2105 * none.
2106 */
2107static void isci_request_handle_controller_specific_errors(
Dan Williams209fae12011-06-13 17:39:44 -07002108 struct isci_remote_device *idev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002109 struct isci_request *request,
2110 struct sas_task *task,
2111 enum service_response *response_ptr,
2112 enum exec_status *status_ptr,
2113 enum isci_completion_selection *complete_to_host_ptr)
2114{
2115 unsigned int cstatus;
2116
Dan Williams5076a1a2011-06-27 14:57:03 -07002117 cstatus = request->scu_status;
Dan Williams6f231dd2011-07-02 22:56:22 -07002118
2119 dev_dbg(&request->isci_host->pdev->dev,
2120 "%s: %p SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR "
2121 "- controller status = 0x%x\n",
2122 __func__, request, cstatus);
2123
2124 /* Decode the controller-specific errors; most
2125 * important is to recognize those conditions in which
2126 * the target may still have a task outstanding that
2127 * must be aborted.
2128 *
2129 * Note that there are SCU completion codes being
2130 * named in the decode below for which SCIC has already
2131 * done work to handle them in a way other than as
2132 * a controller-specific completion code; these are left
2133 * in the decode below for completeness sake.
2134 */
2135 switch (cstatus) {
2136 case SCU_TASK_DONE_DMASETUP_DIRERR:
2137 /* Also SCU_TASK_DONE_SMP_FRM_TYPE_ERR: */
2138 case SCU_TASK_DONE_XFERCNT_ERR:
2139 /* Also SCU_TASK_DONE_SMP_UFI_ERR: */
2140 if (task->task_proto == SAS_PROTOCOL_SMP) {
2141 /* SCU_TASK_DONE_SMP_UFI_ERR == Task Done. */
2142 *response_ptr = SAS_TASK_COMPLETE;
2143
2144 /* See if the device has been/is being stopped. Note
2145 * that we ignore the quiesce state, since we are
2146 * concerned about the actual device state.
2147 */
Dan Williams209fae12011-06-13 17:39:44 -07002148 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002149 *status_ptr = SAS_DEVICE_UNKNOWN;
2150 else
2151 *status_ptr = SAS_ABORTED_TASK;
2152
Dan Williams38d88792011-06-23 14:33:48 -07002153 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002154
2155 *complete_to_host_ptr =
2156 isci_perform_normal_io_completion;
2157 } else {
2158 /* Task in the target is not done. */
2159 *response_ptr = SAS_TASK_UNDELIVERED;
2160
Dan Williams209fae12011-06-13 17:39:44 -07002161 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002162 *status_ptr = SAS_DEVICE_UNKNOWN;
2163 else
2164 *status_ptr = SAM_STAT_TASK_ABORTED;
2165
Dan Williams38d88792011-06-23 14:33:48 -07002166 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002167
2168 *complete_to_host_ptr =
2169 isci_perform_error_io_completion;
2170 }
2171
2172 break;
2173
2174 case SCU_TASK_DONE_CRC_ERR:
2175 case SCU_TASK_DONE_NAK_CMD_ERR:
2176 case SCU_TASK_DONE_EXCESS_DATA:
2177 case SCU_TASK_DONE_UNEXP_FIS:
2178 /* Also SCU_TASK_DONE_UNEXP_RESP: */
2179 case SCU_TASK_DONE_VIIT_ENTRY_NV: /* TODO - conditions? */
2180 case SCU_TASK_DONE_IIT_ENTRY_NV: /* TODO - conditions? */
2181 case SCU_TASK_DONE_RNCNV_OUTBOUND: /* TODO - conditions? */
2182 /* These are conditions in which the target
2183 * has completed the task, so that no cleanup
2184 * is necessary.
2185 */
2186 *response_ptr = SAS_TASK_COMPLETE;
2187
2188 /* See if the device has been/is being stopped. Note
2189 * that we ignore the quiesce state, since we are
2190 * concerned about the actual device state.
2191 */
Dan Williams209fae12011-06-13 17:39:44 -07002192 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002193 *status_ptr = SAS_DEVICE_UNKNOWN;
2194 else
2195 *status_ptr = SAS_ABORTED_TASK;
2196
Dan Williams38d88792011-06-23 14:33:48 -07002197 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002198
2199 *complete_to_host_ptr = isci_perform_normal_io_completion;
2200 break;
2201
2202
2203 /* Note that the only open reject completion codes seen here will be
2204 * abandon-class codes; all others are automatically retried in the SCU.
2205 */
2206 case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION:
2207
2208 isci_request_set_open_reject_status(
2209 request, task, response_ptr, status_ptr,
2210 complete_to_host_ptr, SAS_OREJ_WRONG_DEST);
2211 break;
2212
2213 case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION:
2214
2215 /* Note - the return of AB0 will change when
2216 * libsas implements detection of zone violations.
2217 */
2218 isci_request_set_open_reject_status(
2219 request, task, response_ptr, status_ptr,
2220 complete_to_host_ptr, SAS_OREJ_RESV_AB0);
2221 break;
2222
2223 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1:
2224
2225 isci_request_set_open_reject_status(
2226 request, task, response_ptr, status_ptr,
2227 complete_to_host_ptr, SAS_OREJ_RESV_AB1);
2228 break;
2229
2230 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2:
2231
2232 isci_request_set_open_reject_status(
2233 request, task, response_ptr, status_ptr,
2234 complete_to_host_ptr, SAS_OREJ_RESV_AB2);
2235 break;
2236
2237 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3:
2238
2239 isci_request_set_open_reject_status(
2240 request, task, response_ptr, status_ptr,
2241 complete_to_host_ptr, SAS_OREJ_RESV_AB3);
2242 break;
2243
2244 case SCU_TASK_OPEN_REJECT_BAD_DESTINATION:
2245
2246 isci_request_set_open_reject_status(
2247 request, task, response_ptr, status_ptr,
2248 complete_to_host_ptr, SAS_OREJ_BAD_DEST);
2249 break;
2250
2251 case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY:
2252
2253 isci_request_set_open_reject_status(
2254 request, task, response_ptr, status_ptr,
2255 complete_to_host_ptr, SAS_OREJ_STP_NORES);
2256 break;
2257
2258 case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED:
2259
2260 isci_request_set_open_reject_status(
2261 request, task, response_ptr, status_ptr,
2262 complete_to_host_ptr, SAS_OREJ_EPROTO);
2263 break;
2264
2265 case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED:
2266
2267 isci_request_set_open_reject_status(
2268 request, task, response_ptr, status_ptr,
2269 complete_to_host_ptr, SAS_OREJ_CONN_RATE);
2270 break;
2271
2272 case SCU_TASK_DONE_LL_R_ERR:
2273 /* Also SCU_TASK_DONE_ACK_NAK_TO: */
2274 case SCU_TASK_DONE_LL_PERR:
2275 case SCU_TASK_DONE_LL_SY_TERM:
2276 /* Also SCU_TASK_DONE_NAK_ERR:*/
2277 case SCU_TASK_DONE_LL_LF_TERM:
2278 /* Also SCU_TASK_DONE_DATA_LEN_ERR: */
2279 case SCU_TASK_DONE_LL_ABORT_ERR:
2280 case SCU_TASK_DONE_SEQ_INV_TYPE:
2281 /* Also SCU_TASK_DONE_UNEXP_XR: */
2282 case SCU_TASK_DONE_XR_IU_LEN_ERR:
2283 case SCU_TASK_DONE_INV_FIS_LEN:
2284 /* Also SCU_TASK_DONE_XR_WD_LEN: */
2285 case SCU_TASK_DONE_SDMA_ERR:
2286 case SCU_TASK_DONE_OFFSET_ERR:
2287 case SCU_TASK_DONE_MAX_PLD_ERR:
2288 case SCU_TASK_DONE_LF_ERR:
2289 case SCU_TASK_DONE_SMP_RESP_TO_ERR: /* Escalate to dev reset? */
2290 case SCU_TASK_DONE_SMP_LL_RX_ERR:
2291 case SCU_TASK_DONE_UNEXP_DATA:
2292 case SCU_TASK_DONE_UNEXP_SDBFIS:
2293 case SCU_TASK_DONE_REG_ERR:
2294 case SCU_TASK_DONE_SDB_ERR:
2295 case SCU_TASK_DONE_TASK_ABORT:
2296 default:
2297 /* Task in the target is not done. */
2298 *response_ptr = SAS_TASK_UNDELIVERED;
2299 *status_ptr = SAM_STAT_TASK_ABORTED;
Dan Williams6f231dd2011-07-02 22:56:22 -07002300
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002301 if (task->task_proto == SAS_PROTOCOL_SMP) {
Dan Williams38d88792011-06-23 14:33:48 -07002302 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002303
2304 *complete_to_host_ptr = isci_perform_normal_io_completion;
2305 } else {
Dan Williams38d88792011-06-23 14:33:48 -07002306 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002307
2308 *complete_to_host_ptr = isci_perform_error_io_completion;
2309 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002310 break;
2311 }
2312}
2313
2314/**
2315 * isci_task_save_for_upper_layer_completion() - This function saves the
2316 * request for later completion to the upper layer driver.
2317 * @host: This parameter is a pointer to the host on which the the request
2318 * should be queued (either as an error or success).
2319 * @request: This parameter is the completed request.
2320 * @response: This parameter is the response code for the completed task.
2321 * @status: This parameter is the status code for the completed task.
2322 *
2323 * none.
2324 */
2325static void isci_task_save_for_upper_layer_completion(
2326 struct isci_host *host,
2327 struct isci_request *request,
2328 enum service_response response,
2329 enum exec_status status,
2330 enum isci_completion_selection task_notification_selection)
2331{
2332 struct sas_task *task = isci_request_access_task(request);
2333
Jeff Skirvinec6c9632011-03-04 14:06:44 -08002334 task_notification_selection
2335 = isci_task_set_completion_status(task, response, status,
2336 task_notification_selection);
Dan Williams6f231dd2011-07-02 22:56:22 -07002337
2338 /* Tasks aborted specifically by a call to the lldd_abort_task
2339 * function should not be completed to the host in the regular path.
2340 */
2341 switch (task_notification_selection) {
2342
2343 case isci_perform_normal_io_completion:
2344
2345 /* Normal notification (task_done) */
2346 dev_dbg(&host->pdev->dev,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002347 "%s: Normal - task = %p, response=%d (%d), status=%d (%d)\n",
Dan Williams6f231dd2011-07-02 22:56:22 -07002348 __func__,
2349 task,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002350 task->task_status.resp, response,
2351 task->task_status.stat, status);
Dan Williams6f231dd2011-07-02 22:56:22 -07002352 /* Add to the completed list. */
2353 list_add(&request->completed_node,
2354 &host->requests_to_complete);
Jeff Skirvinec6c9632011-03-04 14:06:44 -08002355
2356 /* Take the request off the device's pending request list. */
2357 list_del_init(&request->dev_node);
Dan Williams6f231dd2011-07-02 22:56:22 -07002358 break;
2359
2360 case isci_perform_aborted_io_completion:
Jeff Skirvina5fde222011-03-04 14:06:42 -08002361 /* No notification to libsas because this request is
2362 * already in the abort path.
Dan Williams6f231dd2011-07-02 22:56:22 -07002363 */
2364 dev_warn(&host->pdev->dev,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002365 "%s: Aborted - task = %p, response=%d (%d), status=%d (%d)\n",
Dan Williams6f231dd2011-07-02 22:56:22 -07002366 __func__,
2367 task,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002368 task->task_status.resp, response,
2369 task->task_status.stat, status);
Jeff Skirvina5fde222011-03-04 14:06:42 -08002370
2371 /* Wake up whatever process was waiting for this
2372 * request to complete.
2373 */
2374 WARN_ON(request->io_request_completion == NULL);
2375
2376 if (request->io_request_completion != NULL) {
2377
2378 /* Signal whoever is waiting that this
2379 * request is complete.
2380 */
2381 complete(request->io_request_completion);
2382 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002383 break;
2384
2385 case isci_perform_error_io_completion:
2386 /* Use sas_task_abort */
2387 dev_warn(&host->pdev->dev,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002388 "%s: Error - task = %p, response=%d (%d), status=%d (%d)\n",
Dan Williams6f231dd2011-07-02 22:56:22 -07002389 __func__,
2390 task,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002391 task->task_status.resp, response,
2392 task->task_status.stat, status);
Dan Williams6f231dd2011-07-02 22:56:22 -07002393 /* Add to the aborted list. */
2394 list_add(&request->completed_node,
Jeff Skirvin11b00c12011-03-04 14:06:40 -08002395 &host->requests_to_errorback);
Dan Williams6f231dd2011-07-02 22:56:22 -07002396 break;
2397
2398 default:
2399 dev_warn(&host->pdev->dev,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002400 "%s: Unknown - task = %p, response=%d (%d), status=%d (%d)\n",
Dan Williams6f231dd2011-07-02 22:56:22 -07002401 __func__,
2402 task,
Jeff Skirvinaa145102011-03-07 16:40:47 -07002403 task->task_status.resp, response,
2404 task->task_status.stat, status);
Dan Williams6f231dd2011-07-02 22:56:22 -07002405
Jeff Skirvina5fde222011-03-04 14:06:42 -08002406 /* Add to the error to libsas list. */
Dan Williams6f231dd2011-07-02 22:56:22 -07002407 list_add(&request->completed_node,
Jeff Skirvin11b00c12011-03-04 14:06:40 -08002408 &host->requests_to_errorback);
Dan Williams6f231dd2011-07-02 22:56:22 -07002409 break;
2410 }
2411}
2412
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002413static void isci_request_io_request_complete(struct isci_host *ihost,
Dan Williamsf1f52e72011-05-10 02:28:45 -07002414 struct isci_request *request,
2415 enum sci_io_status completion_status)
Dan Williams6f231dd2011-07-02 22:56:22 -07002416{
2417 struct sas_task *task = isci_request_access_task(request);
2418 struct ssp_response_iu *resp_iu;
2419 void *resp_buf;
2420 unsigned long task_flags;
Dan Williams209fae12011-06-13 17:39:44 -07002421 struct isci_remote_device *idev = isci_lookup_device(task->dev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002422 enum service_response response = SAS_TASK_UNDELIVERED;
2423 enum exec_status status = SAS_ABORTED_TASK;
2424 enum isci_request_status request_status;
2425 enum isci_completion_selection complete_to_host
2426 = isci_perform_normal_io_completion;
2427
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002428 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002429 "%s: request = %p, task = %p,\n"
2430 "task->data_dir = %d completion_status = 0x%x\n",
2431 __func__,
2432 request,
2433 task,
2434 task->data_dir,
2435 completion_status);
2436
Jeff Skirvina5fde222011-03-04 14:06:42 -08002437 spin_lock(&request->state_lock);
Dan Williams34a99152011-07-01 02:25:15 -07002438 request_status = request->status;
Dan Williams6f231dd2011-07-02 22:56:22 -07002439
2440 /* Decode the request status. Note that if the request has been
2441 * aborted by a task management function, we don't care
2442 * what the status is.
2443 */
2444 switch (request_status) {
2445
2446 case aborted:
2447 /* "aborted" indicates that the request was aborted by a task
2448 * management function, since once a task management request is
2449 * perfomed by the device, the request only completes because
2450 * of the subsequent driver terminate.
2451 *
2452 * Aborted also means an external thread is explicitly managing
2453 * this request, so that we do not complete it up the stack.
2454 *
2455 * The target is still there (since the TMF was successful).
2456 */
Dan Williams38d88792011-06-23 14:33:48 -07002457 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002458 response = SAS_TASK_COMPLETE;
2459
2460 /* See if the device has been/is being stopped. Note
2461 * that we ignore the quiesce state, since we are
2462 * concerned about the actual device state.
2463 */
Dan Williams209fae12011-06-13 17:39:44 -07002464 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002465 status = SAS_DEVICE_UNKNOWN;
2466 else
2467 status = SAS_ABORTED_TASK;
2468
2469 complete_to_host = isci_perform_aborted_io_completion;
2470 /* This was an aborted request. */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002471
2472 spin_unlock(&request->state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002473 break;
2474
2475 case aborting:
2476 /* aborting means that the task management function tried and
2477 * failed to abort the request. We need to note the request
2478 * as SAS_TASK_UNDELIVERED, so that the scsi mid layer marks the
2479 * target as down.
2480 *
2481 * Aborting also means an external thread is explicitly managing
2482 * this request, so that we do not complete it up the stack.
2483 */
Dan Williams38d88792011-06-23 14:33:48 -07002484 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002485 response = SAS_TASK_UNDELIVERED;
2486
Dan Williams209fae12011-06-13 17:39:44 -07002487 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002488 /* The device has been /is being stopped. Note that
2489 * we ignore the quiesce state, since we are
2490 * concerned about the actual device state.
2491 */
2492 status = SAS_DEVICE_UNKNOWN;
2493 else
2494 status = SAS_PHY_DOWN;
2495
2496 complete_to_host = isci_perform_aborted_io_completion;
2497
2498 /* This was an aborted request. */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002499
2500 spin_unlock(&request->state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002501 break;
2502
2503 case terminating:
2504
2505 /* This was an terminated request. This happens when
2506 * the I/O is being terminated because of an action on
2507 * the device (reset, tear down, etc.), and the I/O needs
2508 * to be completed up the stack.
2509 */
Dan Williams38d88792011-06-23 14:33:48 -07002510 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002511 response = SAS_TASK_UNDELIVERED;
2512
2513 /* See if the device has been/is being stopped. Note
2514 * that we ignore the quiesce state, since we are
2515 * concerned about the actual device state.
2516 */
Dan Williams209fae12011-06-13 17:39:44 -07002517 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002518 status = SAS_DEVICE_UNKNOWN;
2519 else
2520 status = SAS_ABORTED_TASK;
2521
Jeff Skirvina5fde222011-03-04 14:06:42 -08002522 complete_to_host = isci_perform_aborted_io_completion;
Dan Williams6f231dd2011-07-02 22:56:22 -07002523
2524 /* This was a terminated request. */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002525
2526 spin_unlock(&request->state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002527 break;
2528
Jeff Skirvin77c852f2011-06-20 14:09:16 -07002529 case dead:
2530 /* This was a terminated request that timed-out during the
2531 * termination process. There is no task to complete to
2532 * libsas.
2533 */
2534 complete_to_host = isci_perform_normal_io_completion;
2535 spin_unlock(&request->state_lock);
2536 break;
2537
Dan Williams6f231dd2011-07-02 22:56:22 -07002538 default:
2539
Jeff Skirvina5fde222011-03-04 14:06:42 -08002540 /* The request is done from an SCU HW perspective. */
2541 request->status = completed;
2542
2543 spin_unlock(&request->state_lock);
2544
Dan Williams6f231dd2011-07-02 22:56:22 -07002545 /* This is an active request being completed from the core. */
2546 switch (completion_status) {
2547
2548 case SCI_IO_FAILURE_RESPONSE_VALID:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002549 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002550 "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n",
2551 __func__,
2552 request,
2553 task);
2554
2555 if (sas_protocol_ata(task->task_proto)) {
Dan Williams5076a1a2011-06-27 14:57:03 -07002556 resp_buf = &request->stp.rsp;
Dan Williams6f231dd2011-07-02 22:56:22 -07002557 isci_request_process_stp_response(task,
Dan Williamsb7645812011-05-08 02:35:32 -07002558 resp_buf);
Dan Williams6f231dd2011-07-02 22:56:22 -07002559 } else if (SAS_PROTOCOL_SSP == task->task_proto) {
2560
2561 /* crack the iu response buffer. */
Dan Williams5076a1a2011-06-27 14:57:03 -07002562 resp_iu = &request->ssp.rsp;
Dan Williams6f231dd2011-07-02 22:56:22 -07002563 isci_request_process_response_iu(task, resp_iu,
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002564 &ihost->pdev->dev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002565
2566 } else if (SAS_PROTOCOL_SMP == task->task_proto) {
2567
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002568 dev_err(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002569 "%s: SCI_IO_FAILURE_RESPONSE_VALID: "
2570 "SAS_PROTOCOL_SMP protocol\n",
2571 __func__);
2572
2573 } else
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002574 dev_err(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002575 "%s: unknown protocol\n", __func__);
2576
2577 /* use the task status set in the task struct by the
2578 * isci_request_process_response_iu call.
2579 */
Dan Williams38d88792011-06-23 14:33:48 -07002580 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002581 response = task->task_status.resp;
2582 status = task->task_status.stat;
2583 break;
2584
2585 case SCI_IO_SUCCESS:
2586 case SCI_IO_SUCCESS_IO_DONE_EARLY:
2587
2588 response = SAS_TASK_COMPLETE;
2589 status = SAM_STAT_GOOD;
Dan Williams38d88792011-06-23 14:33:48 -07002590 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002591
2592 if (task->task_proto == SAS_PROTOCOL_SMP) {
Dan Williams5076a1a2011-06-27 14:57:03 -07002593 void *rsp = &request->smp.rsp;
Dan Williams6f231dd2011-07-02 22:56:22 -07002594
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002595 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002596 "%s: SMP protocol completion\n",
2597 __func__);
2598
2599 sg_copy_from_buffer(
2600 &task->smp_task.smp_resp, 1,
Dan Williamsb7645812011-05-08 02:35:32 -07002601 rsp, sizeof(struct smp_resp));
Dan Williams6f231dd2011-07-02 22:56:22 -07002602 } else if (completion_status
2603 == SCI_IO_SUCCESS_IO_DONE_EARLY) {
2604
2605 /* This was an SSP / STP / SATA transfer.
2606 * There is a possibility that less data than
2607 * the maximum was transferred.
2608 */
Dan Williams5076a1a2011-06-27 14:57:03 -07002609 u32 transferred_length = sci_req_tx_bytes(request);
Dan Williams6f231dd2011-07-02 22:56:22 -07002610
2611 task->task_status.residual
2612 = task->total_xfer_len - transferred_length;
2613
2614 /* If there were residual bytes, call this an
2615 * underrun.
2616 */
2617 if (task->task_status.residual != 0)
2618 status = SAS_DATA_UNDERRUN;
2619
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002620 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002621 "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n",
2622 __func__,
2623 status);
2624
2625 } else
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002626 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002627 "%s: SCI_IO_SUCCESS\n",
2628 __func__);
2629
2630 break;
2631
2632 case SCI_IO_FAILURE_TERMINATED:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002633 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002634 "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n",
2635 __func__,
2636 request,
2637 task);
2638
2639 /* The request was terminated explicitly. No handling
2640 * is needed in the SCSI error handler path.
2641 */
Dan Williams38d88792011-06-23 14:33:48 -07002642 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002643 response = SAS_TASK_UNDELIVERED;
2644
2645 /* See if the device has been/is being stopped. Note
2646 * that we ignore the quiesce state, since we are
2647 * concerned about the actual device state.
2648 */
Dan Williams209fae12011-06-13 17:39:44 -07002649 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002650 status = SAS_DEVICE_UNKNOWN;
2651 else
2652 status = SAS_ABORTED_TASK;
2653
2654 complete_to_host = isci_perform_normal_io_completion;
2655 break;
2656
2657 case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR:
2658
2659 isci_request_handle_controller_specific_errors(
Dan Williams209fae12011-06-13 17:39:44 -07002660 idev, request, task, &response, &status,
Dan Williams6f231dd2011-07-02 22:56:22 -07002661 &complete_to_host);
2662
2663 break;
2664
2665 case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED:
2666 /* This is a special case, in that the I/O completion
2667 * is telling us that the device needs a reset.
2668 * In order for the device reset condition to be
2669 * noticed, the I/O has to be handled in the error
2670 * handler. Set the reset flag and cause the
2671 * SCSI error thread to be scheduled.
2672 */
2673 spin_lock_irqsave(&task->task_state_lock, task_flags);
2674 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
2675 spin_unlock_irqrestore(&task->task_state_lock, task_flags);
2676
Jeff Skirvinaa145102011-03-07 16:40:47 -07002677 /* Fail the I/O. */
2678 response = SAS_TASK_UNDELIVERED;
2679 status = SAM_STAT_TASK_ABORTED;
2680
Dan Williams6f231dd2011-07-02 22:56:22 -07002681 complete_to_host = isci_perform_error_io_completion;
Dan Williams38d88792011-06-23 14:33:48 -07002682 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002683 break;
2684
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002685 case SCI_FAILURE_RETRY_REQUIRED:
2686
2687 /* Fail the I/O so it can be retried. */
2688 response = SAS_TASK_UNDELIVERED;
Dan Williams209fae12011-06-13 17:39:44 -07002689 if (!idev)
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002690 status = SAS_DEVICE_UNKNOWN;
2691 else
2692 status = SAS_ABORTED_TASK;
2693
2694 complete_to_host = isci_perform_normal_io_completion;
Dan Williams38d88792011-06-23 14:33:48 -07002695 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002696 break;
2697
2698
Dan Williams6f231dd2011-07-02 22:56:22 -07002699 default:
2700 /* Catch any otherwise unhandled error codes here. */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002701 dev_warn(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002702 "%s: invalid completion code: 0x%x - "
2703 "isci_request = %p\n",
2704 __func__, completion_status, request);
2705
2706 response = SAS_TASK_UNDELIVERED;
2707
2708 /* See if the device has been/is being stopped. Note
2709 * that we ignore the quiesce state, since we are
2710 * concerned about the actual device state.
2711 */
Dan Williams209fae12011-06-13 17:39:44 -07002712 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002713 status = SAS_DEVICE_UNKNOWN;
2714 else
2715 status = SAS_ABORTED_TASK;
2716
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002717 if (SAS_PROTOCOL_SMP == task->task_proto) {
Dan Williams38d88792011-06-23 14:33:48 -07002718 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002719 complete_to_host = isci_perform_normal_io_completion;
2720 } else {
Dan Williams38d88792011-06-23 14:33:48 -07002721 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002722 complete_to_host = isci_perform_error_io_completion;
2723 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002724 break;
2725 }
2726 break;
2727 }
2728
Dan Williamsddcc7e32011-06-17 10:40:43 -07002729 switch (task->task_proto) {
2730 case SAS_PROTOCOL_SSP:
2731 if (task->data_dir == DMA_NONE)
2732 break;
2733 if (task->num_scatter == 0)
2734 /* 0 indicates a single dma address */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002735 dma_unmap_single(&ihost->pdev->dev,
Dan Williamsddcc7e32011-06-17 10:40:43 -07002736 request->zero_scatter_daddr,
2737 task->total_xfer_len, task->data_dir);
2738 else /* unmap the sgl dma addresses */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002739 dma_unmap_sg(&ihost->pdev->dev, task->scatter,
Dan Williamsddcc7e32011-06-17 10:40:43 -07002740 request->num_sg_entries, task->data_dir);
2741 break;
Dan Williamse9bf7092011-06-16 16:59:56 -07002742 case SAS_PROTOCOL_SMP: {
2743 struct scatterlist *sg = &task->smp_task.smp_req;
2744 struct smp_req *smp_req;
2745 void *kaddr;
2746
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002747 dma_unmap_sg(&ihost->pdev->dev, sg, 1, DMA_TO_DEVICE);
Dan Williamse9bf7092011-06-16 16:59:56 -07002748
2749 /* need to swab it back in case the command buffer is re-used */
2750 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
2751 smp_req = kaddr + sg->offset;
2752 sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
2753 kunmap_atomic(kaddr, KM_IRQ0);
2754 break;
2755 }
Dan Williamsddcc7e32011-06-17 10:40:43 -07002756 default:
2757 break;
2758 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002759
2760 /* Put the completed request on the correct list */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002761 isci_task_save_for_upper_layer_completion(ihost, request, response,
Dan Williams6f231dd2011-07-02 22:56:22 -07002762 status, complete_to_host
2763 );
2764
2765 /* complete the io request to the core. */
Dan Williams89a73012011-06-30 19:14:33 -07002766 sci_controller_complete_io(ihost, request->target_device, request);
Dan Williams209fae12011-06-13 17:39:44 -07002767 isci_put_device(idev);
2768
Dan Williams67ea8382011-05-08 11:47:15 -07002769 /* set terminated handle so it cannot be completed or
Dan Williams6f231dd2011-07-02 22:56:22 -07002770 * terminated again, and to cause any calls into abort
2771 * task to recognize the already completed case.
2772 */
Dan Williams38d88792011-06-23 14:33:48 -07002773 set_bit(IREQ_TERMINATED, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002774}
Dan Williamsf1f52e72011-05-10 02:28:45 -07002775
Dan Williams89a73012011-06-30 19:14:33 -07002776static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002777{
Dan Williams5076a1a2011-06-27 14:57:03 -07002778 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams78a6f062011-06-30 16:31:37 -07002779 struct domain_device *dev = ireq->target_device->domain_dev;
Dan Williamsc72086e2011-05-10 02:28:48 -07002780 struct sas_task *task;
2781
2782 /* XXX as hch said always creating an internal sas_task for tmf
2783 * requests would simplify the driver
2784 */
2785 task = ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002786
Dan Williams5dec6f42011-05-10 02:28:49 -07002787 /* all unaccelerated request types (non ssp or ncq) handled with
2788 * substates
Dan Williamsf1393032011-05-10 02:28:47 -07002789 */
Dan Williamsc72086e2011-05-10 02:28:48 -07002790 if (!task && dev->dev_type == SAS_END_DEV) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00002791 sci_change_state(sm, SCI_REQ_TASK_WAIT_TC_COMP);
Dan Williams5dec6f42011-05-10 02:28:49 -07002792 } else if (!task &&
2793 (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high ||
2794 isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00002795 sci_change_state(sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED);
Dan Williamsc72086e2011-05-10 02:28:48 -07002796 } else if (task && task->task_proto == SAS_PROTOCOL_SMP) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00002797 sci_change_state(sm, SCI_REQ_SMP_WAIT_RESP);
Dan Williams5dec6f42011-05-10 02:28:49 -07002798 } else if (task && sas_protocol_ata(task->task_proto) &&
2799 !task->ata_task.use_ncq) {
2800 u32 state;
2801
2802 if (task->data_dir == DMA_NONE)
Edmund Nadolskie3013702011-06-02 00:10:43 +00002803 state = SCI_REQ_STP_NON_DATA_WAIT_H2D;
Dan Williams5dec6f42011-05-10 02:28:49 -07002804 else if (task->ata_task.dma_xfer)
Edmund Nadolskie3013702011-06-02 00:10:43 +00002805 state = SCI_REQ_STP_UDMA_WAIT_TC_COMP;
Dan Williams5dec6f42011-05-10 02:28:49 -07002806 else /* PIO */
Edmund Nadolskie3013702011-06-02 00:10:43 +00002807 state = SCI_REQ_STP_PIO_WAIT_H2D;
Dan Williams5dec6f42011-05-10 02:28:49 -07002808
Edmund Nadolskie3013702011-06-02 00:10:43 +00002809 sci_change_state(sm, state);
Dan Williamsc72086e2011-05-10 02:28:48 -07002810 }
Dan Williamsf1f52e72011-05-10 02:28:45 -07002811}
2812
Dan Williams89a73012011-06-30 19:14:33 -07002813static void sci_request_completed_state_enter(struct sci_base_state_machine *sm)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002814{
Dan Williams5076a1a2011-06-27 14:57:03 -07002815 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002816 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002817
Dan Williamsf1f52e72011-05-10 02:28:45 -07002818 /* Tell the SCI_USER that the IO request is complete */
Dan Williams38d88792011-06-23 14:33:48 -07002819 if (!test_bit(IREQ_TMF, &ireq->flags))
Dan Williamsf1f52e72011-05-10 02:28:45 -07002820 isci_request_io_request_complete(ihost, ireq,
Dan Williams5076a1a2011-06-27 14:57:03 -07002821 ireq->sci_status);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002822 else
Dan Williams5076a1a2011-06-27 14:57:03 -07002823 isci_task_request_complete(ihost, ireq, ireq->sci_status);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002824}
2825
Dan Williams89a73012011-06-30 19:14:33 -07002826static void sci_request_aborting_state_enter(struct sci_base_state_machine *sm)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002827{
Dan Williams5076a1a2011-06-27 14:57:03 -07002828 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002829
2830 /* Setting the abort bit in the Task Context is required by the silicon. */
Dan Williams5076a1a2011-06-27 14:57:03 -07002831 ireq->tc->abort = 1;
Dan Williamsc72086e2011-05-10 02:28:48 -07002832}
2833
Dan Williams89a73012011-06-30 19:14:33 -07002834static void sci_stp_request_started_non_data_await_h2d_completion_enter(struct sci_base_state_machine *sm)
Dan Williams5dec6f42011-05-10 02:28:49 -07002835{
Dan Williams5076a1a2011-06-27 14:57:03 -07002836 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams5dec6f42011-05-10 02:28:49 -07002837
Dan Williams34a99152011-07-01 02:25:15 -07002838 ireq->target_device->working_request = ireq;
Dan Williams5dec6f42011-05-10 02:28:49 -07002839}
2840
Dan Williams89a73012011-06-30 19:14:33 -07002841static void sci_stp_request_started_pio_await_h2d_completion_enter(struct sci_base_state_machine *sm)
Dan Williams5dec6f42011-05-10 02:28:49 -07002842{
Dan Williams5076a1a2011-06-27 14:57:03 -07002843 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams5dec6f42011-05-10 02:28:49 -07002844
Dan Williams34a99152011-07-01 02:25:15 -07002845 ireq->target_device->working_request = ireq;
Dan Williams5dec6f42011-05-10 02:28:49 -07002846}
2847
Dan Williams89a73012011-06-30 19:14:33 -07002848static void sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(struct sci_base_state_machine *sm)
Dan Williams5dec6f42011-05-10 02:28:49 -07002849{
Dan Williams5076a1a2011-06-27 14:57:03 -07002850 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams5dec6f42011-05-10 02:28:49 -07002851
Dan Williams34a99152011-07-01 02:25:15 -07002852 ireq->target_device->working_request = ireq;
Dan Williams5dec6f42011-05-10 02:28:49 -07002853}
2854
Dan Williams89a73012011-06-30 19:14:33 -07002855static void sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(struct sci_base_state_machine *sm)
Dan Williams5dec6f42011-05-10 02:28:49 -07002856{
Dan Williams5076a1a2011-06-27 14:57:03 -07002857 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
2858 struct scu_task_context *tc = ireq->tc;
Dan Williams5dec6f42011-05-10 02:28:49 -07002859 struct host_to_dev_fis *h2d_fis;
2860 enum sci_status status;
2861
2862 /* Clear the SRST bit */
Dan Williams5076a1a2011-06-27 14:57:03 -07002863 h2d_fis = &ireq->stp.cmd;
Dan Williams5dec6f42011-05-10 02:28:49 -07002864 h2d_fis->control = 0;
2865
2866 /* Clear the TC control bit */
Dan Williams312e0c22011-06-28 13:47:09 -07002867 tc->control_frame = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07002868
Dan Williams89a73012011-06-30 19:14:33 -07002869 status = sci_controller_continue_io(ireq);
Dan Williams79e2b6b2011-05-11 08:29:56 -07002870 WARN_ONCE(status != SCI_SUCCESS, "isci: continue io failure\n");
Dan Williams5dec6f42011-05-10 02:28:49 -07002871}
2872
Dan Williams89a73012011-06-30 19:14:33 -07002873static const struct sci_base_state sci_request_state_table[] = {
Edmund Nadolskie3013702011-06-02 00:10:43 +00002874 [SCI_REQ_INIT] = { },
2875 [SCI_REQ_CONSTRUCTED] = { },
2876 [SCI_REQ_STARTED] = {
Dan Williams89a73012011-06-30 19:14:33 -07002877 .enter_state = sci_request_started_state_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07002878 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002879 [SCI_REQ_STP_NON_DATA_WAIT_H2D] = {
Dan Williams89a73012011-06-30 19:14:33 -07002880 .enter_state = sci_stp_request_started_non_data_await_h2d_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07002881 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002882 [SCI_REQ_STP_NON_DATA_WAIT_D2H] = { },
2883 [SCI_REQ_STP_PIO_WAIT_H2D] = {
Dan Williams89a73012011-06-30 19:14:33 -07002884 .enter_state = sci_stp_request_started_pio_await_h2d_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07002885 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002886 [SCI_REQ_STP_PIO_WAIT_FRAME] = { },
2887 [SCI_REQ_STP_PIO_DATA_IN] = { },
2888 [SCI_REQ_STP_PIO_DATA_OUT] = { },
2889 [SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { },
2890 [SCI_REQ_STP_UDMA_WAIT_D2H] = { },
2891 [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED] = {
Dan Williams89a73012011-06-30 19:14:33 -07002892 .enter_state = sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07002893 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002894 [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG] = {
Dan Williams89a73012011-06-30 19:14:33 -07002895 .enter_state = sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07002896 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002897 [SCI_REQ_STP_SOFT_RESET_WAIT_D2H] = { },
2898 [SCI_REQ_TASK_WAIT_TC_COMP] = { },
2899 [SCI_REQ_TASK_WAIT_TC_RESP] = { },
2900 [SCI_REQ_SMP_WAIT_RESP] = { },
2901 [SCI_REQ_SMP_WAIT_TC_COMP] = { },
2902 [SCI_REQ_COMPLETED] = {
Dan Williams89a73012011-06-30 19:14:33 -07002903 .enter_state = sci_request_completed_state_enter,
Dan Williamsf1f52e72011-05-10 02:28:45 -07002904 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002905 [SCI_REQ_ABORTING] = {
Dan Williams89a73012011-06-30 19:14:33 -07002906 .enter_state = sci_request_aborting_state_enter,
Dan Williamsf1f52e72011-05-10 02:28:45 -07002907 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00002908 [SCI_REQ_FINAL] = { },
Dan Williamsf1f52e72011-05-10 02:28:45 -07002909};
2910
Edmund Nadolskie3013702011-06-02 00:10:43 +00002911static void
Dan Williams89a73012011-06-30 19:14:33 -07002912sci_general_request_construct(struct isci_host *ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07002913 struct isci_remote_device *idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07002914 struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002915{
Dan Williams89a73012011-06-30 19:14:33 -07002916 sci_init_sm(&ireq->sm, sci_request_state_table, SCI_REQ_INIT);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002917
Dan Williams78a6f062011-06-30 16:31:37 -07002918 ireq->target_device = idev;
Dan Williams5076a1a2011-06-27 14:57:03 -07002919 ireq->protocol = SCIC_NO_PROTOCOL;
2920 ireq->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002921
Dan Williams5076a1a2011-06-27 14:57:03 -07002922 ireq->sci_status = SCI_SUCCESS;
2923 ireq->scu_status = 0;
2924 ireq->post_context = 0xFFFFFFFF;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002925}
2926
2927static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07002928sci_io_request_construct(struct isci_host *ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07002929 struct isci_remote_device *idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07002930 struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002931{
Dan Williams78a6f062011-06-30 16:31:37 -07002932 struct domain_device *dev = idev->domain_dev;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002933 enum sci_status status = SCI_SUCCESS;
2934
2935 /* Build the common part of the request */
Dan Williams89a73012011-06-30 19:14:33 -07002936 sci_general_request_construct(ihost, idev, ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002937
Dan Williams78a6f062011-06-30 16:31:37 -07002938 if (idev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002939 return SCI_FAILURE_INVALID_REMOTE_DEVICE;
2940
2941 if (dev->dev_type == SAS_END_DEV)
Dan Williamsc72086e2011-05-10 02:28:48 -07002942 /* pass */;
2943 else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
Dan Williams5076a1a2011-06-27 14:57:03 -07002944 memset(&ireq->stp.cmd, 0, sizeof(ireq->stp.cmd));
Dan Williamsc72086e2011-05-10 02:28:48 -07002945 else if (dev_is_expander(dev))
Dan Williamse9bf7092011-06-16 16:59:56 -07002946 /* pass */;
Dan Williamsc72086e2011-05-10 02:28:48 -07002947 else
2948 return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002949
Dan Williams5076a1a2011-06-27 14:57:03 -07002950 memset(ireq->tc, 0, offsetof(struct scu_task_context, sgl_pair_ab));
Dan Williamsf1f52e72011-05-10 02:28:45 -07002951
2952 return status;
2953}
2954
Dan Williams89a73012011-06-30 19:14:33 -07002955enum sci_status sci_task_request_construct(struct isci_host *ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07002956 struct isci_remote_device *idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07002957 u16 io_tag, struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07002958{
Dan Williams78a6f062011-06-30 16:31:37 -07002959 struct domain_device *dev = idev->domain_dev;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002960 enum sci_status status = SCI_SUCCESS;
2961
2962 /* Build the common part of the request */
Dan Williams89a73012011-06-30 19:14:33 -07002963 sci_general_request_construct(ihost, idev, ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002964
Dan Williamsc72086e2011-05-10 02:28:48 -07002965 if (dev->dev_type == SAS_END_DEV ||
2966 dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
Dan Williams5076a1a2011-06-27 14:57:03 -07002967 set_bit(IREQ_TMF, &ireq->flags);
2968 memset(ireq->tc, 0, sizeof(struct scu_task_context));
Dan Williamsc72086e2011-05-10 02:28:48 -07002969 } else
2970 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williamsf1f52e72011-05-10 02:28:45 -07002971
2972 return status;
2973}
2974
2975static enum sci_status isci_request_ssp_request_construct(
2976 struct isci_request *request)
2977{
2978 enum sci_status status;
2979
2980 dev_dbg(&request->isci_host->pdev->dev,
2981 "%s: request = %p\n",
2982 __func__,
2983 request);
Dan Williams89a73012011-06-30 19:14:33 -07002984 status = sci_io_request_construct_basic_ssp(request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07002985 return status;
2986}
2987
2988static enum sci_status isci_request_stp_request_construct(
2989 struct isci_request *request)
2990{
2991 struct sas_task *task = isci_request_access_task(request);
2992 enum sci_status status;
2993 struct host_to_dev_fis *register_fis;
2994
2995 dev_dbg(&request->isci_host->pdev->dev,
2996 "%s: request = %p\n",
2997 __func__,
2998 request);
2999
3000 /* Get the host_to_dev_fis from the core and copy
3001 * the fis from the task into it.
3002 */
3003 register_fis = isci_sata_task_to_fis_copy(task);
3004
Dan Williams89a73012011-06-30 19:14:33 -07003005 status = sci_io_request_construct_basic_sata(request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003006
3007 /* Set the ncq tag in the fis, from the queue
3008 * command in the task.
3009 */
3010 if (isci_sata_is_task_ncq(task)) {
3011
3012 isci_sata_set_ncq_tag(
3013 register_fis,
3014 task
3015 );
3016 }
3017
3018 return status;
3019}
3020
Dan Williamse9bf7092011-06-16 16:59:56 -07003021static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07003022sci_io_request_construct_smp(struct device *dev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003023 struct isci_request *ireq,
Dan Williamse9bf7092011-06-16 16:59:56 -07003024 struct sas_task *task)
Dan Williamsc72086e2011-05-10 02:28:48 -07003025{
Dan Williamse9bf7092011-06-16 16:59:56 -07003026 struct scatterlist *sg = &task->smp_task.smp_req;
Dan Williams78a6f062011-06-30 16:31:37 -07003027 struct isci_remote_device *idev;
Dan Williamsc72086e2011-05-10 02:28:48 -07003028 struct scu_task_context *task_context;
Dan Williamsffe191c2011-06-29 13:09:25 -07003029 struct isci_port *iport;
Dan Williamse9bf7092011-06-16 16:59:56 -07003030 struct smp_req *smp_req;
3031 void *kaddr;
3032 u8 req_len;
3033 u32 cmd;
3034
3035 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
3036 smp_req = kaddr + sg->offset;
3037 /*
3038 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
3039 * functions under SAS 2.0, a zero request length really indicates
3040 * a non-zero default length.
3041 */
3042 if (smp_req->req_len == 0) {
3043 switch (smp_req->func) {
3044 case SMP_DISCOVER:
3045 case SMP_REPORT_PHY_ERR_LOG:
3046 case SMP_REPORT_PHY_SATA:
3047 case SMP_REPORT_ROUTE_INFO:
3048 smp_req->req_len = 2;
3049 break;
3050 case SMP_CONF_ROUTE_INFO:
3051 case SMP_PHY_CONTROL:
3052 case SMP_PHY_TEST_FUNCTION:
3053 smp_req->req_len = 9;
3054 break;
3055 /* Default - zero is a valid default for 2.0. */
3056 }
3057 }
3058 req_len = smp_req->req_len;
3059 sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
3060 cmd = *(u32 *) smp_req;
3061 kunmap_atomic(kaddr, KM_IRQ0);
3062
3063 if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
3064 return SCI_FAILURE;
3065
Dan Williams5076a1a2011-06-27 14:57:03 -07003066 ireq->protocol = SCIC_SMP_PROTOCOL;
Dan Williamsc72086e2011-05-10 02:28:48 -07003067
3068 /* byte swap the smp request. */
Dan Williamsc72086e2011-05-10 02:28:48 -07003069
Dan Williams5076a1a2011-06-27 14:57:03 -07003070 task_context = ireq->tc;
Dan Williamsc72086e2011-05-10 02:28:48 -07003071
Dan Williams34a99152011-07-01 02:25:15 -07003072 idev = ireq->target_device;
3073 iport = idev->owning_port;
Dan Williamsc72086e2011-05-10 02:28:48 -07003074
3075 /*
3076 * Fill in the TC with the its required data
3077 * 00h
3078 */
3079 task_context->priority = 0;
3080 task_context->initiator_request = 1;
Dan Williams78a6f062011-06-30 16:31:37 -07003081 task_context->connection_rate = idev->connection_rate;
Dan Williams34a99152011-07-01 02:25:15 -07003082 task_context->protocol_engine_index = ISCI_PEG;
3083 task_context->logical_port_index = iport->physical_port_index;
Dan Williamsc72086e2011-05-10 02:28:48 -07003084 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
3085 task_context->abort = 0;
3086 task_context->valid = SCU_TASK_CONTEXT_VALID;
3087 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
3088
3089 /* 04h */
Dan Williams78a6f062011-06-30 16:31:37 -07003090 task_context->remote_node_index = idev->rnc.remote_node_index;
Dan Williamsc72086e2011-05-10 02:28:48 -07003091 task_context->command_code = 0;
3092 task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
3093
3094 /* 08h */
3095 task_context->link_layer_control = 0;
3096 task_context->do_not_dma_ssp_good_response = 1;
3097 task_context->strict_ordering = 0;
3098 task_context->control_frame = 1;
3099 task_context->timeout_enable = 0;
3100 task_context->block_guard_enable = 0;
3101
3102 /* 0ch */
3103 task_context->address_modifier = 0;
3104
3105 /* 10h */
Dave Jiang77d67382011-05-25 02:21:57 +00003106 task_context->ssp_command_iu_length = req_len;
Dan Williamsc72086e2011-05-10 02:28:48 -07003107
3108 /* 14h */
3109 task_context->transfer_length_bytes = 0;
3110
3111 /*
3112 * 18h ~ 30h, protocol specific
3113 * since commandIU has been build by framework at this point, we just
3114 * copy the frist DWord from command IU to this location. */
Dan Williamse9bf7092011-06-16 16:59:56 -07003115 memcpy(&task_context->type.smp, &cmd, sizeof(u32));
Dan Williamsc72086e2011-05-10 02:28:48 -07003116
3117 /*
3118 * 40h
3119 * "For SMP you could program it to zero. We would prefer that way
3120 * so that done code will be consistent." - Venki
3121 */
3122 task_context->task_phase = 0;
3123
Dan Williams5076a1a2011-06-27 14:57:03 -07003124 ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
Dan Williams34a99152011-07-01 02:25:15 -07003125 (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
3126 (iport->physical_port_index <<
3127 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
3128 ISCI_TAG_TCI(ireq->io_tag));
Dan Williamsc72086e2011-05-10 02:28:48 -07003129 /*
3130 * Copy the physical address for the command buffer to the SCU Task
3131 * Context command buffer should not contain command header.
3132 */
Dan Williamse9bf7092011-06-16 16:59:56 -07003133 task_context->command_iu_upper = upper_32_bits(sg_dma_address(sg));
3134 task_context->command_iu_lower = lower_32_bits(sg_dma_address(sg) + sizeof(u32));
Dan Williamsc72086e2011-05-10 02:28:48 -07003135
3136 /* SMP response comes as UF, so no need to set response IU address. */
3137 task_context->response_iu_upper = 0;
3138 task_context->response_iu_lower = 0;
Dan Williamsc72086e2011-05-10 02:28:48 -07003139
Dan Williams5076a1a2011-06-27 14:57:03 -07003140 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williamsc72086e2011-05-10 02:28:48 -07003141
3142 return SCI_SUCCESS;
3143}
3144
3145/*
Dan Williamsf1f52e72011-05-10 02:28:45 -07003146 * isci_smp_request_build() - This function builds the smp request.
3147 * @ireq: This parameter points to the isci_request allocated in the
3148 * request construct function.
3149 *
3150 * SCI_SUCCESS on successfull completion, or specific failure code.
3151 */
3152static enum sci_status isci_smp_request_build(struct isci_request *ireq)
3153{
Dan Williamsf1f52e72011-05-10 02:28:45 -07003154 struct sas_task *task = isci_request_access_task(ireq);
Dan Williamse9bf7092011-06-16 16:59:56 -07003155 struct device *dev = &ireq->isci_host->pdev->dev;
Dan Williamse9bf7092011-06-16 16:59:56 -07003156 enum sci_status status = SCI_FAILURE;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003157
Dan Williams89a73012011-06-30 19:14:33 -07003158 status = sci_io_request_construct_smp(dev, ireq, task);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003159 if (status != SCI_SUCCESS)
3160 dev_warn(&ireq->isci_host->pdev->dev,
3161 "%s: failed with status = %d\n",
3162 __func__,
3163 status);
3164
3165 return status;
3166}
3167
3168/**
3169 * isci_io_request_build() - This function builds the io request object.
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003170 * @ihost: This parameter specifies the ISCI host object
Dan Williamsf1f52e72011-05-10 02:28:45 -07003171 * @request: This parameter points to the isci_request object allocated in the
3172 * request construct function.
3173 * @sci_device: This parameter is the handle for the sci core's remote device
3174 * object that is the destination for this request.
3175 *
3176 * SCI_SUCCESS on successfull completion, or specific failure code.
3177 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003178static enum sci_status isci_io_request_build(struct isci_host *ihost,
Dan Williams312e0c22011-06-28 13:47:09 -07003179 struct isci_request *request,
Dan Williams78a6f062011-06-30 16:31:37 -07003180 struct isci_remote_device *idev)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003181{
3182 enum sci_status status = SCI_SUCCESS;
3183 struct sas_task *task = isci_request_access_task(request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003184
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003185 dev_dbg(&ihost->pdev->dev,
Dan Williams78a6f062011-06-30 16:31:37 -07003186 "%s: idev = 0x%p; request = %p, "
Dan Williamsf1f52e72011-05-10 02:28:45 -07003187 "num_scatter = %d\n",
3188 __func__,
Dan Williams78a6f062011-06-30 16:31:37 -07003189 idev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003190 request,
3191 task->num_scatter);
3192
3193 /* map the sgl addresses, if present.
3194 * libata does the mapping for sata devices
3195 * before we get the request.
3196 */
3197 if (task->num_scatter &&
3198 !sas_protocol_ata(task->task_proto) &&
3199 !(SAS_PROTOCOL_SMP & task->task_proto)) {
3200
3201 request->num_sg_entries = dma_map_sg(
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003202 &ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003203 task->scatter,
3204 task->num_scatter,
3205 task->data_dir
3206 );
3207
3208 if (request->num_sg_entries == 0)
3209 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
3210 }
3211
Dan Williams89a73012011-06-30 19:14:33 -07003212 status = sci_io_request_construct(ihost, idev, request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003213
3214 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003215 dev_warn(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003216 "%s: failed request construct\n",
3217 __func__);
3218 return SCI_FAILURE;
3219 }
3220
3221 switch (task->task_proto) {
3222 case SAS_PROTOCOL_SMP:
3223 status = isci_smp_request_build(request);
3224 break;
3225 case SAS_PROTOCOL_SSP:
3226 status = isci_request_ssp_request_construct(request);
3227 break;
3228 case SAS_PROTOCOL_SATA:
3229 case SAS_PROTOCOL_STP:
3230 case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
3231 status = isci_request_stp_request_construct(request);
3232 break;
3233 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003234 dev_warn(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003235 "%s: unknown protocol\n", __func__);
3236 return SCI_FAILURE;
3237 }
3238
3239 return SCI_SUCCESS;
3240}
3241
Dan Williamsdb056252011-06-17 14:18:39 -07003242static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003243{
Dan Williams0d0cf142011-06-13 00:51:30 -07003244 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003245
Dan Williamsdb056252011-06-17 14:18:39 -07003246 ireq = ihost->reqs[ISCI_TAG_TCI(tag)];
Dan Williams5076a1a2011-06-27 14:57:03 -07003247 ireq->io_tag = tag;
Dan Williams0d0cf142011-06-13 00:51:30 -07003248 ireq->io_request_completion = NULL;
Dan Williams38d88792011-06-23 14:33:48 -07003249 ireq->flags = 0;
Dan Williams0d0cf142011-06-13 00:51:30 -07003250 ireq->num_sg_entries = 0;
Dan Williams0d0cf142011-06-13 00:51:30 -07003251 INIT_LIST_HEAD(&ireq->completed_node);
3252 INIT_LIST_HEAD(&ireq->dev_node);
Dan Williams0d0cf142011-06-13 00:51:30 -07003253 isci_request_change_state(ireq, allocated);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003254
Dan Williams0d0cf142011-06-13 00:51:30 -07003255 return ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003256}
3257
Dan Williamsdb056252011-06-17 14:18:39 -07003258static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost,
3259 struct sas_task *task,
3260 u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003261{
Dan Williams0d0cf142011-06-13 00:51:30 -07003262 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003263
Dan Williamsdb056252011-06-17 14:18:39 -07003264 ireq = isci_request_from_tag(ihost, tag);
3265 ireq->ttype_ptr.io_task_ptr = task;
3266 ireq->ttype = io_task;
3267 task->lldd_task = ireq;
3268
Dan Williams0d0cf142011-06-13 00:51:30 -07003269 return ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003270}
3271
Dan Williamsdb056252011-06-17 14:18:39 -07003272struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
3273 struct isci_tmf *isci_tmf,
3274 u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003275{
Dan Williams0d0cf142011-06-13 00:51:30 -07003276 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003277
Dan Williamsdb056252011-06-17 14:18:39 -07003278 ireq = isci_request_from_tag(ihost, tag);
3279 ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
3280 ireq->ttype = tmf_task;
3281
Dan Williams0d0cf142011-06-13 00:51:30 -07003282 return ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003283}
3284
Dan Williams209fae12011-06-13 17:39:44 -07003285int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev,
Dan Williamsdb056252011-06-17 14:18:39 -07003286 struct sas_task *task, u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003287{
Dan Williamsf1f52e72011-05-10 02:28:45 -07003288 enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williams0d0cf142011-06-13 00:51:30 -07003289 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003290 unsigned long flags;
Dan Williams0d0cf142011-06-13 00:51:30 -07003291 int ret = 0;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003292
Dan Williamsf1f52e72011-05-10 02:28:45 -07003293 /* do common allocation and init of request object. */
Dan Williamsdb056252011-06-17 14:18:39 -07003294 ireq = isci_io_request_from_tag(ihost, task, tag);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003295
Dan Williamsdb056252011-06-17 14:18:39 -07003296 status = isci_io_request_build(ihost, ireq, idev);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003297 if (status != SCI_SUCCESS) {
Dan Williams0d0cf142011-06-13 00:51:30 -07003298 dev_warn(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003299 "%s: request_construct failed - status = 0x%x\n",
3300 __func__,
3301 status);
Dan Williamsdb056252011-06-17 14:18:39 -07003302 return status;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003303 }
3304
Dan Williams0d0cf142011-06-13 00:51:30 -07003305 spin_lock_irqsave(&ihost->scic_lock, flags);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003306
Jeff Skirvin9274f452011-06-23 17:09:02 -07003307 if (test_bit(IDEV_IO_NCQERROR, &idev->flags)) {
3308
3309 if (isci_task_is_ncq_recovery(task)) {
3310
3311 /* The device is in an NCQ recovery state. Issue the
3312 * request on the task side. Note that it will
3313 * complete on the I/O request side because the
3314 * request was built that way (ie.
3315 * ireq->is_task_management_request is false).
3316 */
Dan Williams89a73012011-06-30 19:14:33 -07003317 status = sci_controller_start_task(ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07003318 idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003319 ireq);
Jeff Skirvin9274f452011-06-23 17:09:02 -07003320 } else {
3321 status = SCI_FAILURE;
3322 }
3323 } else {
Jeff Skirvin9274f452011-06-23 17:09:02 -07003324 /* send the request, let the core assign the IO TAG. */
Dan Williams89a73012011-06-30 19:14:33 -07003325 status = sci_controller_start_io(ihost, idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003326 ireq);
Jeff Skirvin9274f452011-06-23 17:09:02 -07003327 }
Dan Williams312e0c22011-06-28 13:47:09 -07003328
Dan Williamsf1f52e72011-05-10 02:28:45 -07003329 if (status != SCI_SUCCESS &&
3330 status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
Dan Williams0d0cf142011-06-13 00:51:30 -07003331 dev_warn(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003332 "%s: failed request start (0x%x)\n",
3333 __func__, status);
Dan Williams0d0cf142011-06-13 00:51:30 -07003334 spin_unlock_irqrestore(&ihost->scic_lock, flags);
Dan Williamsdb056252011-06-17 14:18:39 -07003335 return status;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003336 }
3337
3338 /* Either I/O started OK, or the core has signaled that
3339 * the device needs a target reset.
3340 *
3341 * In either case, hold onto the I/O for later.
3342 *
3343 * Update it's status and add it to the list in the
3344 * remote device object.
3345 */
Dan Williams0d0cf142011-06-13 00:51:30 -07003346 list_add(&ireq->dev_node, &idev->reqs_in_process);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003347
3348 if (status == SCI_SUCCESS) {
Dan Williams0d0cf142011-06-13 00:51:30 -07003349 isci_request_change_state(ireq, started);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003350 } else {
3351 /* The request did not really start in the
3352 * hardware, so clear the request handle
3353 * here so no terminations will be done.
3354 */
Dan Williams38d88792011-06-23 14:33:48 -07003355 set_bit(IREQ_TERMINATED, &ireq->flags);
Dan Williams0d0cf142011-06-13 00:51:30 -07003356 isci_request_change_state(ireq, completed);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003357 }
Dan Williams0d0cf142011-06-13 00:51:30 -07003358 spin_unlock_irqrestore(&ihost->scic_lock, flags);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003359
3360 if (status ==
3361 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
3362 /* Signal libsas that we need the SCSI error
Dan Williams312e0c22011-06-28 13:47:09 -07003363 * handler thread to work on this I/O and that
3364 * we want a device reset.
3365 */
Dan Williamsf1f52e72011-05-10 02:28:45 -07003366 spin_lock_irqsave(&task->task_state_lock, flags);
3367 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
3368 spin_unlock_irqrestore(&task->task_state_lock, flags);
3369
3370 /* Cause this task to be scheduled in the SCSI error
Dan Williams312e0c22011-06-28 13:47:09 -07003371 * handler thread.
3372 */
Dan Williams0d0cf142011-06-13 00:51:30 -07003373 isci_execpath_callback(ihost, task,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003374 sas_task_abort);
3375
3376 /* Change the status, since we are holding
Dan Williams312e0c22011-06-28 13:47:09 -07003377 * the I/O until it is managed by the SCSI
3378 * error handler.
3379 */
Dan Williamsf1f52e72011-05-10 02:28:45 -07003380 status = SCI_SUCCESS;
3381 }
3382
Dan Williamsf1f52e72011-05-10 02:28:45 -07003383 return ret;
3384}