blob: 192cb48d849ac6429673d9529505bac2608d87d2 [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"
Dan Williams6f231dd2011-07-02 22:56:22 -070059#include "scu_completion_codes.h"
Dan Williams5dec6f42011-05-10 02:28:49 -070060#include "scu_event_codes.h"
Dave Jiang2ec53eb2011-05-04 18:01:22 -070061#include "sas.h"
Dan Williams6f231dd2011-07-02 22:56:22 -070062
Dan Williams5076a1a2011-06-27 14:57:03 -070063static struct scu_sgl_element_pair *to_sgl_element_pair(struct isci_request *ireq,
Dan Williams312e0c22011-06-28 13:47:09 -070064 int idx)
65{
66 if (idx == 0)
Dan Williams5076a1a2011-06-27 14:57:03 -070067 return &ireq->tc->sgl_pair_ab;
Dan Williams312e0c22011-06-28 13:47:09 -070068 else if (idx == 1)
Dan Williams5076a1a2011-06-27 14:57:03 -070069 return &ireq->tc->sgl_pair_cd;
Dan Williams312e0c22011-06-28 13:47:09 -070070 else if (idx < 0)
71 return NULL;
72 else
Dan Williams5076a1a2011-06-27 14:57:03 -070073 return &ireq->sg_table[idx - 2];
Dan Williams6f231dd2011-07-02 22:56:22 -070074}
75
Dan Williamsd9dcb4b2011-06-30 17:38:32 -070076static dma_addr_t to_sgl_element_pair_dma(struct isci_host *ihost,
Dan Williams5076a1a2011-06-27 14:57:03 -070077 struct isci_request *ireq, u32 idx)
Dan Williams312e0c22011-06-28 13:47:09 -070078{
79 u32 offset;
80
81 if (idx == 0) {
Dan Williams5076a1a2011-06-27 14:57:03 -070082 offset = (void *) &ireq->tc->sgl_pair_ab -
Dan Williamsd9dcb4b2011-06-30 17:38:32 -070083 (void *) &ihost->task_context_table[0];
84 return ihost->task_context_dma + offset;
Dan Williams312e0c22011-06-28 13:47:09 -070085 } else if (idx == 1) {
Dan Williams5076a1a2011-06-27 14:57:03 -070086 offset = (void *) &ireq->tc->sgl_pair_cd -
Dan Williamsd9dcb4b2011-06-30 17:38:32 -070087 (void *) &ihost->task_context_table[0];
88 return ihost->task_context_dma + offset;
Dan Williams312e0c22011-06-28 13:47:09 -070089 }
90
Dan Williams89a73012011-06-30 19:14:33 -070091 return sci_io_request_get_dma_addr(ireq, &ireq->sg_table[idx - 2]);
Dan Williams312e0c22011-06-28 13:47:09 -070092}
93
94static void init_sgl_element(struct scu_sgl_element *e, struct scatterlist *sg)
95{
96 e->length = sg_dma_len(sg);
97 e->address_upper = upper_32_bits(sg_dma_address(sg));
98 e->address_lower = lower_32_bits(sg_dma_address(sg));
99 e->address_modifier = 0;
100}
101
Dan Williams89a73012011-06-30 19:14:33 -0700102static void sci_request_build_sgl(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700103{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700104 struct isci_host *ihost = ireq->isci_host;
Dan Williams5076a1a2011-06-27 14:57:03 -0700105 struct sas_task *task = isci_request_access_task(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700106 struct scatterlist *sg = NULL;
107 dma_addr_t dma_addr;
108 u32 sg_idx = 0;
109 struct scu_sgl_element_pair *scu_sg = NULL;
110 struct scu_sgl_element_pair *prev_sg = NULL;
111
112 if (task->num_scatter > 0) {
113 sg = task->scatter;
114
115 while (sg) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700116 scu_sg = to_sgl_element_pair(ireq, sg_idx);
Dan Williams312e0c22011-06-28 13:47:09 -0700117 init_sgl_element(&scu_sg->A, sg);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700118 sg = sg_next(sg);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700119 if (sg) {
Dan Williams312e0c22011-06-28 13:47:09 -0700120 init_sgl_element(&scu_sg->B, sg);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700121 sg = sg_next(sg);
122 } else
Dan Williams312e0c22011-06-28 13:47:09 -0700123 memset(&scu_sg->B, 0, sizeof(scu_sg->B));
Dan Williamsf1f52e72011-05-10 02:28:45 -0700124
125 if (prev_sg) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700126 dma_addr = to_sgl_element_pair_dma(ihost,
Dan Williams5076a1a2011-06-27 14:57:03 -0700127 ireq,
Dan Williams312e0c22011-06-28 13:47:09 -0700128 sg_idx);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700129
130 prev_sg->next_pair_upper =
131 upper_32_bits(dma_addr);
132 prev_sg->next_pair_lower =
133 lower_32_bits(dma_addr);
134 }
135
136 prev_sg = scu_sg;
137 sg_idx++;
138 }
139 } else { /* handle when no sg */
Dan Williams5076a1a2011-06-27 14:57:03 -0700140 scu_sg = to_sgl_element_pair(ireq, sg_idx);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700141
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700142 dma_addr = dma_map_single(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700143 task->scatter,
144 task->total_xfer_len,
145 task->data_dir);
146
Dan Williams5076a1a2011-06-27 14:57:03 -0700147 ireq->zero_scatter_daddr = dma_addr;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700148
149 scu_sg->A.length = task->total_xfer_len;
150 scu_sg->A.address_upper = upper_32_bits(dma_addr);
151 scu_sg->A.address_lower = lower_32_bits(dma_addr);
152 }
153
154 if (scu_sg) {
155 scu_sg->next_pair_upper = 0;
156 scu_sg->next_pair_lower = 0;
157 }
158}
159
Dan Williams89a73012011-06-30 19:14:33 -0700160static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700161{
162 struct ssp_cmd_iu *cmd_iu;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700163 struct sas_task *task = isci_request_access_task(ireq);
164
Dan Williams5076a1a2011-06-27 14:57:03 -0700165 cmd_iu = &ireq->ssp.cmd;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700166
167 memcpy(cmd_iu->LUN, task->ssp_task.LUN, 8);
168 cmd_iu->add_cdb_len = 0;
169 cmd_iu->_r_a = 0;
170 cmd_iu->_r_b = 0;
171 cmd_iu->en_fburst = 0; /* unsupported */
172 cmd_iu->task_prio = task->ssp_task.task_prio;
173 cmd_iu->task_attr = task->ssp_task.task_attr;
174 cmd_iu->_r_c = 0;
175
176 sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
177 sizeof(task->ssp_task.cdb) / sizeof(u32));
178}
179
Dan Williams89a73012011-06-30 19:14:33 -0700180static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700181{
182 struct ssp_task_iu *task_iu;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700183 struct sas_task *task = isci_request_access_task(ireq);
184 struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
185
Dan Williams5076a1a2011-06-27 14:57:03 -0700186 task_iu = &ireq->ssp.tmf;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700187
188 memset(task_iu, 0, sizeof(struct ssp_task_iu));
189
190 memcpy(task_iu->LUN, task->ssp_task.LUN, 8);
191
192 task_iu->task_func = isci_tmf->tmf_code;
193 task_iu->task_tag =
Jeff Skirvin3b34c162011-10-27 15:05:22 -0700194 (test_bit(IREQ_TMF, &ireq->flags)) ?
Dan Williamsf1f52e72011-05-10 02:28:45 -0700195 isci_tmf->io_tag :
196 SCI_CONTROLLER_INVALID_IO_TAG;
197}
198
199/**
200 * This method is will fill in the SCU Task Context for any type of SSP request.
201 * @sci_req:
202 * @task_context:
203 *
204 */
205static void scu_ssp_reqeust_construct_task_context(
Dan Williams5076a1a2011-06-27 14:57:03 -0700206 struct isci_request *ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700207 struct scu_task_context *task_context)
208{
209 dma_addr_t dma_addr;
Dan Williams78a6f062011-06-30 16:31:37 -0700210 struct isci_remote_device *idev;
Dan Williamsffe191c2011-06-29 13:09:25 -0700211 struct isci_port *iport;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700212
Dan Williams34a99152011-07-01 02:25:15 -0700213 idev = ireq->target_device;
214 iport = idev->owning_port;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700215
216 /* Fill in the TC with the its required data */
217 task_context->abort = 0;
218 task_context->priority = 0;
219 task_context->initiator_request = 1;
Dan Williams78a6f062011-06-30 16:31:37 -0700220 task_context->connection_rate = idev->connection_rate;
Dan Williams34a99152011-07-01 02:25:15 -0700221 task_context->protocol_engine_index = ISCI_PEG;
222 task_context->logical_port_index = iport->physical_port_index;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700223 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
224 task_context->valid = SCU_TASK_CONTEXT_VALID;
225 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
226
Dan Williams34a99152011-07-01 02:25:15 -0700227 task_context->remote_node_index = idev->rnc.remote_node_index;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700228 task_context->command_code = 0;
229
230 task_context->link_layer_control = 0;
231 task_context->do_not_dma_ssp_good_response = 1;
232 task_context->strict_ordering = 0;
233 task_context->control_frame = 0;
234 task_context->timeout_enable = 0;
235 task_context->block_guard_enable = 0;
236
237 task_context->address_modifier = 0;
238
Dan Williams5076a1a2011-06-27 14:57:03 -0700239 /* task_context->type.ssp.tag = ireq->io_tag; */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700240 task_context->task_phase = 0x01;
241
Dan Williams5076a1a2011-06-27 14:57:03 -0700242 ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
Dan Williams34a99152011-07-01 02:25:15 -0700243 (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
244 (iport->physical_port_index <<
Dan Williamsffe191c2011-06-29 13:09:25 -0700245 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
246 ISCI_TAG_TCI(ireq->io_tag));
Dan Williamsf1f52e72011-05-10 02:28:45 -0700247
248 /*
249 * Copy the physical address for the command buffer to the
250 * SCU Task Context
251 */
Dan Williams89a73012011-06-30 19:14:33 -0700252 dma_addr = sci_io_request_get_dma_addr(ireq, &ireq->ssp.cmd);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700253
254 task_context->command_iu_upper = upper_32_bits(dma_addr);
255 task_context->command_iu_lower = lower_32_bits(dma_addr);
256
257 /*
258 * Copy the physical address for the response buffer to the
259 * SCU Task Context
260 */
Dan Williams89a73012011-06-30 19:14:33 -0700261 dma_addr = sci_io_request_get_dma_addr(ireq, &ireq->ssp.rsp);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700262
263 task_context->response_iu_upper = upper_32_bits(dma_addr);
264 task_context->response_iu_lower = lower_32_bits(dma_addr);
265}
266
267/**
268 * This method is will fill in the SCU Task Context for a SSP IO request.
269 * @sci_req:
270 *
271 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700272static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
Dan Williams312e0c22011-06-28 13:47:09 -0700273 enum dma_data_direction dir,
274 u32 len)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700275{
Dan Williams5076a1a2011-06-27 14:57:03 -0700276 struct scu_task_context *task_context = ireq->tc;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700277
Dan Williams5076a1a2011-06-27 14:57:03 -0700278 scu_ssp_reqeust_construct_task_context(ireq, task_context);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700279
280 task_context->ssp_command_iu_length =
281 sizeof(struct ssp_cmd_iu) / sizeof(u32);
282 task_context->type.ssp.frame_type = SSP_COMMAND;
283
284 switch (dir) {
285 case DMA_FROM_DEVICE:
286 case DMA_NONE:
287 default:
288 task_context->task_type = SCU_TASK_TYPE_IOREAD;
289 break;
290 case DMA_TO_DEVICE:
291 task_context->task_type = SCU_TASK_TYPE_IOWRITE;
292 break;
293 }
294
295 task_context->transfer_length_bytes = len;
296
297 if (task_context->transfer_length_bytes > 0)
Dan Williams89a73012011-06-30 19:14:33 -0700298 sci_request_build_sgl(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700299}
300
Dan Williamsf1f52e72011-05-10 02:28:45 -0700301/**
302 * This method will fill in the SCU Task Context for a SSP Task request. The
303 * following important settings are utilized: -# priority ==
304 * SCU_TASK_PRIORITY_HIGH. This ensures that the task request is issued
305 * ahead of other task destined for the same Remote Node. -# task_type ==
306 * SCU_TASK_TYPE_IOREAD. This simply indicates that a normal request type
307 * (i.e. non-raw frame) is being utilized to perform task management. -#
308 * control_frame == 1. This ensures that the proper endianess is set so
309 * that the bytes are transmitted in the right order for a task frame.
310 * @sci_req: This parameter specifies the task request object being
311 * constructed.
312 *
313 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700314static void scu_ssp_task_request_construct_task_context(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700315{
Dan Williams5076a1a2011-06-27 14:57:03 -0700316 struct scu_task_context *task_context = ireq->tc;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700317
Dan Williams5076a1a2011-06-27 14:57:03 -0700318 scu_ssp_reqeust_construct_task_context(ireq, task_context);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700319
320 task_context->control_frame = 1;
321 task_context->priority = SCU_TASK_PRIORITY_HIGH;
322 task_context->task_type = SCU_TASK_TYPE_RAW_FRAME;
323 task_context->transfer_length_bytes = 0;
324 task_context->type.ssp.frame_type = SSP_TASK;
325 task_context->ssp_command_iu_length =
326 sizeof(struct ssp_task_iu) / sizeof(u32);
327}
328
Dan Williamsf1f52e72011-05-10 02:28:45 -0700329/**
Dan Williams5dec6f42011-05-10 02:28:49 -0700330 * This method is will fill in the SCU Task Context for any type of SATA
331 * request. This is called from the various SATA constructors.
332 * @sci_req: The general IO request object which is to be used in
333 * constructing the SCU task context.
334 * @task_context: The buffer pointer for the SCU task context which is being
335 * constructed.
Dan Williamsf1f52e72011-05-10 02:28:45 -0700336 *
Dan Williams5dec6f42011-05-10 02:28:49 -0700337 * The general io request construction is complete. The buffer assignment for
338 * the command buffer is complete. none Revisit task context construction to
339 * determine what is common for SSP/SMP/STP task context structures.
Dan Williamsf1f52e72011-05-10 02:28:45 -0700340 */
Dan Williams5dec6f42011-05-10 02:28:49 -0700341static void scu_sata_reqeust_construct_task_context(
Dan Williams5076a1a2011-06-27 14:57:03 -0700342 struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700343 struct scu_task_context *task_context)
344{
345 dma_addr_t dma_addr;
Dan Williams78a6f062011-06-30 16:31:37 -0700346 struct isci_remote_device *idev;
Dan Williamsffe191c2011-06-29 13:09:25 -0700347 struct isci_port *iport;
Dan Williams5dec6f42011-05-10 02:28:49 -0700348
Dan Williams34a99152011-07-01 02:25:15 -0700349 idev = ireq->target_device;
350 iport = idev->owning_port;
Dan Williams5dec6f42011-05-10 02:28:49 -0700351
352 /* Fill in the TC with the its required data */
353 task_context->abort = 0;
354 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
355 task_context->initiator_request = 1;
Dan Williams78a6f062011-06-30 16:31:37 -0700356 task_context->connection_rate = idev->connection_rate;
Dan Williams34a99152011-07-01 02:25:15 -0700357 task_context->protocol_engine_index = ISCI_PEG;
358 task_context->logical_port_index = iport->physical_port_index;
Dan Williams5dec6f42011-05-10 02:28:49 -0700359 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
360 task_context->valid = SCU_TASK_CONTEXT_VALID;
361 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
362
Dan Williams34a99152011-07-01 02:25:15 -0700363 task_context->remote_node_index = idev->rnc.remote_node_index;
Dan Williams5dec6f42011-05-10 02:28:49 -0700364 task_context->command_code = 0;
365
366 task_context->link_layer_control = 0;
367 task_context->do_not_dma_ssp_good_response = 1;
368 task_context->strict_ordering = 0;
369 task_context->control_frame = 0;
370 task_context->timeout_enable = 0;
371 task_context->block_guard_enable = 0;
372
373 task_context->address_modifier = 0;
374 task_context->task_phase = 0x01;
375
376 task_context->ssp_command_iu_length =
377 (sizeof(struct host_to_dev_fis) - sizeof(u32)) / sizeof(u32);
378
379 /* Set the first word of the H2D REG FIS */
Dan Williams5076a1a2011-06-27 14:57:03 -0700380 task_context->type.words[0] = *(u32 *)&ireq->stp.cmd;
Dan Williams5dec6f42011-05-10 02:28:49 -0700381
Dan Williams5076a1a2011-06-27 14:57:03 -0700382 ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
Dan Williams34a99152011-07-01 02:25:15 -0700383 (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
384 (iport->physical_port_index <<
385 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
386 ISCI_TAG_TCI(ireq->io_tag));
Dan Williams5dec6f42011-05-10 02:28:49 -0700387 /*
388 * Copy the physical address for the command buffer to the SCU Task
389 * Context. We must offset the command buffer by 4 bytes because the
390 * first 4 bytes are transfered in the body of the TC.
391 */
Dan Williams89a73012011-06-30 19:14:33 -0700392 dma_addr = sci_io_request_get_dma_addr(ireq,
Dan Williams5076a1a2011-06-27 14:57:03 -0700393 ((char *) &ireq->stp.cmd) +
Dan Williams5dec6f42011-05-10 02:28:49 -0700394 sizeof(u32));
395
396 task_context->command_iu_upper = upper_32_bits(dma_addr);
397 task_context->command_iu_lower = lower_32_bits(dma_addr);
398
399 /* SATA Requests do not have a response buffer */
400 task_context->response_iu_upper = 0;
401 task_context->response_iu_lower = 0;
402}
403
Dan Williams5076a1a2011-06-27 14:57:03 -0700404static void scu_stp_raw_request_construct_task_context(struct isci_request *ireq)
Dan Williams5dec6f42011-05-10 02:28:49 -0700405{
Dan Williams5076a1a2011-06-27 14:57:03 -0700406 struct scu_task_context *task_context = ireq->tc;
Dan Williams5dec6f42011-05-10 02:28:49 -0700407
Dan Williams5076a1a2011-06-27 14:57:03 -0700408 scu_sata_reqeust_construct_task_context(ireq, task_context);
Dan Williams5dec6f42011-05-10 02:28:49 -0700409
410 task_context->control_frame = 0;
411 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
412 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME;
413 task_context->type.stp.fis_type = FIS_REGH2D;
414 task_context->transfer_length_bytes = sizeof(struct host_to_dev_fis) - sizeof(u32);
415}
416
Dan Williams89a73012011-06-30 19:14:33 -0700417static enum sci_status sci_stp_pio_request_construct(struct isci_request *ireq,
Dan Williams5076a1a2011-06-27 14:57:03 -0700418 bool copy_rx_frame)
Dan Williams5dec6f42011-05-10 02:28:49 -0700419{
Dan Williams5076a1a2011-06-27 14:57:03 -0700420 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williams5dec6f42011-05-10 02:28:49 -0700421
Dan Williams5076a1a2011-06-27 14:57:03 -0700422 scu_stp_raw_request_construct_task_context(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700423
Dan Williamsba7cb222011-06-27 11:56:41 -0700424 stp_req->status = 0;
425 stp_req->sgl.offset = 0;
426 stp_req->sgl.set = SCU_SGL_ELEMENT_PAIR_A;
Dan Williams5dec6f42011-05-10 02:28:49 -0700427
428 if (copy_rx_frame) {
Dan Williams89a73012011-06-30 19:14:33 -0700429 sci_request_build_sgl(ireq);
Dan Williamsba7cb222011-06-27 11:56:41 -0700430 stp_req->sgl.index = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -0700431 } else {
432 /* The user does not want the data copied to the SGL buffer location */
Dan Williamsba7cb222011-06-27 11:56:41 -0700433 stp_req->sgl.index = -1;
Dan Williams5dec6f42011-05-10 02:28:49 -0700434 }
435
436 return SCI_SUCCESS;
437}
438
439/**
440 *
441 * @sci_req: This parameter specifies the request to be constructed as an
442 * optimized request.
443 * @optimized_task_type: This parameter specifies whether the request is to be
444 * an UDMA request or a NCQ request. - A value of 0 indicates UDMA. - A
445 * value of 1 indicates NCQ.
446 *
447 * This method will perform request construction common to all types of STP
448 * requests that are optimized by the silicon (i.e. UDMA, NCQ). This method
449 * returns an indication as to whether the construction was successful.
450 */
Dan Williams89a73012011-06-30 19:14:33 -0700451static void sci_stp_optimized_request_construct(struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700452 u8 optimized_task_type,
453 u32 len,
454 enum dma_data_direction dir)
455{
Dan Williams5076a1a2011-06-27 14:57:03 -0700456 struct scu_task_context *task_context = ireq->tc;
Dan Williams5dec6f42011-05-10 02:28:49 -0700457
458 /* Build the STP task context structure */
Dan Williams5076a1a2011-06-27 14:57:03 -0700459 scu_sata_reqeust_construct_task_context(ireq, task_context);
Dan Williams5dec6f42011-05-10 02:28:49 -0700460
461 /* Copy over the SGL elements */
Dan Williams89a73012011-06-30 19:14:33 -0700462 sci_request_build_sgl(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700463
464 /* Copy over the number of bytes to be transfered */
465 task_context->transfer_length_bytes = len;
466
467 if (dir == DMA_TO_DEVICE) {
468 /*
469 * The difference between the DMA IN and DMA OUT request task type
470 * values are consistent with the difference between FPDMA READ
471 * and FPDMA WRITE values. Add the supplied task type parameter
472 * to this difference to set the task type properly for this
473 * DATA OUT (WRITE) case. */
474 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
475 - SCU_TASK_TYPE_DMA_IN);
476 } else {
477 /*
478 * For the DATA IN (READ) case, simply save the supplied
479 * optimized task type. */
480 task_context->task_type = optimized_task_type;
481 }
482}
483
Dan Williamsb50102d2011-09-30 18:52:19 -0700484static void sci_atapi_construct(struct isci_request *ireq)
485{
486 struct host_to_dev_fis *h2d_fis = &ireq->stp.cmd;
487 struct sas_task *task;
Dan Williams5dec6f42011-05-10 02:28:49 -0700488
Dan Williamsb50102d2011-09-30 18:52:19 -0700489 /* To simplify the implementation we take advantage of the
490 * silicon's partial acceleration of atapi protocol (dma data
491 * transfers), so we promote all commands to dma protocol. This
492 * breaks compatibility with ATA_HORKAGE_ATAPI_MOD16_DMA drives.
493 */
494 h2d_fis->features |= ATAPI_PKT_DMA;
495
496 scu_stp_raw_request_construct_task_context(ireq);
497
498 task = isci_request_access_task(ireq);
499 if (task->data_dir == DMA_NONE)
500 task->total_xfer_len = 0;
501
502 /* clear the response so we can detect arrivial of an
503 * unsolicited h2d fis
504 */
505 ireq->stp.rsp.fis_type = 0;
506}
Dan Williams5dec6f42011-05-10 02:28:49 -0700507
Dan Williamsf1f52e72011-05-10 02:28:45 -0700508static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -0700509sci_io_request_construct_sata(struct isci_request *ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700510 u32 len,
511 enum dma_data_direction dir,
512 bool copy)
Dan Williams6f231dd2011-07-02 22:56:22 -0700513{
Dan Williams6f231dd2011-07-02 22:56:22 -0700514 enum sci_status status = SCI_SUCCESS;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700515 struct sas_task *task = isci_request_access_task(ireq);
Dan Williamsb50102d2011-09-30 18:52:19 -0700516 struct domain_device *dev = ireq->target_device->domain_dev;
Dan Williams6f231dd2011-07-02 22:56:22 -0700517
Dan Williamsf1f52e72011-05-10 02:28:45 -0700518 /* check for management protocols */
Jeff Skirvin3b34c162011-10-27 15:05:22 -0700519 if (test_bit(IREQ_TMF, &ireq->flags)) {
Dan Williamsf1f52e72011-05-10 02:28:45 -0700520 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700521
Dan Williamsf1f52e72011-05-10 02:28:45 -0700522 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
Dan Williams5dec6f42011-05-10 02:28:49 -0700523 tmf->tmf_code == isci_tmf_sata_srst_low) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700524 scu_stp_raw_request_construct_task_context(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700525 return SCI_SUCCESS;
526 } else {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700527 dev_err(&ireq->owning_controller->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700528 "%s: Request 0x%p received un-handled SAT "
529 "management protocol 0x%x.\n",
Dan Williams5076a1a2011-06-27 14:57:03 -0700530 __func__, ireq, tmf->tmf_code);
Dan Williams6f231dd2011-07-02 22:56:22 -0700531
Dan Williamsf1f52e72011-05-10 02:28:45 -0700532 return SCI_FAILURE;
533 }
Dan Williams6f231dd2011-07-02 22:56:22 -0700534 }
535
Dan Williamsf1f52e72011-05-10 02:28:45 -0700536 if (!sas_protocol_ata(task->task_proto)) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700537 dev_err(&ireq->owning_controller->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700538 "%s: Non-ATA protocol in SATA path: 0x%x\n",
539 __func__,
540 task->task_proto);
Dan Williams6f231dd2011-07-02 22:56:22 -0700541 return SCI_FAILURE;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700542
Dan Williams6f231dd2011-07-02 22:56:22 -0700543 }
544
Dan Williamsb50102d2011-09-30 18:52:19 -0700545 /* ATAPI */
546 if (dev->sata_dev.command_set == ATAPI_COMMAND_SET &&
547 task->ata_task.fis.command == ATA_CMD_PACKET) {
548 sci_atapi_construct(ireq);
549 return SCI_SUCCESS;
550 }
551
Dan Williamsf1f52e72011-05-10 02:28:45 -0700552 /* non data */
Dan Williams5dec6f42011-05-10 02:28:49 -0700553 if (task->data_dir == DMA_NONE) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700554 scu_stp_raw_request_construct_task_context(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -0700555 return SCI_SUCCESS;
556 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700557
558 /* NCQ */
Dan Williams5dec6f42011-05-10 02:28:49 -0700559 if (task->ata_task.use_ncq) {
Dan Williams89a73012011-06-30 19:14:33 -0700560 sci_stp_optimized_request_construct(ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700561 SCU_TASK_TYPE_FPDMAQ_READ,
562 len, dir);
563 return SCI_SUCCESS;
564 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700565
566 /* DMA */
Dan Williams5dec6f42011-05-10 02:28:49 -0700567 if (task->ata_task.dma_xfer) {
Dan Williams89a73012011-06-30 19:14:33 -0700568 sci_stp_optimized_request_construct(ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -0700569 SCU_TASK_TYPE_DMA_IN,
570 len, dir);
571 return SCI_SUCCESS;
572 } else /* PIO */
Dan Williams89a73012011-06-30 19:14:33 -0700573 return sci_stp_pio_request_construct(ireq, copy);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700574
575 return status;
576}
577
Dan Williams89a73012011-06-30 19:14:33 -0700578static enum sci_status sci_io_request_construct_basic_ssp(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700579{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700580 struct sas_task *task = isci_request_access_task(ireq);
581
Dan Williams5076a1a2011-06-27 14:57:03 -0700582 ireq->protocol = SCIC_SSP_PROTOCOL;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700583
Dan Williams5076a1a2011-06-27 14:57:03 -0700584 scu_ssp_io_request_construct_task_context(ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700585 task->data_dir,
586 task->total_xfer_len);
587
Dan Williams89a73012011-06-30 19:14:33 -0700588 sci_io_request_build_ssp_command_iu(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700589
Dan Williams5076a1a2011-06-27 14:57:03 -0700590 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700591
592 return SCI_SUCCESS;
593}
594
Dan Williams89a73012011-06-30 19:14:33 -0700595enum sci_status sci_task_request_construct_ssp(
Dan Williams5076a1a2011-06-27 14:57:03 -0700596 struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700597{
598 /* Construct the SSP Task SCU Task Context */
Dan Williams5076a1a2011-06-27 14:57:03 -0700599 scu_ssp_task_request_construct_task_context(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700600
601 /* Fill in the SSP Task IU */
Dan Williams89a73012011-06-30 19:14:33 -0700602 sci_task_request_build_ssp_task_iu(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700603
Dan Williams5076a1a2011-06-27 14:57:03 -0700604 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williams6f231dd2011-07-02 22:56:22 -0700605
606 return SCI_SUCCESS;
607}
608
Dan Williams89a73012011-06-30 19:14:33 -0700609static enum sci_status sci_io_request_construct_basic_sata(struct isci_request *ireq)
Dan Williams6f231dd2011-07-02 22:56:22 -0700610{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700611 enum sci_status status;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700612 bool copy = false;
Dan Williams5076a1a2011-06-27 14:57:03 -0700613 struct sas_task *task = isci_request_access_task(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700614
Dan Williams5076a1a2011-06-27 14:57:03 -0700615 ireq->protocol = SCIC_STP_PROTOCOL;
Dan Williams6f231dd2011-07-02 22:56:22 -0700616
Dan Williamsf1f52e72011-05-10 02:28:45 -0700617 copy = (task->data_dir == DMA_NONE) ? false : true;
Dan Williams6f231dd2011-07-02 22:56:22 -0700618
Dan Williams89a73012011-06-30 19:14:33 -0700619 status = sci_io_request_construct_sata(ireq,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700620 task->total_xfer_len,
621 task->data_dir,
622 copy);
Dan Williams6f231dd2011-07-02 22:56:22 -0700623
Dan Williamsf1f52e72011-05-10 02:28:45 -0700624 if (status == SCI_SUCCESS)
Dan Williams5076a1a2011-06-27 14:57:03 -0700625 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williams6f231dd2011-07-02 22:56:22 -0700626
Dan Williamsf1f52e72011-05-10 02:28:45 -0700627 return status;
Dan Williams6f231dd2011-07-02 22:56:22 -0700628}
629
Dan Williams89a73012011-06-30 19:14:33 -0700630enum sci_status sci_task_request_construct_sata(struct isci_request *ireq)
Dan Williams6f231dd2011-07-02 22:56:22 -0700631{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700632 enum sci_status status = SCI_SUCCESS;
Dan Williams6f231dd2011-07-02 22:56:22 -0700633
Dan Williamsf1f52e72011-05-10 02:28:45 -0700634 /* check for management protocols */
Jeff Skirvin3b34c162011-10-27 15:05:22 -0700635 if (test_bit(IREQ_TMF, &ireq->flags)) {
Dan Williamsf1f52e72011-05-10 02:28:45 -0700636 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
Dan Williams6f231dd2011-07-02 22:56:22 -0700637
Dan Williamsf1f52e72011-05-10 02:28:45 -0700638 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
639 tmf->tmf_code == isci_tmf_sata_srst_low) {
Dan Williams5076a1a2011-06-27 14:57:03 -0700640 scu_stp_raw_request_construct_task_context(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700641 } else {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700642 dev_err(&ireq->owning_controller->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700643 "%s: Request 0x%p received un-handled SAT "
644 "Protocol 0x%x.\n",
Dan Williams5076a1a2011-06-27 14:57:03 -0700645 __func__, ireq, tmf->tmf_code);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700646
647 return SCI_FAILURE;
648 }
Dan Williams6f231dd2011-07-02 22:56:22 -0700649 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700650
Dan Williams5dec6f42011-05-10 02:28:49 -0700651 if (status != SCI_SUCCESS)
652 return status;
Dan Williams5076a1a2011-06-27 14:57:03 -0700653 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700654
655 return status;
Dan Williams6f231dd2011-07-02 22:56:22 -0700656}
657
658/**
Dan Williamsf1f52e72011-05-10 02:28:45 -0700659 * sci_req_tx_bytes - bytes transferred when reply underruns request
Dan Williamsb50102d2011-09-30 18:52:19 -0700660 * @ireq: request that was terminated early
Dan Williams6f231dd2011-07-02 22:56:22 -0700661 */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700662#define SCU_TASK_CONTEXT_SRAM 0x200000
Dan Williams5076a1a2011-06-27 14:57:03 -0700663static u32 sci_req_tx_bytes(struct isci_request *ireq)
Dan Williams6f231dd2011-07-02 22:56:22 -0700664{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700665 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700666 u32 ret_val = 0;
Dan Williams6f231dd2011-07-02 22:56:22 -0700667
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700668 if (readl(&ihost->smu_registers->address_modifier) == 0) {
669 void __iomem *scu_reg_base = ihost->scu_registers;
Dan Williams6f231dd2011-07-02 22:56:22 -0700670
Dan Williamsf1f52e72011-05-10 02:28:45 -0700671 /* get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where
672 * BAR1 is the scu_registers
673 * 0x20002C = 0x200000 + 0x2c
674 * = start of task context SRAM + offset of (type.ssp.data_offset)
Dan Williams89a73012011-06-30 19:14:33 -0700675 * TCi is the io_tag of struct sci_request
Dan Williams67ea8382011-05-08 11:47:15 -0700676 */
Dan Williamsf1f52e72011-05-10 02:28:45 -0700677 ret_val = readl(scu_reg_base +
678 (SCU_TASK_CONTEXT_SRAM + offsetof(struct scu_task_context, type.ssp.data_offset)) +
Dan Williams5076a1a2011-06-27 14:57:03 -0700679 ((sizeof(struct scu_task_context)) * ISCI_TAG_TCI(ireq->io_tag)));
Dan Williams67ea8382011-05-08 11:47:15 -0700680 }
Dan Williams6f231dd2011-07-02 22:56:22 -0700681
Dan Williamsf1f52e72011-05-10 02:28:45 -0700682 return ret_val;
Dan Williams6f231dd2011-07-02 22:56:22 -0700683}
684
Dan Williams89a73012011-06-30 19:14:33 -0700685enum sci_status sci_request_start(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700686{
Piotr Sawickif4636a72011-05-10 23:50:32 +0000687 enum sci_base_request_states state;
Dan Williams5076a1a2011-06-27 14:57:03 -0700688 struct scu_task_context *tc = ireq->tc;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700689 struct isci_host *ihost = ireq->owning_controller;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000690
Dan Williams5076a1a2011-06-27 14:57:03 -0700691 state = ireq->sm.current_state_id;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000692 if (state != SCI_REQ_CONSTRUCTED) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700693 dev_warn(&ihost->pdev->dev,
Piotr Sawickif4636a72011-05-10 23:50:32 +0000694 "%s: SCIC IO Request requested to start while in wrong "
695 "state %d\n", __func__, state);
696 return SCI_FAILURE_INVALID_STATE;
697 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700698
Dan Williams5076a1a2011-06-27 14:57:03 -0700699 tc->task_index = ISCI_TAG_TCI(ireq->io_tag);
Dan Williamsf1f52e72011-05-10 02:28:45 -0700700
Dan Williams312e0c22011-06-28 13:47:09 -0700701 switch (tc->protocol_type) {
702 case SCU_TASK_CONTEXT_PROTOCOL_SMP:
703 case SCU_TASK_CONTEXT_PROTOCOL_SSP:
704 /* SSP/SMP Frame */
Dan Williams5076a1a2011-06-27 14:57:03 -0700705 tc->type.ssp.tag = ireq->io_tag;
Dan Williams312e0c22011-06-28 13:47:09 -0700706 tc->type.ssp.target_port_transfer_tag = 0xFFFF;
707 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000708
Dan Williams312e0c22011-06-28 13:47:09 -0700709 case SCU_TASK_CONTEXT_PROTOCOL_STP:
710 /* STP/SATA Frame
Dan Williams5076a1a2011-06-27 14:57:03 -0700711 * tc->type.stp.ncq_tag = ireq->ncq_tag;
Dan Williams312e0c22011-06-28 13:47:09 -0700712 */
713 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000714
Dan Williams312e0c22011-06-28 13:47:09 -0700715 case SCU_TASK_CONTEXT_PROTOCOL_NONE:
716 /* / @todo When do we set no protocol type? */
717 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000718
Dan Williams312e0c22011-06-28 13:47:09 -0700719 default:
720 /* This should never happen since we build the IO
721 * requests */
722 break;
Piotr Sawickif4636a72011-05-10 23:50:32 +0000723 }
724
Dan Williams312e0c22011-06-28 13:47:09 -0700725 /* Add to the post_context the io tag value */
Dan Williams5076a1a2011-06-27 14:57:03 -0700726 ireq->post_context |= ISCI_TAG_TCI(ireq->io_tag);
Dan Williams312e0c22011-06-28 13:47:09 -0700727
728 /* Everything is good go ahead and change state */
Dan Williams5076a1a2011-06-27 14:57:03 -0700729 sci_change_state(&ireq->sm, SCI_REQ_STARTED);
Dan Williams312e0c22011-06-28 13:47:09 -0700730
731 return SCI_SUCCESS;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700732}
733
734enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -0700735sci_io_request_terminate(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700736{
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700737 enum sci_base_request_states state;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700738
Dan Williams5076a1a2011-06-27 14:57:03 -0700739 state = ireq->sm.current_state_id;
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700740
741 switch (state) {
Edmund Nadolskie3013702011-06-02 00:10:43 +0000742 case SCI_REQ_CONSTRUCTED:
Dan Williams34a99152011-07-01 02:25:15 -0700743 ireq->scu_status = SCU_TASK_DONE_TASK_ABORT;
744 ireq->sci_status = SCI_FAILURE_IO_TERMINATED;
Dan Williams5076a1a2011-06-27 14:57:03 -0700745 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700746 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000747 case SCI_REQ_STARTED:
748 case SCI_REQ_TASK_WAIT_TC_COMP:
749 case SCI_REQ_SMP_WAIT_RESP:
750 case SCI_REQ_SMP_WAIT_TC_COMP:
751 case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
752 case SCI_REQ_STP_UDMA_WAIT_D2H:
753 case SCI_REQ_STP_NON_DATA_WAIT_H2D:
754 case SCI_REQ_STP_NON_DATA_WAIT_D2H:
755 case SCI_REQ_STP_PIO_WAIT_H2D:
756 case SCI_REQ_STP_PIO_WAIT_FRAME:
757 case SCI_REQ_STP_PIO_DATA_IN:
758 case SCI_REQ_STP_PIO_DATA_OUT:
759 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
760 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
761 case SCI_REQ_STP_SOFT_RESET_WAIT_D2H:
Dan Williamsb50102d2011-09-30 18:52:19 -0700762 case SCI_REQ_ATAPI_WAIT_H2D:
763 case SCI_REQ_ATAPI_WAIT_PIO_SETUP:
764 case SCI_REQ_ATAPI_WAIT_D2H:
765 case SCI_REQ_ATAPI_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -0700766 sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700767 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000768 case SCI_REQ_TASK_WAIT_TC_RESP:
Jeff Skirvin39ea2c52011-07-29 17:17:05 -0700769 /* The task frame was already confirmed to have been
770 * sent by the SCU HW. Since the state machine is
771 * now only waiting for the task response itself,
772 * abort the request and complete it immediately
773 * and don't wait for the task response.
774 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700775 sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
776 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700777 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000778 case SCI_REQ_ABORTING:
Jeff Skirvin39ea2c52011-07-29 17:17:05 -0700779 /* If a request has a termination requested twice, return
780 * a failure indication, since HW confirmation of the first
781 * abort is still outstanding.
782 */
Edmund Nadolskie3013702011-06-02 00:10:43 +0000783 case SCI_REQ_COMPLETED:
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700784 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700785 dev_warn(&ireq->owning_controller->pdev->dev,
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700786 "%s: SCIC IO Request requested to abort while in wrong "
787 "state %d\n",
788 __func__,
Dan Williams5076a1a2011-06-27 14:57:03 -0700789 ireq->sm.current_state_id);
Dan Williamsf00e6ba2011-05-10 02:39:11 -0700790 break;
791 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700792
793 return SCI_FAILURE_INVALID_STATE;
794}
795
Dan Williams89a73012011-06-30 19:14:33 -0700796enum sci_status sci_request_complete(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700797{
Dan Williams79e2b6b2011-05-11 08:29:56 -0700798 enum sci_base_request_states state;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700799 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700800
Dan Williams5076a1a2011-06-27 14:57:03 -0700801 state = ireq->sm.current_state_id;
Edmund Nadolskie3013702011-06-02 00:10:43 +0000802 if (WARN_ONCE(state != SCI_REQ_COMPLETED,
Dan Williams79e2b6b2011-05-11 08:29:56 -0700803 "isci: request completion from wrong state (%d)\n", state))
804 return SCI_FAILURE_INVALID_STATE;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700805
Dan Williams5076a1a2011-06-27 14:57:03 -0700806 if (ireq->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX)
Dan Williams89a73012011-06-30 19:14:33 -0700807 sci_controller_release_frame(ihost,
Dan Williams5076a1a2011-06-27 14:57:03 -0700808 ireq->saved_rx_frame_index);
Dan Williams79e2b6b2011-05-11 08:29:56 -0700809
810 /* XXX can we just stop the machine and remove the 'final' state? */
Dan Williams5076a1a2011-06-27 14:57:03 -0700811 sci_change_state(&ireq->sm, SCI_REQ_FINAL);
Dan Williams79e2b6b2011-05-11 08:29:56 -0700812 return SCI_SUCCESS;
813}
814
Dan Williams89a73012011-06-30 19:14:33 -0700815enum sci_status sci_io_request_event_handler(struct isci_request *ireq,
Dan Williams79e2b6b2011-05-11 08:29:56 -0700816 u32 event_code)
817{
818 enum sci_base_request_states state;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700819 struct isci_host *ihost = ireq->owning_controller;
Dan Williams79e2b6b2011-05-11 08:29:56 -0700820
Dan Williams5076a1a2011-06-27 14:57:03 -0700821 state = ireq->sm.current_state_id;
Dan Williams79e2b6b2011-05-11 08:29:56 -0700822
Edmund Nadolskie3013702011-06-02 00:10:43 +0000823 if (state != SCI_REQ_STP_PIO_DATA_IN) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700824 dev_warn(&ihost->pdev->dev, "%s: (%x) in wrong state %d\n",
Dan Williams79e2b6b2011-05-11 08:29:56 -0700825 __func__, event_code, state);
826
827 return SCI_FAILURE_INVALID_STATE;
828 }
829
830 switch (scu_get_event_specifier(event_code)) {
831 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
832 /* We are waiting for data and the SCU has R_ERR the data frame.
833 * Go back to waiting for the D2H Register FIS
834 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700835 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williams79e2b6b2011-05-11 08:29:56 -0700836 return SCI_SUCCESS;
837 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -0700838 dev_err(&ihost->pdev->dev,
Dan Williams79e2b6b2011-05-11 08:29:56 -0700839 "%s: pio request unexpected event %#x\n",
840 __func__, event_code);
841
842 /* TODO Should we fail the PIO request when we get an
843 * unexpected event?
844 */
845 return SCI_FAILURE;
846 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700847}
848
Dan Williamsf1f52e72011-05-10 02:28:45 -0700849/*
850 * This function copies response data for requests returning response data
851 * instead of sense data.
852 * @sci_req: This parameter specifies the request object for which to copy
853 * the response data.
854 */
Dan Williams89a73012011-06-30 19:14:33 -0700855static void sci_io_request_copy_response(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700856{
857 void *resp_buf;
858 u32 len;
859 struct ssp_response_iu *ssp_response;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700860 struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
861
Dan Williams5076a1a2011-06-27 14:57:03 -0700862 ssp_response = &ireq->ssp.rsp;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700863
864 resp_buf = &isci_tmf->resp.resp_iu;
865
866 len = min_t(u32,
867 SSP_RESP_IU_MAX_SIZE,
868 be32_to_cpu(ssp_response->response_data_len));
869
870 memcpy(resp_buf, ssp_response->resp_data, len);
871}
872
Edmund Nadolskie3013702011-06-02 00:10:43 +0000873static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -0700874request_started_state_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +0000875 u32 completion_code)
Dan Williamsf1f52e72011-05-10 02:28:45 -0700876{
Dan Williamsf1f52e72011-05-10 02:28:45 -0700877 struct ssp_response_iu *resp_iu;
Dan Williamsa7e255a2011-05-11 08:27:47 -0700878 u8 datapres;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700879
Dan Williamsa7e255a2011-05-11 08:27:47 -0700880 /* TODO: Any SDMA return code of other than 0 is bad decode 0x003C0000
881 * to determine SDMA status
Dan Williamsf1f52e72011-05-10 02:28:45 -0700882 */
883 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
884 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -0700885 ireq->scu_status = SCU_TASK_DONE_GOOD;
886 ireq->sci_status = SCI_SUCCESS;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700887 break;
Dan Williamsa7e255a2011-05-11 08:27:47 -0700888 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP): {
889 /* There are times when the SCU hardware will return an early
Dan Williamsf1f52e72011-05-10 02:28:45 -0700890 * response because the io request specified more data than is
891 * returned by the target device (mode pages, inquiry data,
892 * etc.). We must check the response stats to see if this is
893 * truly a failed request or a good request that just got
894 * completed early.
895 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700896 struct ssp_response_iu *resp = &ireq->ssp.rsp;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700897 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
898
Dan Williams5076a1a2011-06-27 14:57:03 -0700899 sci_swab32_cpy(&ireq->ssp.rsp,
900 &ireq->ssp.rsp,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700901 word_cnt);
902
903 if (resp->status == 0) {
Dan Williams34a99152011-07-01 02:25:15 -0700904 ireq->scu_status = SCU_TASK_DONE_GOOD;
905 ireq->sci_status = SCI_SUCCESS_IO_DONE_EARLY;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700906 } else {
Dan Williams34a99152011-07-01 02:25:15 -0700907 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
908 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700909 }
Dan Williamsa7e255a2011-05-11 08:27:47 -0700910 break;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700911 }
Dan Williamsa7e255a2011-05-11 08:27:47 -0700912 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE): {
Dan Williamsf1f52e72011-05-10 02:28:45 -0700913 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
914
Dan Williams5076a1a2011-06-27 14:57:03 -0700915 sci_swab32_cpy(&ireq->ssp.rsp,
916 &ireq->ssp.rsp,
Dan Williamsf1f52e72011-05-10 02:28:45 -0700917 word_cnt);
918
Dan Williams34a99152011-07-01 02:25:15 -0700919 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
920 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700921 break;
922 }
923
924 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
Dan Williamsa7e255a2011-05-11 08:27:47 -0700925 /* TODO With TASK_DONE_RESP_LEN_ERR is the response frame
Dan Williamsf1f52e72011-05-10 02:28:45 -0700926 * guaranteed to be received before this completion status is
927 * posted?
928 */
Dan Williams5076a1a2011-06-27 14:57:03 -0700929 resp_iu = &ireq->ssp.rsp;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700930 datapres = resp_iu->datapres;
931
Dan Williamsa7e255a2011-05-11 08:27:47 -0700932 if (datapres == 1 || datapres == 2) {
Dan Williams34a99152011-07-01 02:25:15 -0700933 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
934 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
935 } else {
936 ireq->scu_status = SCU_TASK_DONE_GOOD;
937 ireq->sci_status = SCI_SUCCESS;
938 }
Dan Williamsf1f52e72011-05-10 02:28:45 -0700939 break;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700940 /* only stp device gets suspended. */
941 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
942 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR):
943 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR):
944 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR):
945 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR):
946 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN):
947 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
948 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP):
949 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS):
950 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
951 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR):
Dan Williams5076a1a2011-06-27 14:57:03 -0700952 if (ireq->protocol == SCIC_STP_PROTOCOL) {
Dan Williams34a99152011-07-01 02:25:15 -0700953 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
954 SCU_COMPLETION_TL_STATUS_SHIFT;
955 ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700956 } else {
Dan Williams34a99152011-07-01 02:25:15 -0700957 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
958 SCU_COMPLETION_TL_STATUS_SHIFT;
959 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700960 }
961 break;
962
963 /* both stp/ssp device gets suspended */
964 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR):
965 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION):
966 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1):
967 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2):
968 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3):
969 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION):
970 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION):
971 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY):
972 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED):
973 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
Dan Williams34a99152011-07-01 02:25:15 -0700974 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
975 SCU_COMPLETION_TL_STATUS_SHIFT;
976 ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700977 break;
978
979 /* neither ssp nor stp gets suspended. */
980 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR):
981 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR):
982 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR):
983 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR):
984 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR):
985 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA):
986 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
987 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
988 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
989 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
990 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA):
991 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL):
992 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV):
993 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV):
994 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND):
995 default:
Dan Williams34a99152011-07-01 02:25:15 -0700996 ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
997 SCU_COMPLETION_TL_STATUS_SHIFT;
998 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williamsf1f52e72011-05-10 02:28:45 -0700999 break;
1000 }
1001
1002 /*
1003 * TODO: This is probably wrong for ACK/NAK timeout conditions
1004 */
1005
1006 /* In all cases we will treat this as the completion of the IO req. */
Dan Williams5076a1a2011-06-27 14:57:03 -07001007 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf1f52e72011-05-10 02:28:45 -07001008 return SCI_SUCCESS;
1009}
1010
Edmund Nadolskie3013702011-06-02 00:10:43 +00001011static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001012request_aborting_state_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001013 u32 completion_code)
Dan Williamsf1f52e72011-05-10 02:28:45 -07001014{
1015 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1016 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
1017 case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT):
Dan Williams34a99152011-07-01 02:25:15 -07001018 ireq->scu_status = SCU_TASK_DONE_TASK_ABORT;
1019 ireq->sci_status = SCI_FAILURE_IO_TERMINATED;
Dan Williams5076a1a2011-06-27 14:57:03 -07001020 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf1f52e72011-05-10 02:28:45 -07001021 break;
1022
1023 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001024 /* Unless we get some strange error wait for the task abort to complete
1025 * TODO: Should there be a state change for this completion?
1026 */
Dan Williamsf1f52e72011-05-10 02:28:45 -07001027 break;
1028 }
1029
1030 return SCI_SUCCESS;
1031}
1032
Dan Williams5076a1a2011-06-27 14:57:03 -07001033static enum sci_status ssp_task_request_await_tc_event(struct isci_request *ireq,
Dan Williamsa7e255a2011-05-11 08:27:47 -07001034 u32 completion_code)
Dan Williamsf1393032011-05-10 02:28:47 -07001035{
1036 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1037 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001038 ireq->scu_status = SCU_TASK_DONE_GOOD;
1039 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001040 sci_change_state(&ireq->sm, SCI_REQ_TASK_WAIT_TC_RESP);
Dan Williamsf1393032011-05-10 02:28:47 -07001041 break;
Dan Williamsf1393032011-05-10 02:28:47 -07001042 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001043 /* Currently, the decision is to simply allow the task request
1044 * to timeout if the task IU wasn't received successfully.
1045 * There is a potential for receiving multiple task responses if
1046 * we decide to send the task IU again.
1047 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001048 dev_warn(&ireq->owning_controller->pdev->dev,
Dan Williamsf1393032011-05-10 02:28:47 -07001049 "%s: TaskRequest:0x%p CompletionCode:%x - "
Dan Williams5076a1a2011-06-27 14:57:03 -07001050 "ACK/NAK timeout\n", __func__, ireq,
Dan Williamsf1393032011-05-10 02:28:47 -07001051 completion_code);
1052
Dan Williams5076a1a2011-06-27 14:57:03 -07001053 sci_change_state(&ireq->sm, SCI_REQ_TASK_WAIT_TC_RESP);
Dan Williamsf1393032011-05-10 02:28:47 -07001054 break;
Dan Williamsf1393032011-05-10 02:28:47 -07001055 default:
Edmund Nadolskie3013702011-06-02 00:10:43 +00001056 /*
1057 * All other completion status cause the IO to be complete.
1058 * If a NAK was received, then it is up to the user to retry
1059 * the request.
Dan Williamsa7e255a2011-05-11 08:27:47 -07001060 */
Dan Williams34a99152011-07-01 02:25:15 -07001061 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1062 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001063 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsf1393032011-05-10 02:28:47 -07001064 break;
1065 }
1066
1067 return SCI_SUCCESS;
1068}
1069
Edmund Nadolskie3013702011-06-02 00:10:43 +00001070static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001071smp_request_await_response_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001072 u32 completion_code)
Dan Williamsc72086e2011-05-10 02:28:48 -07001073{
1074 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1075 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001076 /* In the AWAIT RESPONSE state, any TC completion is
1077 * unexpected. but if the TC has success status, we
1078 * complete the IO anyway.
1079 */
Dan Williams34a99152011-07-01 02:25:15 -07001080 ireq->scu_status = SCU_TASK_DONE_GOOD;
1081 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001082 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001083 break;
Dan Williamsc72086e2011-05-10 02:28:48 -07001084 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
1085 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
1086 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
1087 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
Dan Williamsa7e255a2011-05-11 08:27:47 -07001088 /* These status has been seen in a specific LSI
1089 * expander, which sometimes is not able to send smp
1090 * response within 2 ms. This causes our hardware break
1091 * the connection and set TC completion with one of
1092 * these SMP_XXX_XX_ERR status. For these type of error,
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001093 * we ask ihost user to retry the request.
Dan Williamsa7e255a2011-05-11 08:27:47 -07001094 */
Dan Williams34a99152011-07-01 02:25:15 -07001095 ireq->scu_status = SCU_TASK_DONE_SMP_RESP_TO_ERR;
1096 ireq->sci_status = SCI_FAILURE_RETRY_REQUIRED;
Dan Williams5076a1a2011-06-27 14:57:03 -07001097 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001098 break;
Dan Williamsc72086e2011-05-10 02:28:48 -07001099 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001100 /* All other completion status cause the IO to be complete. If a NAK
1101 * was received, then it is up to the user to retry the request
1102 */
Dan Williams34a99152011-07-01 02:25:15 -07001103 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1104 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001105 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001106 break;
1107 }
1108
1109 return SCI_SUCCESS;
1110}
1111
Edmund Nadolskie3013702011-06-02 00:10:43 +00001112static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001113smp_request_await_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001114 u32 completion_code)
Dan Williamsc72086e2011-05-10 02:28:48 -07001115{
1116 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1117 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001118 ireq->scu_status = SCU_TASK_DONE_GOOD;
1119 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001120 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001121 break;
Dan Williamsc72086e2011-05-10 02:28:48 -07001122 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001123 /* All other completion status cause the IO to be
1124 * complete. If a NAK was received, then it is up to
1125 * the user to retry the request.
1126 */
Dan Williams34a99152011-07-01 02:25:15 -07001127 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1128 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001129 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsc72086e2011-05-10 02:28:48 -07001130 break;
1131 }
1132
1133 return SCI_SUCCESS;
1134}
1135
Dan Williamsba7cb222011-06-27 11:56:41 -07001136static struct scu_sgl_element *pio_sgl_next(struct isci_stp_request *stp_req)
Dan Williams5dec6f42011-05-10 02:28:49 -07001137{
Dan Williams312e0c22011-06-28 13:47:09 -07001138 struct scu_sgl_element *sgl;
1139 struct scu_sgl_element_pair *sgl_pair;
Dan Williams5076a1a2011-06-27 14:57:03 -07001140 struct isci_request *ireq = to_ireq(stp_req);
Dan Williamsba7cb222011-06-27 11:56:41 -07001141 struct isci_stp_pio_sgl *pio_sgl = &stp_req->sgl;
Dan Williams5dec6f42011-05-10 02:28:49 -07001142
Dan Williams5076a1a2011-06-27 14:57:03 -07001143 sgl_pair = to_sgl_element_pair(ireq, pio_sgl->index);
Dan Williams312e0c22011-06-28 13:47:09 -07001144 if (!sgl_pair)
1145 sgl = NULL;
Dan Williamsba7cb222011-06-27 11:56:41 -07001146 else if (pio_sgl->set == SCU_SGL_ELEMENT_PAIR_A) {
Dan Williams312e0c22011-06-28 13:47:09 -07001147 if (sgl_pair->B.address_lower == 0 &&
1148 sgl_pair->B.address_upper == 0) {
1149 sgl = NULL;
Dan Williams5dec6f42011-05-10 02:28:49 -07001150 } else {
Dan Williamsba7cb222011-06-27 11:56:41 -07001151 pio_sgl->set = SCU_SGL_ELEMENT_PAIR_B;
Dan Williams312e0c22011-06-28 13:47:09 -07001152 sgl = &sgl_pair->B;
Dan Williams5dec6f42011-05-10 02:28:49 -07001153 }
1154 } else {
Dan Williams312e0c22011-06-28 13:47:09 -07001155 if (sgl_pair->next_pair_lower == 0 &&
1156 sgl_pair->next_pair_upper == 0) {
1157 sgl = NULL;
Dan Williams5dec6f42011-05-10 02:28:49 -07001158 } else {
Dan Williamsba7cb222011-06-27 11:56:41 -07001159 pio_sgl->index++;
1160 pio_sgl->set = SCU_SGL_ELEMENT_PAIR_A;
Dan Williams5076a1a2011-06-27 14:57:03 -07001161 sgl_pair = to_sgl_element_pair(ireq, pio_sgl->index);
Dan Williams312e0c22011-06-28 13:47:09 -07001162 sgl = &sgl_pair->A;
Dan Williams5dec6f42011-05-10 02:28:49 -07001163 }
1164 }
1165
Dan Williams312e0c22011-06-28 13:47:09 -07001166 return sgl;
Dan Williams5dec6f42011-05-10 02:28:49 -07001167}
1168
Edmund Nadolskie3013702011-06-02 00:10:43 +00001169static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001170stp_request_non_data_await_h2d_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001171 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001172{
1173 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1174 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001175 ireq->scu_status = SCU_TASK_DONE_GOOD;
1176 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001177 sci_change_state(&ireq->sm, SCI_REQ_STP_NON_DATA_WAIT_D2H);
Dan Williams5dec6f42011-05-10 02:28:49 -07001178 break;
1179
1180 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001181 /* All other completion status cause the IO to be
1182 * complete. If a NAK was received, then it is up to
1183 * the user to retry the request.
1184 */
Dan Williams34a99152011-07-01 02:25:15 -07001185 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1186 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001187 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001188 break;
1189 }
1190
1191 return SCI_SUCCESS;
1192}
1193
Dan Williams5dec6f42011-05-10 02:28:49 -07001194#define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */
1195
1196/* transmit DATA_FIS from (current sgl + offset) for input
1197 * parameter length. current sgl and offset is alreay stored in the IO request
1198 */
Dan Williams89a73012011-06-30 19:14:33 -07001199static enum sci_status sci_stp_request_pio_data_out_trasmit_data_frame(
Dan Williams5076a1a2011-06-27 14:57:03 -07001200 struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -07001201 u32 length)
1202{
Dan Williams5076a1a2011-06-27 14:57:03 -07001203 struct isci_stp_request *stp_req = &ireq->stp.req;
1204 struct scu_task_context *task_context = ireq->tc;
Dan Williams312e0c22011-06-28 13:47:09 -07001205 struct scu_sgl_element_pair *sgl_pair;
Dan Williams5dec6f42011-05-10 02:28:49 -07001206 struct scu_sgl_element *current_sgl;
1207
1208 /* Recycle the TC and reconstruct it for sending out DATA FIS containing
1209 * for the data from current_sgl+offset for the input length
1210 */
Dan Williams5076a1a2011-06-27 14:57:03 -07001211 sgl_pair = to_sgl_element_pair(ireq, stp_req->sgl.index);
Dan Williamsba7cb222011-06-27 11:56:41 -07001212 if (stp_req->sgl.set == SCU_SGL_ELEMENT_PAIR_A)
Dan Williams312e0c22011-06-28 13:47:09 -07001213 current_sgl = &sgl_pair->A;
Dan Williams5dec6f42011-05-10 02:28:49 -07001214 else
Dan Williams312e0c22011-06-28 13:47:09 -07001215 current_sgl = &sgl_pair->B;
Dan Williams5dec6f42011-05-10 02:28:49 -07001216
1217 /* update the TC */
1218 task_context->command_iu_upper = current_sgl->address_upper;
1219 task_context->command_iu_lower = current_sgl->address_lower;
1220 task_context->transfer_length_bytes = length;
1221 task_context->type.stp.fis_type = FIS_DATA;
1222
1223 /* send the new TC out. */
Dan Williams89a73012011-06-30 19:14:33 -07001224 return sci_controller_continue_io(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -07001225}
1226
Dan Williams89a73012011-06-30 19:14:33 -07001227static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_request *ireq)
Dan Williams5dec6f42011-05-10 02:28:49 -07001228{
Dan Williams5076a1a2011-06-27 14:57:03 -07001229 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williams312e0c22011-06-28 13:47:09 -07001230 struct scu_sgl_element_pair *sgl_pair;
Dan Williamsb50102d2011-09-30 18:52:19 -07001231 enum sci_status status = SCI_SUCCESS;
Dan Williamsba7cb222011-06-27 11:56:41 -07001232 struct scu_sgl_element *sgl;
Dan Williamsba7cb222011-06-27 11:56:41 -07001233 u32 offset;
1234 u32 len = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07001235
Dan Williamsba7cb222011-06-27 11:56:41 -07001236 offset = stp_req->sgl.offset;
Dan Williams5076a1a2011-06-27 14:57:03 -07001237 sgl_pair = to_sgl_element_pair(ireq, stp_req->sgl.index);
Dan Williams312e0c22011-06-28 13:47:09 -07001238 if (WARN_ONCE(!sgl_pair, "%s: null sgl element", __func__))
1239 return SCI_FAILURE;
Dan Williams5dec6f42011-05-10 02:28:49 -07001240
Dan Williamsba7cb222011-06-27 11:56:41 -07001241 if (stp_req->sgl.set == SCU_SGL_ELEMENT_PAIR_A) {
1242 sgl = &sgl_pair->A;
1243 len = sgl_pair->A.length - offset;
Dan Williams5dec6f42011-05-10 02:28:49 -07001244 } else {
Dan Williamsba7cb222011-06-27 11:56:41 -07001245 sgl = &sgl_pair->B;
1246 len = sgl_pair->B.length - offset;
Dan Williams5dec6f42011-05-10 02:28:49 -07001247 }
1248
Dan Williamsba7cb222011-06-27 11:56:41 -07001249 if (stp_req->pio_len == 0)
1250 return SCI_SUCCESS;
Dan Williams5dec6f42011-05-10 02:28:49 -07001251
Dan Williamsba7cb222011-06-27 11:56:41 -07001252 if (stp_req->pio_len >= len) {
Dan Williams89a73012011-06-30 19:14:33 -07001253 status = sci_stp_request_pio_data_out_trasmit_data_frame(ireq, len);
Dan Williamsba7cb222011-06-27 11:56:41 -07001254 if (status != SCI_SUCCESS)
1255 return status;
1256 stp_req->pio_len -= len;
Dan Williams5dec6f42011-05-10 02:28:49 -07001257
Dan Williamsba7cb222011-06-27 11:56:41 -07001258 /* update the current sgl, offset and save for future */
1259 sgl = pio_sgl_next(stp_req);
1260 offset = 0;
1261 } else if (stp_req->pio_len < len) {
Dan Williams89a73012011-06-30 19:14:33 -07001262 sci_stp_request_pio_data_out_trasmit_data_frame(ireq, stp_req->pio_len);
Dan Williamsba7cb222011-06-27 11:56:41 -07001263
1264 /* Sgl offset will be adjusted and saved for future */
1265 offset += stp_req->pio_len;
1266 sgl->address_lower += stp_req->pio_len;
1267 stp_req->pio_len = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07001268 }
1269
Dan Williamsba7cb222011-06-27 11:56:41 -07001270 stp_req->sgl.offset = offset;
Dan Williams5dec6f42011-05-10 02:28:49 -07001271
1272 return status;
1273}
1274
1275/**
1276 *
1277 * @stp_request: The request that is used for the SGL processing.
1278 * @data_buffer: The buffer of data to be copied.
1279 * @length: The length of the data transfer.
1280 *
1281 * Copy the data from the buffer for the length specified to the IO reqeust SGL
1282 * specified data region. enum sci_status
1283 */
1284static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07001285sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req,
Dan Williamsb50102d2011-09-30 18:52:19 -07001286 u8 *data_buf, u32 len)
Dan Williams5dec6f42011-05-10 02:28:49 -07001287{
Dan Williams5dec6f42011-05-10 02:28:49 -07001288 struct isci_request *ireq;
1289 u8 *src_addr;
1290 int copy_len;
1291 struct sas_task *task;
1292 struct scatterlist *sg;
1293 void *kaddr;
1294 int total_len = len;
1295
Dan Williams5076a1a2011-06-27 14:57:03 -07001296 ireq = to_ireq(stp_req);
Dan Williams5dec6f42011-05-10 02:28:49 -07001297 task = isci_request_access_task(ireq);
1298 src_addr = data_buf;
1299
1300 if (task->num_scatter > 0) {
1301 sg = task->scatter;
1302
1303 while (total_len > 0) {
1304 struct page *page = sg_page(sg);
1305
1306 copy_len = min_t(int, total_len, sg_dma_len(sg));
1307 kaddr = kmap_atomic(page, KM_IRQ0);
1308 memcpy(kaddr + sg->offset, src_addr, copy_len);
1309 kunmap_atomic(kaddr, KM_IRQ0);
1310 total_len -= copy_len;
1311 src_addr += copy_len;
1312 sg = sg_next(sg);
1313 }
1314 } else {
1315 BUG_ON(task->total_xfer_len < total_len);
1316 memcpy(task->scatter, src_addr, total_len);
1317 }
1318
1319 return SCI_SUCCESS;
1320}
1321
1322/**
1323 *
1324 * @sci_req: The PIO DATA IN request that is to receive the data.
1325 * @data_buffer: The buffer to copy from.
1326 *
1327 * Copy the data buffer to the io request data region. enum sci_status
1328 */
Dan Williams89a73012011-06-30 19:14:33 -07001329static enum sci_status sci_stp_request_pio_data_in_copy_data(
Dan Williamsba7cb222011-06-27 11:56:41 -07001330 struct isci_stp_request *stp_req,
Dan Williams5dec6f42011-05-10 02:28:49 -07001331 u8 *data_buffer)
1332{
1333 enum sci_status status;
1334
1335 /*
1336 * If there is less than 1K remaining in the transfer request
1337 * copy just the data for the transfer */
Dan Williamsba7cb222011-06-27 11:56:41 -07001338 if (stp_req->pio_len < SCU_MAX_FRAME_BUFFER_SIZE) {
Dan Williams89a73012011-06-30 19:14:33 -07001339 status = sci_stp_request_pio_data_in_copy_data_buffer(
Dan Williamsba7cb222011-06-27 11:56:41 -07001340 stp_req, data_buffer, stp_req->pio_len);
Dan Williams5dec6f42011-05-10 02:28:49 -07001341
1342 if (status == SCI_SUCCESS)
Dan Williamsba7cb222011-06-27 11:56:41 -07001343 stp_req->pio_len = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07001344 } else {
1345 /* We are transfering the whole frame so copy */
Dan Williams89a73012011-06-30 19:14:33 -07001346 status = sci_stp_request_pio_data_in_copy_data_buffer(
Dan Williamsba7cb222011-06-27 11:56:41 -07001347 stp_req, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
Dan Williams5dec6f42011-05-10 02:28:49 -07001348
1349 if (status == SCI_SUCCESS)
Dan Williamsba7cb222011-06-27 11:56:41 -07001350 stp_req->pio_len -= SCU_MAX_FRAME_BUFFER_SIZE;
Dan Williams5dec6f42011-05-10 02:28:49 -07001351 }
1352
1353 return status;
1354}
1355
Edmund Nadolskie3013702011-06-02 00:10:43 +00001356static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001357stp_request_pio_await_h2d_completion_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001358 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001359{
1360 enum sci_status status = SCI_SUCCESS;
1361
1362 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1363 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07001364 ireq->scu_status = SCU_TASK_DONE_GOOD;
1365 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001366 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williams5dec6f42011-05-10 02:28:49 -07001367 break;
1368
1369 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07001370 /* All other completion status cause the IO to be
1371 * complete. If a NAK was received, then it is up to
1372 * the user to retry the request.
1373 */
Dan Williams34a99152011-07-01 02:25:15 -07001374 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1375 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001376 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001377 break;
1378 }
1379
1380 return status;
1381}
1382
Edmund Nadolskie3013702011-06-02 00:10:43 +00001383static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07001384pio_data_out_tx_done_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001385 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07001386{
1387 enum sci_status status = SCI_SUCCESS;
1388 bool all_frames_transferred = false;
Dan Williams5076a1a2011-06-27 14:57:03 -07001389 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williams5dec6f42011-05-10 02:28:49 -07001390
1391 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1392 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1393 /* Transmit data */
Dan Williamsba7cb222011-06-27 11:56:41 -07001394 if (stp_req->pio_len != 0) {
Dan Williams89a73012011-06-30 19:14:33 -07001395 status = sci_stp_request_pio_data_out_transmit_data(ireq);
Dan Williams5dec6f42011-05-10 02:28:49 -07001396 if (status == SCI_SUCCESS) {
Dan Williamsba7cb222011-06-27 11:56:41 -07001397 if (stp_req->pio_len == 0)
Dan Williams5dec6f42011-05-10 02:28:49 -07001398 all_frames_transferred = true;
1399 }
Dan Williamsba7cb222011-06-27 11:56:41 -07001400 } else if (stp_req->pio_len == 0) {
Dan Williams5dec6f42011-05-10 02:28:49 -07001401 /*
1402 * this will happen if the all data is written at the
1403 * first time after the pio setup fis is received
1404 */
1405 all_frames_transferred = true;
1406 }
1407
1408 /* all data transferred. */
1409 if (all_frames_transferred) {
1410 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001411 * Change the state to SCI_REQ_STP_PIO_DATA_IN
Dan Williams5dec6f42011-05-10 02:28:49 -07001412 * and wait for PIO_SETUP fis / or D2H REg fis. */
Dan Williams5076a1a2011-06-27 14:57:03 -07001413 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williams5dec6f42011-05-10 02:28:49 -07001414 }
1415 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001416
Dan Williams5dec6f42011-05-10 02:28:49 -07001417 default:
1418 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001419 * All other completion status cause the IO to be complete.
1420 * If a NAK was received, then it is up to the user to retry
1421 * the request.
1422 */
Dan Williams34a99152011-07-01 02:25:15 -07001423 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
1424 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001425 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07001426 break;
1427 }
1428
1429 return status;
1430}
1431
Dan Williams89a73012011-06-30 19:14:33 -07001432static enum sci_status sci_stp_request_udma_general_frame_handler(struct isci_request *ireq,
Dan Williams5dec6f42011-05-10 02:28:49 -07001433 u32 frame_index)
1434{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001435 struct isci_host *ihost = ireq->owning_controller;
Dan Williams5dec6f42011-05-10 02:28:49 -07001436 struct dev_to_host_fis *frame_header;
1437 enum sci_status status;
1438 u32 *frame_buffer;
1439
Dan Williams89a73012011-06-30 19:14:33 -07001440 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williams5dec6f42011-05-10 02:28:49 -07001441 frame_index,
1442 (void **)&frame_header);
1443
1444 if ((status == SCI_SUCCESS) &&
1445 (frame_header->fis_type == FIS_REGD2H)) {
Dan Williams89a73012011-06-30 19:14:33 -07001446 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williams5dec6f42011-05-10 02:28:49 -07001447 frame_index,
1448 (void **)&frame_buffer);
1449
Dan Williams89a73012011-06-30 19:14:33 -07001450 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williams5dec6f42011-05-10 02:28:49 -07001451 frame_header,
1452 frame_buffer);
1453 }
1454
Dan Williams89a73012011-06-30 19:14:33 -07001455 sci_controller_release_frame(ihost, frame_index);
Dan Williams5dec6f42011-05-10 02:28:49 -07001456
1457 return status;
1458}
1459
Dan Williamsb50102d2011-09-30 18:52:19 -07001460static enum sci_status process_unsolicited_fis(struct isci_request *ireq,
1461 u32 frame_index)
1462{
1463 struct isci_host *ihost = ireq->owning_controller;
1464 enum sci_status status;
1465 struct dev_to_host_fis *frame_header;
1466 u32 *frame_buffer;
1467
1468 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
1469 frame_index,
1470 (void **)&frame_header);
1471
1472 if (status != SCI_SUCCESS)
1473 return status;
1474
1475 if (frame_header->fis_type != FIS_REGD2H) {
1476 dev_err(&ireq->isci_host->pdev->dev,
1477 "%s ERROR: invalid fis type 0x%X\n",
1478 __func__, frame_header->fis_type);
1479 return SCI_FAILURE;
1480 }
1481
1482 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
1483 frame_index,
1484 (void **)&frame_buffer);
1485
1486 sci_controller_copy_sata_response(&ireq->stp.rsp,
1487 (u32 *)frame_header,
1488 frame_buffer);
1489
1490 /* Frame has been decoded return it to the controller */
1491 sci_controller_release_frame(ihost, frame_index);
1492
1493 return status;
1494}
1495
1496static enum sci_status atapi_d2h_reg_frame_handler(struct isci_request *ireq,
1497 u32 frame_index)
1498{
1499 struct sas_task *task = isci_request_access_task(ireq);
1500 enum sci_status status;
1501
1502 status = process_unsolicited_fis(ireq, frame_index);
1503
1504 if (status == SCI_SUCCESS) {
1505 if (ireq->stp.rsp.status & ATA_ERR)
1506 status = SCI_IO_FAILURE_RESPONSE_VALID;
1507 } else {
1508 status = SCI_IO_FAILURE_RESPONSE_VALID;
1509 }
1510
1511 if (status != SCI_SUCCESS) {
1512 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1513 ireq->sci_status = status;
1514 } else {
1515 ireq->scu_status = SCU_TASK_DONE_GOOD;
1516 ireq->sci_status = SCI_SUCCESS;
1517 }
1518
1519 /* the d2h ufi is the end of non-data commands */
1520 if (task->data_dir == DMA_NONE)
1521 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
1522
1523 return status;
1524}
1525
1526static void scu_atapi_reconstruct_raw_frame_task_context(struct isci_request *ireq)
1527{
1528 struct ata_device *dev = sas_to_ata_dev(ireq->target_device->domain_dev);
1529 void *atapi_cdb = ireq->ttype_ptr.io_task_ptr->ata_task.atapi_packet;
1530 struct scu_task_context *task_context = ireq->tc;
1531
1532 /* fill in the SCU Task Context for a DATA fis containing CDB in Raw Frame
1533 * type. The TC for previous Packet fis was already there, we only need to
1534 * change the H2D fis content.
1535 */
1536 memset(&ireq->stp.cmd, 0, sizeof(struct host_to_dev_fis));
1537 memcpy(((u8 *)&ireq->stp.cmd + sizeof(u32)), atapi_cdb, ATAPI_CDB_LEN);
1538 memset(&(task_context->type.stp), 0, sizeof(struct stp_task_context));
1539 task_context->type.stp.fis_type = FIS_DATA;
1540 task_context->transfer_length_bytes = dev->cdb_len;
1541}
1542
1543static void scu_atapi_construct_task_context(struct isci_request *ireq)
1544{
1545 struct ata_device *dev = sas_to_ata_dev(ireq->target_device->domain_dev);
1546 struct sas_task *task = isci_request_access_task(ireq);
1547 struct scu_task_context *task_context = ireq->tc;
1548 int cdb_len = dev->cdb_len;
1549
1550 /* reference: SSTL 1.13.4.2
1551 * task_type, sata_direction
1552 */
1553 if (task->data_dir == DMA_TO_DEVICE) {
1554 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_OUT;
1555 task_context->sata_direction = 0;
1556 } else {
1557 /* todo: for NO_DATA command, we need to send out raw frame. */
1558 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_IN;
1559 task_context->sata_direction = 1;
1560 }
1561
1562 memset(&task_context->type.stp, 0, sizeof(task_context->type.stp));
1563 task_context->type.stp.fis_type = FIS_DATA;
1564
1565 memset(&ireq->stp.cmd, 0, sizeof(ireq->stp.cmd));
1566 memcpy(&ireq->stp.cmd.lbal, task->ata_task.atapi_packet, cdb_len);
1567 task_context->ssp_command_iu_length = cdb_len / sizeof(u32);
1568
1569 /* task phase is set to TX_CMD */
1570 task_context->task_phase = 0x1;
1571
1572 /* retry counter */
1573 task_context->stp_retry_count = 0;
1574
1575 /* data transfer size. */
1576 task_context->transfer_length_bytes = task->total_xfer_len;
1577
1578 /* setup sgl */
1579 sci_request_build_sgl(ireq);
1580}
1581
Edmund Nadolskie3013702011-06-02 00:10:43 +00001582enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07001583sci_io_request_frame_handler(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001584 u32 frame_index)
Dan Williamsd1c637c32011-05-11 08:27:47 -07001585{
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001586 struct isci_host *ihost = ireq->owning_controller;
Dan Williams5076a1a2011-06-27 14:57:03 -07001587 struct isci_stp_request *stp_req = &ireq->stp.req;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001588 enum sci_base_request_states state;
1589 enum sci_status status;
1590 ssize_t word_cnt;
1591
Dan Williams5076a1a2011-06-27 14:57:03 -07001592 state = ireq->sm.current_state_id;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001593 switch (state) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001594 case SCI_REQ_STARTED: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001595 struct ssp_frame_hdr ssp_hdr;
1596 void *frame_header;
1597
Dan Williams89a73012011-06-30 19:14:33 -07001598 sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001599 frame_index,
1600 &frame_header);
1601
1602 word_cnt = sizeof(struct ssp_frame_hdr) / sizeof(u32);
1603 sci_swab32_cpy(&ssp_hdr, frame_header, word_cnt);
1604
1605 if (ssp_hdr.frame_type == SSP_RESPONSE) {
1606 struct ssp_response_iu *resp_iu;
1607 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
1608
Dan Williams89a73012011-06-30 19:14:33 -07001609 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001610 frame_index,
1611 (void **)&resp_iu);
1612
Dan Williams5076a1a2011-06-27 14:57:03 -07001613 sci_swab32_cpy(&ireq->ssp.rsp, resp_iu, word_cnt);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001614
Dan Williams5076a1a2011-06-27 14:57:03 -07001615 resp_iu = &ireq->ssp.rsp;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001616
1617 if (resp_iu->datapres == 0x01 ||
1618 resp_iu->datapres == 0x02) {
Dan Williams34a99152011-07-01 02:25:15 -07001619 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1620 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
1621 } else {
1622 ireq->scu_status = SCU_TASK_DONE_GOOD;
1623 ireq->sci_status = SCI_SUCCESS;
1624 }
Dan Williamsd1c637c32011-05-11 08:27:47 -07001625 } else {
1626 /* not a response frame, why did it get forwarded? */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001627 dev_err(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001628 "%s: SCIC IO Request 0x%p received unexpected "
Dan Williams5076a1a2011-06-27 14:57:03 -07001629 "frame %d type 0x%02x\n", __func__, ireq,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001630 frame_index, ssp_hdr.frame_type);
1631 }
1632
1633 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00001634 * In any case we are done with this frame buffer return it to
1635 * the controller
Dan Williamsd1c637c32011-05-11 08:27:47 -07001636 */
Dan Williams89a73012011-06-30 19:14:33 -07001637 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001638
1639 return SCI_SUCCESS;
1640 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001641
1642 case SCI_REQ_TASK_WAIT_TC_RESP:
Dan Williams89a73012011-06-30 19:14:33 -07001643 sci_io_request_copy_response(ireq);
Dan Williams5076a1a2011-06-27 14:57:03 -07001644 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams89a73012011-06-30 19:14:33 -07001645 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001646 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001647
1648 case SCI_REQ_SMP_WAIT_RESP: {
Dan Williams54b5e3a2011-09-28 18:35:27 -07001649 struct sas_task *task = isci_request_access_task(ireq);
1650 struct scatterlist *sg = &task->smp_task.smp_resp;
1651 void *frame_header, *kaddr;
1652 u8 *rsp;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001653
Dan Williams89a73012011-06-30 19:14:33 -07001654 sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williams54b5e3a2011-09-28 18:35:27 -07001655 frame_index,
1656 &frame_header);
1657 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
1658 rsp = kaddr + sg->offset;
1659 sci_swab32_cpy(rsp, frame_header, 1);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001660
Dan Williams54b5e3a2011-09-28 18:35:27 -07001661 if (rsp[0] == SMP_RESPONSE) {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001662 void *smp_resp;
1663
Dan Williams89a73012011-06-30 19:14:33 -07001664 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williams54b5e3a2011-09-28 18:35:27 -07001665 frame_index,
1666 &smp_resp);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001667
Dan Williams54b5e3a2011-09-28 18:35:27 -07001668 word_cnt = (sg->length/4)-1;
1669 if (word_cnt > 0)
1670 word_cnt = min_t(unsigned int, word_cnt,
1671 SCU_UNSOLICITED_FRAME_BUFFER_SIZE/4);
1672 sci_swab32_cpy(rsp + 4, smp_resp, word_cnt);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001673
Dan Williams34a99152011-07-01 02:25:15 -07001674 ireq->scu_status = SCU_TASK_DONE_GOOD;
1675 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07001676 sci_change_state(&ireq->sm, SCI_REQ_SMP_WAIT_TC_COMP);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001677 } else {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001678 /*
1679 * This was not a response frame why did it get
1680 * forwarded?
1681 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001682 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001683 "%s: SCIC SMP Request 0x%p received unexpected "
1684 "frame %d type 0x%02x\n",
1685 __func__,
Dan Williams5076a1a2011-06-27 14:57:03 -07001686 ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001687 frame_index,
Dan Williams54b5e3a2011-09-28 18:35:27 -07001688 rsp[0]);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001689
Dan Williams34a99152011-07-01 02:25:15 -07001690 ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR;
1691 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07001692 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001693 }
Dan Williams54b5e3a2011-09-28 18:35:27 -07001694 kunmap_atomic(kaddr, KM_IRQ0);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001695
Dan Williams89a73012011-06-30 19:14:33 -07001696 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001697
1698 return SCI_SUCCESS;
1699 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001700
1701 case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
Dan Williams89a73012011-06-30 19:14:33 -07001702 return sci_stp_request_udma_general_frame_handler(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001703 frame_index);
1704
1705 case SCI_REQ_STP_UDMA_WAIT_D2H:
Dan Williamsd1c637c32011-05-11 08:27:47 -07001706 /* Use the general frame handler to copy the resposne data */
Dan Williams34a99152011-07-01 02:25:15 -07001707 status = sci_stp_request_udma_general_frame_handler(ireq, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001708
1709 if (status != SCI_SUCCESS)
1710 return status;
1711
Dan Williams34a99152011-07-01 02:25:15 -07001712 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1713 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
1714 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001715 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001716
1717 case SCI_REQ_STP_NON_DATA_WAIT_D2H: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001718 struct dev_to_host_fis *frame_header;
1719 u32 *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
1734 return status;
1735 }
1736
1737 switch (frame_header->fis_type) {
1738 case FIS_REGD2H:
Dan Williams89a73012011-06-30 19:14:33 -07001739 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001740 frame_index,
1741 (void **)&frame_buffer);
1742
Dan Williams89a73012011-06-30 19:14:33 -07001743 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001744 frame_header,
1745 frame_buffer);
1746
1747 /* The command has completed with error */
Dan Williams34a99152011-07-01 02:25:15 -07001748 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1749 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001750 break;
1751
1752 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001753 dev_warn(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001754 "%s: IO Request:0x%p Frame Id:%d protocol "
1755 "violation occurred\n", __func__, stp_req,
1756 frame_index);
1757
Dan Williams34a99152011-07-01 02:25:15 -07001758 ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
1759 ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001760 break;
1761 }
1762
Dan Williams5076a1a2011-06-27 14:57:03 -07001763 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001764
1765 /* Frame has been decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001766 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001767
1768 return status;
1769 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001770
1771 case SCI_REQ_STP_PIO_WAIT_FRAME: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001772 struct sas_task *task = isci_request_access_task(ireq);
1773 struct dev_to_host_fis *frame_header;
1774 u32 *frame_buffer;
1775
Dan Williams89a73012011-06-30 19:14:33 -07001776 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001777 frame_index,
1778 (void **)&frame_header);
1779
1780 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001781 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001782 "%s: SCIC IO Request 0x%p could not get frame "
1783 "header for frame index %d, status %x\n",
Dan Williamsd1c637c32011-05-11 08:27:47 -07001784 __func__, stp_req, frame_index, status);
1785 return status;
1786 }
1787
1788 switch (frame_header->fis_type) {
1789 case FIS_PIO_SETUP:
1790 /* Get from the frame buffer the PIO Setup Data */
Dan Williams89a73012011-06-30 19:14:33 -07001791 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001792 frame_index,
1793 (void **)&frame_buffer);
1794
Edmund Nadolskie3013702011-06-02 00:10:43 +00001795 /* Get the data from the PIO Setup The SCU Hardware
1796 * returns first word in the frame_header and the rest
1797 * of the data is in the frame buffer so we need to
1798 * back up one dword
Dan Williamsd1c637c32011-05-11 08:27:47 -07001799 */
1800
1801 /* transfer_count: first 16bits in the 4th dword */
Dan Williamsba7cb222011-06-27 11:56:41 -07001802 stp_req->pio_len = frame_buffer[3] & 0xffff;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001803
Dan Williamsba7cb222011-06-27 11:56:41 -07001804 /* status: 4th byte in the 3rd dword */
1805 stp_req->status = (frame_buffer[2] >> 24) & 0xff;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001806
Dan Williams89a73012011-06-30 19:14:33 -07001807 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001808 frame_header,
1809 frame_buffer);
1810
Dan Williams5076a1a2011-06-27 14:57:03 -07001811 ireq->stp.rsp.status = stp_req->status;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001812
1813 /* The next state is dependent on whether the
1814 * request was PIO Data-in or Data out
1815 */
1816 if (task->data_dir == DMA_FROM_DEVICE) {
Dan Williams5076a1a2011-06-27 14:57:03 -07001817 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_DATA_IN);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001818 } else if (task->data_dir == DMA_TO_DEVICE) {
1819 /* Transmit data */
Dan Williams89a73012011-06-30 19:14:33 -07001820 status = sci_stp_request_pio_data_out_transmit_data(ireq);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001821 if (status != SCI_SUCCESS)
1822 break;
Dan Williams5076a1a2011-06-27 14:57:03 -07001823 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_DATA_OUT);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001824 }
1825 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001826
Dan Williamsd1c637c32011-05-11 08:27:47 -07001827 case FIS_SETDEVBITS:
Dan Williams5076a1a2011-06-27 14:57:03 -07001828 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001829 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001830
Dan Williamsd1c637c32011-05-11 08:27:47 -07001831 case FIS_REGD2H:
1832 if (frame_header->status & ATA_BUSY) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00001833 /*
1834 * Now why is the drive sending a D2H Register
1835 * FIS when it is still busy? Do nothing since
1836 * we are still in the right state.
Dan Williamsd1c637c32011-05-11 08:27:47 -07001837 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001838 dev_dbg(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001839 "%s: SCIC PIO Request 0x%p received "
1840 "D2H Register FIS with BSY status "
Edmund Nadolskie3013702011-06-02 00:10:43 +00001841 "0x%x\n",
1842 __func__,
1843 stp_req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001844 frame_header->status);
1845 break;
1846 }
1847
Dan Williams89a73012011-06-30 19:14:33 -07001848 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001849 frame_index,
1850 (void **)&frame_buffer);
1851
Dan Williams89a73012011-06-30 19:14:33 -07001852 sci_controller_copy_sata_response(&ireq->stp.req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001853 frame_header,
1854 frame_buffer);
1855
Dan Williams34a99152011-07-01 02:25:15 -07001856 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1857 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williams5076a1a2011-06-27 14:57:03 -07001858 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001859 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001860
Dan Williamsd1c637c32011-05-11 08:27:47 -07001861 default:
1862 /* FIXME: what do we do here? */
1863 break;
1864 }
1865
1866 /* Frame is decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001867 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001868
1869 return status;
1870 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001871
1872 case SCI_REQ_STP_PIO_DATA_IN: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001873 struct dev_to_host_fis *frame_header;
1874 struct sata_fis_data *frame_buffer;
1875
Dan Williams89a73012011-06-30 19:14:33 -07001876 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001877 frame_index,
1878 (void **)&frame_header);
1879
1880 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001881 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001882 "%s: SCIC IO Request 0x%p could not get frame "
1883 "header for frame index %d, status %x\n",
1884 __func__,
1885 stp_req,
1886 frame_index,
1887 status);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001888 return status;
1889 }
1890
1891 if (frame_header->fis_type != FIS_DATA) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001892 dev_err(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001893 "%s: SCIC PIO Request 0x%p received frame %d "
1894 "with fis type 0x%02x when expecting a data "
Edmund Nadolskie3013702011-06-02 00:10:43 +00001895 "fis.\n",
1896 __func__,
1897 stp_req,
1898 frame_index,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001899 frame_header->fis_type);
1900
Dan Williams34a99152011-07-01 02:25:15 -07001901 ireq->scu_status = SCU_TASK_DONE_GOOD;
1902 ireq->sci_status = SCI_FAILURE_IO_REQUIRES_SCSI_ABORT;
Dan Williams5076a1a2011-06-27 14:57:03 -07001903 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001904
1905 /* Frame is decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001906 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001907 return status;
1908 }
1909
Dan Williamsba7cb222011-06-27 11:56:41 -07001910 if (stp_req->sgl.index < 0) {
Dan Williams5076a1a2011-06-27 14:57:03 -07001911 ireq->saved_rx_frame_index = frame_index;
Dan Williamsba7cb222011-06-27 11:56:41 -07001912 stp_req->pio_len = 0;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001913 } else {
Dan Williams89a73012011-06-30 19:14:33 -07001914 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001915 frame_index,
1916 (void **)&frame_buffer);
1917
Dan Williams89a73012011-06-30 19:14:33 -07001918 status = sci_stp_request_pio_data_in_copy_data(stp_req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001919 (u8 *)frame_buffer);
1920
1921 /* Frame is decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001922 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001923 }
1924
1925 /* Check for the end of the transfer, are there more
1926 * bytes remaining for this data transfer
1927 */
Dan Williamsba7cb222011-06-27 11:56:41 -07001928 if (status != SCI_SUCCESS || stp_req->pio_len != 0)
Dan Williamsd1c637c32011-05-11 08:27:47 -07001929 return status;
1930
Dan Williamsba7cb222011-06-27 11:56:41 -07001931 if ((stp_req->status & ATA_BUSY) == 0) {
Dan Williams34a99152011-07-01 02:25:15 -07001932 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1933 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williams5076a1a2011-06-27 14:57:03 -07001934 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001935 } else {
Dan Williams5076a1a2011-06-27 14:57:03 -07001936 sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001937 }
1938 return status;
1939 }
Edmund Nadolskie3013702011-06-02 00:10:43 +00001940
1941 case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: {
Dan Williamsd1c637c32011-05-11 08:27:47 -07001942 struct dev_to_host_fis *frame_header;
1943 u32 *frame_buffer;
1944
Dan Williams89a73012011-06-30 19:14:33 -07001945 status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001946 frame_index,
1947 (void **)&frame_header);
1948 if (status != SCI_SUCCESS) {
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001949 dev_err(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00001950 "%s: SCIC IO Request 0x%p could not get frame "
1951 "header for frame index %d, status %x\n",
1952 __func__,
1953 stp_req,
1954 frame_index,
1955 status);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001956 return status;
1957 }
1958
1959 switch (frame_header->fis_type) {
1960 case FIS_REGD2H:
Dan Williams89a73012011-06-30 19:14:33 -07001961 sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001962 frame_index,
1963 (void **)&frame_buffer);
1964
Dan Williams89a73012011-06-30 19:14:33 -07001965 sci_controller_copy_sata_response(&ireq->stp.rsp,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001966 frame_header,
1967 frame_buffer);
1968
1969 /* The command has completed with error */
Dan Williams34a99152011-07-01 02:25:15 -07001970 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
1971 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001972 break;
Edmund Nadolskie3013702011-06-02 00:10:43 +00001973
Dan Williamsd1c637c32011-05-11 08:27:47 -07001974 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07001975 dev_warn(&ihost->pdev->dev,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001976 "%s: IO Request:0x%p Frame Id:%d protocol "
Edmund Nadolskie3013702011-06-02 00:10:43 +00001977 "violation occurred\n",
1978 __func__,
1979 stp_req,
Dan Williamsd1c637c32011-05-11 08:27:47 -07001980 frame_index);
1981
Dan Williams34a99152011-07-01 02:25:15 -07001982 ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
1983 ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
Dan Williamsd1c637c32011-05-11 08:27:47 -07001984 break;
1985 }
1986
Dan Williams5076a1a2011-06-27 14:57:03 -07001987 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001988
1989 /* Frame has been decoded return it to the controller */
Dan Williams89a73012011-06-30 19:14:33 -07001990 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07001991
1992 return status;
1993 }
Dan Williamsb50102d2011-09-30 18:52:19 -07001994 case SCI_REQ_ATAPI_WAIT_PIO_SETUP: {
1995 struct sas_task *task = isci_request_access_task(ireq);
1996
1997 sci_controller_release_frame(ihost, frame_index);
1998 ireq->target_device->working_request = ireq;
1999 if (task->data_dir == DMA_NONE) {
2000 sci_change_state(&ireq->sm, SCI_REQ_ATAPI_WAIT_TC_COMP);
2001 scu_atapi_reconstruct_raw_frame_task_context(ireq);
2002 } else {
2003 sci_change_state(&ireq->sm, SCI_REQ_ATAPI_WAIT_D2H);
2004 scu_atapi_construct_task_context(ireq);
2005 }
2006
2007 sci_controller_continue_io(ireq);
2008 return SCI_SUCCESS;
2009 }
2010 case SCI_REQ_ATAPI_WAIT_D2H:
2011 return atapi_d2h_reg_frame_handler(ireq, frame_index);
Edmund Nadolskie3013702011-06-02 00:10:43 +00002012 case SCI_REQ_ABORTING:
2013 /*
2014 * TODO: Is it even possible to get an unsolicited frame in the
Dan Williamsd1c637c32011-05-11 08:27:47 -07002015 * aborting state?
2016 */
Dan Williams89a73012011-06-30 19:14:33 -07002017 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07002018 return SCI_SUCCESS;
Edmund Nadolskie3013702011-06-02 00:10:43 +00002019
Dan Williamsd1c637c32011-05-11 08:27:47 -07002020 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002021 dev_warn(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002022 "%s: SCIC IO Request given unexpected frame %x while "
2023 "in state %d\n",
2024 __func__,
2025 frame_index,
2026 state);
Dan Williamsd1c637c32011-05-11 08:27:47 -07002027
Dan Williams89a73012011-06-30 19:14:33 -07002028 sci_controller_release_frame(ihost, frame_index);
Dan Williamsd1c637c32011-05-11 08:27:47 -07002029 return SCI_FAILURE_INVALID_STATE;
2030 }
2031}
2032
Dan Williams5076a1a2011-06-27 14:57:03 -07002033static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq,
Dan Williamsa7e255a2011-05-11 08:27:47 -07002034 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07002035{
2036 enum sci_status status = SCI_SUCCESS;
2037
2038 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
2039 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07002040 ireq->scu_status = SCU_TASK_DONE_GOOD;
2041 ireq->sci_status = SCI_SUCCESS;
2042 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07002043 break;
2044 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
2045 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
Dan Williamsa7e255a2011-05-11 08:27:47 -07002046 /* We must check ther response buffer to see if the D2H
2047 * Register FIS was received before we got the TC
2048 * completion.
2049 */
Dan Williams5076a1a2011-06-27 14:57:03 -07002050 if (ireq->stp.rsp.fis_type == FIS_REGD2H) {
Dan Williams89a73012011-06-30 19:14:33 -07002051 sci_remote_device_suspend(ireq->target_device,
Dan Williams5dec6f42011-05-10 02:28:49 -07002052 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)));
2053
Dan Williams34a99152011-07-01 02:25:15 -07002054 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
2055 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
2056 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07002057 } else {
Dan Williamsa7e255a2011-05-11 08:27:47 -07002058 /* If we have an error completion status for the
2059 * TC then we can expect a D2H register FIS from
2060 * the device so we must change state to wait
2061 * for it
2062 */
Dan Williams5076a1a2011-06-27 14:57:03 -07002063 sci_change_state(&ireq->sm, SCI_REQ_STP_UDMA_WAIT_D2H);
Dan Williams5dec6f42011-05-10 02:28:49 -07002064 }
2065 break;
2066
Dan Williamsa7e255a2011-05-11 08:27:47 -07002067 /* TODO Check to see if any of these completion status need to
2068 * wait for the device to host register fis.
2069 */
2070 /* TODO We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR
2071 * - this comes only for B0
2072 */
Dan Williams5dec6f42011-05-10 02:28:49 -07002073 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
2074 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
2075 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
2076 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
Dan Williams89a73012011-06-30 19:14:33 -07002077 sci_remote_device_suspend(ireq->target_device,
Dan Williams5dec6f42011-05-10 02:28:49 -07002078 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)));
Jeff Skirvin7582ba82011-09-28 18:47:51 -07002079 /* Fall through to the default case */
Dan Williams5dec6f42011-05-10 02:28:49 -07002080 default:
2081 /* All other completion status cause the IO to be complete. */
Dan Williams34a99152011-07-01 02:25:15 -07002082 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
2083 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
2084 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07002085 break;
2086 }
2087
2088 return status;
2089}
2090
Edmund Nadolskie3013702011-06-02 00:10:43 +00002091static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07002092stp_request_soft_reset_await_h2d_asserted_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002093 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07002094{
2095 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
2096 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07002097 ireq->scu_status = SCU_TASK_DONE_GOOD;
2098 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07002099 sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG);
Dan Williams5dec6f42011-05-10 02:28:49 -07002100 break;
2101
2102 default:
2103 /*
Edmund Nadolskie3013702011-06-02 00:10:43 +00002104 * All other completion status cause the IO to be complete.
2105 * If a NAK was received, then it is up to the user to retry
2106 * the request.
2107 */
Dan Williams34a99152011-07-01 02:25:15 -07002108 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
2109 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07002110 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07002111 break;
2112 }
2113
2114 return SCI_SUCCESS;
2115}
2116
Edmund Nadolskie3013702011-06-02 00:10:43 +00002117static enum sci_status
Dan Williams5076a1a2011-06-27 14:57:03 -07002118stp_request_soft_reset_await_h2d_diagnostic_tc_event(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002119 u32 completion_code)
Dan Williams5dec6f42011-05-10 02:28:49 -07002120{
2121 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
2122 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
Dan Williams34a99152011-07-01 02:25:15 -07002123 ireq->scu_status = SCU_TASK_DONE_GOOD;
2124 ireq->sci_status = SCI_SUCCESS;
Dan Williams5076a1a2011-06-27 14:57:03 -07002125 sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_D2H);
Dan Williams5dec6f42011-05-10 02:28:49 -07002126 break;
2127
2128 default:
Dan Williamsa7e255a2011-05-11 08:27:47 -07002129 /* All other completion status cause the IO to be complete. If
2130 * a NAK was received, then it is up to the user to retry the
2131 * request.
2132 */
Dan Williams34a99152011-07-01 02:25:15 -07002133 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
2134 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
Dan Williams5076a1a2011-06-27 14:57:03 -07002135 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
Dan Williams5dec6f42011-05-10 02:28:49 -07002136 break;
2137 }
2138
2139 return SCI_SUCCESS;
2140}
2141
Dan Williamsb50102d2011-09-30 18:52:19 -07002142static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code,
2143 enum sci_base_request_states next)
2144{
2145 enum sci_status status = SCI_SUCCESS;
2146
2147 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
2148 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2149 ireq->scu_status = SCU_TASK_DONE_GOOD;
2150 ireq->sci_status = SCI_SUCCESS;
2151 sci_change_state(&ireq->sm, next);
2152 break;
2153 default:
2154 /* All other completion status cause the IO to be complete.
2155 * If a NAK was received, then it is up to the user to retry
2156 * the request.
2157 */
2158 ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
2159 ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
2160
2161 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
2162 break;
2163 }
2164
2165 return status;
2166}
2167
2168static enum sci_status atapi_data_tc_completion_handler(struct isci_request *ireq,
2169 u32 completion_code)
2170{
2171 struct isci_remote_device *idev = ireq->target_device;
2172 struct dev_to_host_fis *d2h = &ireq->stp.rsp;
2173 enum sci_status status = SCI_SUCCESS;
2174
2175 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
2176 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
2177 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
2178 break;
2179
2180 case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT): {
2181 u16 len = sci_req_tx_bytes(ireq);
2182
2183 /* likely non-error data underrrun, workaround missing
2184 * d2h frame from the controller
2185 */
2186 if (d2h->fis_type != FIS_REGD2H) {
2187 d2h->fis_type = FIS_REGD2H;
2188 d2h->flags = (1 << 6);
2189 d2h->status = 0x50;
2190 d2h->error = 0;
2191 d2h->lbal = 0;
2192 d2h->byte_count_low = len & 0xff;
2193 d2h->byte_count_high = len >> 8;
2194 d2h->device = 0xa0;
2195 d2h->lbal_exp = 0;
2196 d2h->lbam_exp = 0;
2197 d2h->lbah_exp = 0;
2198 d2h->_r_a = 0;
2199 d2h->sector_count = 0x3;
2200 d2h->sector_count_exp = 0;
2201 d2h->_r_b = 0;
2202 d2h->_r_c = 0;
2203 d2h->_r_d = 0;
2204 }
2205
2206 ireq->scu_status = SCU_TASK_DONE_GOOD;
2207 ireq->sci_status = SCI_SUCCESS_IO_DONE_EARLY;
2208 status = ireq->sci_status;
2209
2210 /* the hw will have suspended the rnc, so complete the
2211 * request upon pending resume
2212 */
2213 sci_change_state(&idev->sm, SCI_STP_DEV_ATAPI_ERROR);
2214 break;
2215 }
2216 case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT):
2217 /* In this case, there is no UF coming after.
2218 * compelte the IO now.
2219 */
2220 ireq->scu_status = SCU_TASK_DONE_GOOD;
2221 ireq->sci_status = SCI_SUCCESS;
2222 sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
2223 break;
2224
2225 default:
2226 if (d2h->fis_type == FIS_REGD2H) {
2227 /* UF received change the device state to ATAPI_ERROR */
2228 status = ireq->sci_status;
2229 sci_change_state(&idev->sm, SCI_STP_DEV_ATAPI_ERROR);
2230 } else {
2231 /* If receiving any non-sucess TC status, no UF
2232 * received yet, then an UF for the status fis
2233 * is coming after (XXX: suspect this is
2234 * actually a protocol error or a bug like the
2235 * DONE_UNEXP_FIS case)
2236 */
2237 ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
2238 ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
2239
2240 sci_change_state(&ireq->sm, SCI_REQ_ATAPI_WAIT_D2H);
2241 }
2242 break;
2243 }
2244
2245 return status;
2246}
2247
Dan Williamsa7e255a2011-05-11 08:27:47 -07002248enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07002249sci_io_request_tc_completion(struct isci_request *ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002250 u32 completion_code)
Dan Williamsa7e255a2011-05-11 08:27:47 -07002251{
2252 enum sci_base_request_states state;
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002253 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsa7e255a2011-05-11 08:27:47 -07002254
Dan Williams5076a1a2011-06-27 14:57:03 -07002255 state = ireq->sm.current_state_id;
Dan Williamsa7e255a2011-05-11 08:27:47 -07002256
2257 switch (state) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00002258 case SCI_REQ_STARTED:
Dan Williams5076a1a2011-06-27 14:57:03 -07002259 return request_started_state_tc_event(ireq, completion_code);
Edmund Nadolskie3013702011-06-02 00:10:43 +00002260
2261 case SCI_REQ_TASK_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -07002262 return ssp_task_request_await_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002263 completion_code);
2264
2265 case SCI_REQ_SMP_WAIT_RESP:
Dan Williams5076a1a2011-06-27 14:57:03 -07002266 return smp_request_await_response_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002267 completion_code);
2268
2269 case SCI_REQ_SMP_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -07002270 return smp_request_await_tc_event(ireq, completion_code);
Edmund Nadolskie3013702011-06-02 00:10:43 +00002271
2272 case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
Dan Williams5076a1a2011-06-27 14:57:03 -07002273 return stp_request_udma_await_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002274 completion_code);
2275
2276 case SCI_REQ_STP_NON_DATA_WAIT_H2D:
Dan Williams5076a1a2011-06-27 14:57:03 -07002277 return stp_request_non_data_await_h2d_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002278 completion_code);
2279
2280 case SCI_REQ_STP_PIO_WAIT_H2D:
Dan Williams5076a1a2011-06-27 14:57:03 -07002281 return stp_request_pio_await_h2d_completion_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002282 completion_code);
2283
2284 case SCI_REQ_STP_PIO_DATA_OUT:
Dan Williams5076a1a2011-06-27 14:57:03 -07002285 return pio_data_out_tx_done_tc_event(ireq, completion_code);
Edmund Nadolskie3013702011-06-02 00:10:43 +00002286
2287 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
Dan Williams5076a1a2011-06-27 14:57:03 -07002288 return stp_request_soft_reset_await_h2d_asserted_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002289 completion_code);
2290
2291 case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
Dan Williams5076a1a2011-06-27 14:57:03 -07002292 return stp_request_soft_reset_await_h2d_diagnostic_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002293 completion_code);
2294
2295 case SCI_REQ_ABORTING:
Dan Williams5076a1a2011-06-27 14:57:03 -07002296 return request_aborting_state_tc_event(ireq,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002297 completion_code);
2298
Dan Williamsb50102d2011-09-30 18:52:19 -07002299 case SCI_REQ_ATAPI_WAIT_H2D:
2300 return atapi_raw_completion(ireq, completion_code,
2301 SCI_REQ_ATAPI_WAIT_PIO_SETUP);
2302
2303 case SCI_REQ_ATAPI_WAIT_TC_COMP:
2304 return atapi_raw_completion(ireq, completion_code,
2305 SCI_REQ_ATAPI_WAIT_D2H);
2306
2307 case SCI_REQ_ATAPI_WAIT_D2H:
2308 return atapi_data_tc_completion_handler(ireq, completion_code);
2309
Edmund Nadolskie3013702011-06-02 00:10:43 +00002310 default:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002311 dev_warn(&ihost->pdev->dev,
Edmund Nadolskie3013702011-06-02 00:10:43 +00002312 "%s: SCIC IO Request given task completion "
2313 "notification %x while in wrong state %d\n",
2314 __func__,
2315 completion_code,
2316 state);
2317 return SCI_FAILURE_INVALID_STATE;
Dan Williamsa7e255a2011-05-11 08:27:47 -07002318 }
2319}
2320
Dan Williams6f231dd2011-07-02 22:56:22 -07002321/**
2322 * isci_request_process_response_iu() - This function sets the status and
2323 * response iu, in the task struct, from the request object for the upper
2324 * layer driver.
2325 * @sas_task: This parameter is the task struct from the upper layer driver.
2326 * @resp_iu: This parameter points to the response iu of the completed request.
2327 * @dev: This parameter specifies the linux device struct.
2328 *
2329 * none.
2330 */
2331static void isci_request_process_response_iu(
2332 struct sas_task *task,
2333 struct ssp_response_iu *resp_iu,
2334 struct device *dev)
2335{
2336 dev_dbg(dev,
2337 "%s: resp_iu = %p "
2338 "resp_iu->status = 0x%x,\nresp_iu->datapres = %d "
2339 "resp_iu->response_data_len = %x, "
2340 "resp_iu->sense_data_len = %x\nrepsonse data: ",
2341 __func__,
2342 resp_iu,
2343 resp_iu->status,
2344 resp_iu->datapres,
2345 resp_iu->response_data_len,
2346 resp_iu->sense_data_len);
2347
2348 task->task_status.stat = resp_iu->status;
2349
2350 /* libsas updates the task status fields based on the response iu. */
2351 sas_ssp_task_response(dev, task, resp_iu);
2352}
2353
2354/**
2355 * isci_request_set_open_reject_status() - This function prepares the I/O
2356 * completion for OPEN_REJECT conditions.
2357 * @request: This parameter is the completed isci_request object.
2358 * @response_ptr: This parameter specifies the service response for the I/O.
2359 * @status_ptr: This parameter specifies the exec status for the I/O.
2360 * @complete_to_host_ptr: This parameter specifies the action to be taken by
2361 * the LLDD with respect to completing this request or forcing an abort
2362 * condition on the I/O.
2363 * @open_rej_reason: This parameter specifies the encoded reason for the
2364 * abandon-class reject.
2365 *
2366 * none.
2367 */
2368static void isci_request_set_open_reject_status(
2369 struct isci_request *request,
2370 struct sas_task *task,
2371 enum service_response *response_ptr,
2372 enum exec_status *status_ptr,
2373 enum isci_completion_selection *complete_to_host_ptr,
2374 enum sas_open_rej_reason open_rej_reason)
2375{
2376 /* Task in the target is done. */
Dan Williams38d88792011-06-23 14:33:48 -07002377 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002378 *response_ptr = SAS_TASK_UNDELIVERED;
2379 *status_ptr = SAS_OPEN_REJECT;
2380 *complete_to_host_ptr = isci_perform_normal_io_completion;
2381 task->task_status.open_rej_reason = open_rej_reason;
2382}
2383
2384/**
2385 * isci_request_handle_controller_specific_errors() - This function decodes
2386 * controller-specific I/O completion error conditions.
2387 * @request: This parameter is the completed isci_request object.
2388 * @response_ptr: This parameter specifies the service response for the I/O.
2389 * @status_ptr: This parameter specifies the exec status for the I/O.
2390 * @complete_to_host_ptr: This parameter specifies the action to be taken by
2391 * the LLDD with respect to completing this request or forcing an abort
2392 * condition on the I/O.
2393 *
2394 * none.
2395 */
2396static void isci_request_handle_controller_specific_errors(
Dan Williams209fae12011-06-13 17:39:44 -07002397 struct isci_remote_device *idev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002398 struct isci_request *request,
2399 struct sas_task *task,
2400 enum service_response *response_ptr,
2401 enum exec_status *status_ptr,
2402 enum isci_completion_selection *complete_to_host_ptr)
2403{
2404 unsigned int cstatus;
2405
Dan Williams5076a1a2011-06-27 14:57:03 -07002406 cstatus = request->scu_status;
Dan Williams6f231dd2011-07-02 22:56:22 -07002407
2408 dev_dbg(&request->isci_host->pdev->dev,
2409 "%s: %p SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR "
2410 "- controller status = 0x%x\n",
2411 __func__, request, cstatus);
2412
2413 /* Decode the controller-specific errors; most
2414 * important is to recognize those conditions in which
2415 * the target may still have a task outstanding that
2416 * must be aborted.
2417 *
2418 * Note that there are SCU completion codes being
2419 * named in the decode below for which SCIC has already
2420 * done work to handle them in a way other than as
2421 * a controller-specific completion code; these are left
2422 * in the decode below for completeness sake.
2423 */
2424 switch (cstatus) {
2425 case SCU_TASK_DONE_DMASETUP_DIRERR:
2426 /* Also SCU_TASK_DONE_SMP_FRM_TYPE_ERR: */
2427 case SCU_TASK_DONE_XFERCNT_ERR:
2428 /* Also SCU_TASK_DONE_SMP_UFI_ERR: */
2429 if (task->task_proto == SAS_PROTOCOL_SMP) {
2430 /* SCU_TASK_DONE_SMP_UFI_ERR == Task Done. */
2431 *response_ptr = SAS_TASK_COMPLETE;
2432
2433 /* See if the device has been/is being stopped. Note
2434 * that we ignore the quiesce state, since we are
2435 * concerned about the actual device state.
2436 */
Dan Williams209fae12011-06-13 17:39:44 -07002437 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002438 *status_ptr = SAS_DEVICE_UNKNOWN;
2439 else
2440 *status_ptr = SAS_ABORTED_TASK;
2441
Dan Williams38d88792011-06-23 14:33:48 -07002442 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002443
2444 *complete_to_host_ptr =
2445 isci_perform_normal_io_completion;
2446 } else {
2447 /* Task in the target is not done. */
2448 *response_ptr = SAS_TASK_UNDELIVERED;
2449
Dan Williams209fae12011-06-13 17:39:44 -07002450 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002451 *status_ptr = SAS_DEVICE_UNKNOWN;
2452 else
2453 *status_ptr = SAM_STAT_TASK_ABORTED;
2454
Dan Williams38d88792011-06-23 14:33:48 -07002455 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002456
2457 *complete_to_host_ptr =
2458 isci_perform_error_io_completion;
2459 }
2460
2461 break;
2462
2463 case SCU_TASK_DONE_CRC_ERR:
2464 case SCU_TASK_DONE_NAK_CMD_ERR:
2465 case SCU_TASK_DONE_EXCESS_DATA:
2466 case SCU_TASK_DONE_UNEXP_FIS:
2467 /* Also SCU_TASK_DONE_UNEXP_RESP: */
2468 case SCU_TASK_DONE_VIIT_ENTRY_NV: /* TODO - conditions? */
2469 case SCU_TASK_DONE_IIT_ENTRY_NV: /* TODO - conditions? */
2470 case SCU_TASK_DONE_RNCNV_OUTBOUND: /* TODO - conditions? */
2471 /* These are conditions in which the target
2472 * has completed the task, so that no cleanup
2473 * is necessary.
2474 */
2475 *response_ptr = SAS_TASK_COMPLETE;
2476
2477 /* See if the device has been/is being stopped. Note
2478 * that we ignore the quiesce state, since we are
2479 * concerned about the actual device state.
2480 */
Dan Williams209fae12011-06-13 17:39:44 -07002481 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002482 *status_ptr = SAS_DEVICE_UNKNOWN;
2483 else
2484 *status_ptr = SAS_ABORTED_TASK;
2485
Dan Williams38d88792011-06-23 14:33:48 -07002486 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002487
2488 *complete_to_host_ptr = isci_perform_normal_io_completion;
2489 break;
2490
2491
2492 /* Note that the only open reject completion codes seen here will be
2493 * abandon-class codes; all others are automatically retried in the SCU.
2494 */
2495 case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION:
2496
2497 isci_request_set_open_reject_status(
2498 request, task, response_ptr, status_ptr,
2499 complete_to_host_ptr, SAS_OREJ_WRONG_DEST);
2500 break;
2501
2502 case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION:
2503
2504 /* Note - the return of AB0 will change when
2505 * libsas implements detection of zone violations.
2506 */
2507 isci_request_set_open_reject_status(
2508 request, task, response_ptr, status_ptr,
2509 complete_to_host_ptr, SAS_OREJ_RESV_AB0);
2510 break;
2511
2512 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1:
2513
2514 isci_request_set_open_reject_status(
2515 request, task, response_ptr, status_ptr,
2516 complete_to_host_ptr, SAS_OREJ_RESV_AB1);
2517 break;
2518
2519 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2:
2520
2521 isci_request_set_open_reject_status(
2522 request, task, response_ptr, status_ptr,
2523 complete_to_host_ptr, SAS_OREJ_RESV_AB2);
2524 break;
2525
2526 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3:
2527
2528 isci_request_set_open_reject_status(
2529 request, task, response_ptr, status_ptr,
2530 complete_to_host_ptr, SAS_OREJ_RESV_AB3);
2531 break;
2532
2533 case SCU_TASK_OPEN_REJECT_BAD_DESTINATION:
2534
2535 isci_request_set_open_reject_status(
2536 request, task, response_ptr, status_ptr,
2537 complete_to_host_ptr, SAS_OREJ_BAD_DEST);
2538 break;
2539
2540 case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY:
2541
2542 isci_request_set_open_reject_status(
2543 request, task, response_ptr, status_ptr,
2544 complete_to_host_ptr, SAS_OREJ_STP_NORES);
2545 break;
2546
2547 case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED:
2548
2549 isci_request_set_open_reject_status(
2550 request, task, response_ptr, status_ptr,
2551 complete_to_host_ptr, SAS_OREJ_EPROTO);
2552 break;
2553
2554 case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED:
2555
2556 isci_request_set_open_reject_status(
2557 request, task, response_ptr, status_ptr,
2558 complete_to_host_ptr, SAS_OREJ_CONN_RATE);
2559 break;
2560
2561 case SCU_TASK_DONE_LL_R_ERR:
2562 /* Also SCU_TASK_DONE_ACK_NAK_TO: */
2563 case SCU_TASK_DONE_LL_PERR:
2564 case SCU_TASK_DONE_LL_SY_TERM:
2565 /* Also SCU_TASK_DONE_NAK_ERR:*/
2566 case SCU_TASK_DONE_LL_LF_TERM:
2567 /* Also SCU_TASK_DONE_DATA_LEN_ERR: */
2568 case SCU_TASK_DONE_LL_ABORT_ERR:
2569 case SCU_TASK_DONE_SEQ_INV_TYPE:
2570 /* Also SCU_TASK_DONE_UNEXP_XR: */
2571 case SCU_TASK_DONE_XR_IU_LEN_ERR:
2572 case SCU_TASK_DONE_INV_FIS_LEN:
2573 /* Also SCU_TASK_DONE_XR_WD_LEN: */
2574 case SCU_TASK_DONE_SDMA_ERR:
2575 case SCU_TASK_DONE_OFFSET_ERR:
2576 case SCU_TASK_DONE_MAX_PLD_ERR:
2577 case SCU_TASK_DONE_LF_ERR:
2578 case SCU_TASK_DONE_SMP_RESP_TO_ERR: /* Escalate to dev reset? */
2579 case SCU_TASK_DONE_SMP_LL_RX_ERR:
2580 case SCU_TASK_DONE_UNEXP_DATA:
2581 case SCU_TASK_DONE_UNEXP_SDBFIS:
2582 case SCU_TASK_DONE_REG_ERR:
2583 case SCU_TASK_DONE_SDB_ERR:
2584 case SCU_TASK_DONE_TASK_ABORT:
2585 default:
2586 /* Task in the target is not done. */
2587 *response_ptr = SAS_TASK_UNDELIVERED;
2588 *status_ptr = SAM_STAT_TASK_ABORTED;
Dan Williams6f231dd2011-07-02 22:56:22 -07002589
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002590 if (task->task_proto == SAS_PROTOCOL_SMP) {
Dan Williams38d88792011-06-23 14:33:48 -07002591 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002592
2593 *complete_to_host_ptr = isci_perform_normal_io_completion;
2594 } else {
Dan Williams38d88792011-06-23 14:33:48 -07002595 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002596
2597 *complete_to_host_ptr = isci_perform_error_io_completion;
2598 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002599 break;
2600 }
2601}
2602
2603/**
2604 * isci_task_save_for_upper_layer_completion() - This function saves the
2605 * request for later completion to the upper layer driver.
2606 * @host: This parameter is a pointer to the host on which the the request
2607 * should be queued (either as an error or success).
2608 * @request: This parameter is the completed request.
2609 * @response: This parameter is the response code for the completed task.
2610 * @status: This parameter is the status code for the completed task.
2611 *
2612 * none.
2613 */
2614static void isci_task_save_for_upper_layer_completion(
2615 struct isci_host *host,
2616 struct isci_request *request,
2617 enum service_response response,
2618 enum exec_status status,
2619 enum isci_completion_selection task_notification_selection)
2620{
2621 struct sas_task *task = isci_request_access_task(request);
2622
Jeff Skirvinec6c9632011-03-04 14:06:44 -08002623 task_notification_selection
2624 = isci_task_set_completion_status(task, response, status,
2625 task_notification_selection);
Dan Williams6f231dd2011-07-02 22:56:22 -07002626
2627 /* Tasks aborted specifically by a call to the lldd_abort_task
2628 * function should not be completed to the host in the regular path.
2629 */
2630 switch (task_notification_selection) {
2631
2632 case isci_perform_normal_io_completion:
Dan Williams6f231dd2011-07-02 22:56:22 -07002633 /* Normal notification (task_done) */
Jeff Skirvin3b34c162011-10-27 15:05:22 -07002634
Dan Williams6f231dd2011-07-02 22:56:22 -07002635 /* Add to the completed list. */
2636 list_add(&request->completed_node,
2637 &host->requests_to_complete);
Jeff Skirvinec6c9632011-03-04 14:06:44 -08002638
2639 /* Take the request off the device's pending request list. */
2640 list_del_init(&request->dev_node);
Dan Williams6f231dd2011-07-02 22:56:22 -07002641 break;
2642
2643 case isci_perform_aborted_io_completion:
Jeff Skirvina5fde222011-03-04 14:06:42 -08002644 /* No notification to libsas because this request is
2645 * already in the abort path.
Dan Williams6f231dd2011-07-02 22:56:22 -07002646 */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002647 /* Wake up whatever process was waiting for this
2648 * request to complete.
2649 */
2650 WARN_ON(request->io_request_completion == NULL);
2651
2652 if (request->io_request_completion != NULL) {
2653
2654 /* Signal whoever is waiting that this
2655 * request is complete.
2656 */
2657 complete(request->io_request_completion);
2658 }
Dan Williams6f231dd2011-07-02 22:56:22 -07002659 break;
2660
2661 case isci_perform_error_io_completion:
2662 /* Use sas_task_abort */
Dan Williams6f231dd2011-07-02 22:56:22 -07002663 /* Add to the aborted list. */
2664 list_add(&request->completed_node,
Jeff Skirvin11b00c12011-03-04 14:06:40 -08002665 &host->requests_to_errorback);
Dan Williams6f231dd2011-07-02 22:56:22 -07002666 break;
2667
2668 default:
Jeff Skirvina5fde222011-03-04 14:06:42 -08002669 /* Add to the error to libsas list. */
Dan Williams6f231dd2011-07-02 22:56:22 -07002670 list_add(&request->completed_node,
Jeff Skirvin11b00c12011-03-04 14:06:40 -08002671 &host->requests_to_errorback);
Dan Williams6f231dd2011-07-02 22:56:22 -07002672 break;
2673 }
Jeff Skirvin3b34c162011-10-27 15:05:22 -07002674 dev_dbg(&host->pdev->dev,
2675 "%s: %d - task = %p, response=%d (%d), status=%d (%d)\n",
2676 __func__, task_notification_selection, task,
2677 (task) ? task->task_status.resp : 0, response,
2678 (task) ? task->task_status.stat : 0, status);
Dan Williams6f231dd2011-07-02 22:56:22 -07002679}
2680
Dan Williams1a878282011-07-29 17:16:40 -07002681static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis)
Dan Williams16ba7702011-07-01 10:52:55 -07002682{
Dan Williams16ba7702011-07-01 10:52:55 -07002683 struct task_status_struct *ts = &task->task_status;
2684 struct ata_task_resp *resp = (void *)&ts->buf[0];
2685
Dan Williams1a878282011-07-29 17:16:40 -07002686 resp->frame_len = sizeof(*fis);
2687 memcpy(resp->ending_fis, fis, sizeof(*fis));
Dan Williams16ba7702011-07-01 10:52:55 -07002688 ts->buf_valid_size = sizeof(*resp);
2689
Dan Williams1a878282011-07-29 17:16:40 -07002690 /* If the device fault bit is set in the status register, then
Dan Williams16ba7702011-07-01 10:52:55 -07002691 * set the sense data and return.
2692 */
Dan Williams1a878282011-07-29 17:16:40 -07002693 if (fis->status & ATA_DF)
Dan Williams16ba7702011-07-01 10:52:55 -07002694 ts->stat = SAS_PROTO_RESPONSE;
Dan Williamsb50102d2011-09-30 18:52:19 -07002695 else if (fis->status & ATA_ERR)
2696 ts->stat = SAM_STAT_CHECK_CONDITION;
Dan Williams16ba7702011-07-01 10:52:55 -07002697 else
2698 ts->stat = SAM_STAT_GOOD;
2699
2700 ts->resp = SAS_TASK_COMPLETE;
2701}
2702
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002703static void isci_request_io_request_complete(struct isci_host *ihost,
Dan Williamsf1f52e72011-05-10 02:28:45 -07002704 struct isci_request *request,
2705 enum sci_io_status completion_status)
Dan Williams6f231dd2011-07-02 22:56:22 -07002706{
2707 struct sas_task *task = isci_request_access_task(request);
2708 struct ssp_response_iu *resp_iu;
Dan Williams6f231dd2011-07-02 22:56:22 -07002709 unsigned long task_flags;
Jeff Skirvin0e2e2792011-10-27 15:04:50 -07002710 struct isci_remote_device *idev = request->target_device;
2711 enum service_response response = SAS_TASK_UNDELIVERED;
2712 enum exec_status status = SAS_ABORTED_TASK;
Dan Williams6f231dd2011-07-02 22:56:22 -07002713 enum isci_request_status request_status;
2714 enum isci_completion_selection complete_to_host
2715 = isci_perform_normal_io_completion;
2716
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002717 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002718 "%s: request = %p, task = %p,\n"
2719 "task->data_dir = %d completion_status = 0x%x\n",
2720 __func__,
2721 request,
2722 task,
2723 task->data_dir,
2724 completion_status);
2725
Jeff Skirvina5fde222011-03-04 14:06:42 -08002726 spin_lock(&request->state_lock);
Dan Williams34a99152011-07-01 02:25:15 -07002727 request_status = request->status;
Dan Williams6f231dd2011-07-02 22:56:22 -07002728
2729 /* Decode the request status. Note that if the request has been
2730 * aborted by a task management function, we don't care
2731 * what the status is.
2732 */
2733 switch (request_status) {
2734
2735 case aborted:
2736 /* "aborted" indicates that the request was aborted by a task
2737 * management function, since once a task management request is
2738 * perfomed by the device, the request only completes because
2739 * of the subsequent driver terminate.
2740 *
2741 * Aborted also means an external thread is explicitly managing
2742 * this request, so that we do not complete it up the stack.
2743 *
2744 * The target is still there (since the TMF was successful).
2745 */
Dan Williams38d88792011-06-23 14:33:48 -07002746 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002747 response = SAS_TASK_COMPLETE;
2748
2749 /* See if the device has been/is being stopped. Note
2750 * that we ignore the quiesce state, since we are
2751 * concerned about the actual device state.
2752 */
Dan Williams209fae12011-06-13 17:39:44 -07002753 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002754 status = SAS_DEVICE_UNKNOWN;
2755 else
2756 status = SAS_ABORTED_TASK;
2757
2758 complete_to_host = isci_perform_aborted_io_completion;
2759 /* This was an aborted request. */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002760
2761 spin_unlock(&request->state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002762 break;
2763
2764 case aborting:
2765 /* aborting means that the task management function tried and
2766 * failed to abort the request. We need to note the request
2767 * as SAS_TASK_UNDELIVERED, so that the scsi mid layer marks the
2768 * target as down.
2769 *
2770 * Aborting also means an external thread is explicitly managing
2771 * this request, so that we do not complete it up the stack.
2772 */
Dan Williams38d88792011-06-23 14:33:48 -07002773 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002774 response = SAS_TASK_UNDELIVERED;
2775
Dan Williams209fae12011-06-13 17:39:44 -07002776 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002777 /* The device has been /is being stopped. Note that
2778 * we ignore the quiesce state, since we are
2779 * concerned about the actual device state.
2780 */
2781 status = SAS_DEVICE_UNKNOWN;
2782 else
2783 status = SAS_PHY_DOWN;
2784
2785 complete_to_host = isci_perform_aborted_io_completion;
2786
2787 /* This was an aborted request. */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002788
2789 spin_unlock(&request->state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002790 break;
2791
2792 case terminating:
2793
2794 /* This was an terminated request. This happens when
2795 * the I/O is being terminated because of an action on
2796 * the device (reset, tear down, etc.), and the I/O needs
2797 * to be completed up the stack.
2798 */
Dan Williams38d88792011-06-23 14:33:48 -07002799 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002800 response = SAS_TASK_UNDELIVERED;
2801
2802 /* See if the device has been/is being stopped. Note
2803 * that we ignore the quiesce state, since we are
2804 * concerned about the actual device state.
2805 */
Dan Williams209fae12011-06-13 17:39:44 -07002806 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002807 status = SAS_DEVICE_UNKNOWN;
2808 else
2809 status = SAS_ABORTED_TASK;
2810
Jeff Skirvina5fde222011-03-04 14:06:42 -08002811 complete_to_host = isci_perform_aborted_io_completion;
Dan Williams6f231dd2011-07-02 22:56:22 -07002812
2813 /* This was a terminated request. */
Jeff Skirvina5fde222011-03-04 14:06:42 -08002814
2815 spin_unlock(&request->state_lock);
Dan Williams6f231dd2011-07-02 22:56:22 -07002816 break;
2817
Jeff Skirvin77c852f2011-06-20 14:09:16 -07002818 case dead:
2819 /* This was a terminated request that timed-out during the
2820 * termination process. There is no task to complete to
2821 * libsas.
2822 */
2823 complete_to_host = isci_perform_normal_io_completion;
2824 spin_unlock(&request->state_lock);
2825 break;
2826
Dan Williams6f231dd2011-07-02 22:56:22 -07002827 default:
2828
Jeff Skirvina5fde222011-03-04 14:06:42 -08002829 /* The request is done from an SCU HW perspective. */
2830 request->status = completed;
2831
2832 spin_unlock(&request->state_lock);
2833
Dan Williams6f231dd2011-07-02 22:56:22 -07002834 /* This is an active request being completed from the core. */
2835 switch (completion_status) {
2836
2837 case SCI_IO_FAILURE_RESPONSE_VALID:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002838 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002839 "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n",
2840 __func__,
2841 request,
2842 task);
2843
2844 if (sas_protocol_ata(task->task_proto)) {
Dan Williams1a878282011-07-29 17:16:40 -07002845 isci_process_stp_response(task, &request->stp.rsp);
Dan Williams6f231dd2011-07-02 22:56:22 -07002846 } else if (SAS_PROTOCOL_SSP == task->task_proto) {
2847
2848 /* crack the iu response buffer. */
Dan Williams5076a1a2011-06-27 14:57:03 -07002849 resp_iu = &request->ssp.rsp;
Dan Williams6f231dd2011-07-02 22:56:22 -07002850 isci_request_process_response_iu(task, resp_iu,
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002851 &ihost->pdev->dev);
Dan Williams6f231dd2011-07-02 22:56:22 -07002852
2853 } else if (SAS_PROTOCOL_SMP == task->task_proto) {
2854
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002855 dev_err(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002856 "%s: SCI_IO_FAILURE_RESPONSE_VALID: "
2857 "SAS_PROTOCOL_SMP protocol\n",
2858 __func__);
2859
2860 } else
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002861 dev_err(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002862 "%s: unknown protocol\n", __func__);
2863
2864 /* use the task status set in the task struct by the
2865 * isci_request_process_response_iu call.
2866 */
Dan Williams38d88792011-06-23 14:33:48 -07002867 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002868 response = task->task_status.resp;
2869 status = task->task_status.stat;
2870 break;
2871
2872 case SCI_IO_SUCCESS:
2873 case SCI_IO_SUCCESS_IO_DONE_EARLY:
2874
2875 response = SAS_TASK_COMPLETE;
2876 status = SAM_STAT_GOOD;
Dan Williams38d88792011-06-23 14:33:48 -07002877 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002878
Dan Williams54b5e3a2011-09-28 18:35:27 -07002879 if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) {
Dan Williams6f231dd2011-07-02 22:56:22 -07002880
2881 /* This was an SSP / STP / SATA transfer.
2882 * There is a possibility that less data than
2883 * the maximum was transferred.
2884 */
Dan Williams5076a1a2011-06-27 14:57:03 -07002885 u32 transferred_length = sci_req_tx_bytes(request);
Dan Williams6f231dd2011-07-02 22:56:22 -07002886
2887 task->task_status.residual
2888 = task->total_xfer_len - transferred_length;
2889
2890 /* If there were residual bytes, call this an
2891 * underrun.
2892 */
2893 if (task->task_status.residual != 0)
2894 status = SAS_DATA_UNDERRUN;
2895
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002896 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002897 "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n",
2898 __func__,
2899 status);
2900
2901 } else
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002902 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002903 "%s: SCI_IO_SUCCESS\n",
2904 __func__);
2905
2906 break;
2907
2908 case SCI_IO_FAILURE_TERMINATED:
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07002909 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002910 "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n",
2911 __func__,
2912 request,
2913 task);
2914
2915 /* The request was terminated explicitly. No handling
2916 * is needed in the SCSI error handler path.
2917 */
Dan Williams38d88792011-06-23 14:33:48 -07002918 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002919 response = SAS_TASK_UNDELIVERED;
2920
2921 /* See if the device has been/is being stopped. Note
2922 * that we ignore the quiesce state, since we are
2923 * concerned about the actual device state.
2924 */
Dan Williams209fae12011-06-13 17:39:44 -07002925 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002926 status = SAS_DEVICE_UNKNOWN;
2927 else
2928 status = SAS_ABORTED_TASK;
2929
2930 complete_to_host = isci_perform_normal_io_completion;
2931 break;
2932
2933 case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR:
2934
2935 isci_request_handle_controller_specific_errors(
Dan Williams209fae12011-06-13 17:39:44 -07002936 idev, request, task, &response, &status,
Dan Williams6f231dd2011-07-02 22:56:22 -07002937 &complete_to_host);
2938
2939 break;
2940
2941 case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED:
2942 /* This is a special case, in that the I/O completion
2943 * is telling us that the device needs a reset.
2944 * In order for the device reset condition to be
2945 * noticed, the I/O has to be handled in the error
2946 * handler. Set the reset flag and cause the
2947 * SCSI error thread to be scheduled.
2948 */
2949 spin_lock_irqsave(&task->task_state_lock, task_flags);
2950 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
2951 spin_unlock_irqrestore(&task->task_state_lock, task_flags);
2952
Jeff Skirvinaa145102011-03-07 16:40:47 -07002953 /* Fail the I/O. */
2954 response = SAS_TASK_UNDELIVERED;
2955 status = SAM_STAT_TASK_ABORTED;
2956
Dan Williams6f231dd2011-07-02 22:56:22 -07002957 complete_to_host = isci_perform_error_io_completion;
Dan Williams38d88792011-06-23 14:33:48 -07002958 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07002959 break;
2960
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002961 case SCI_FAILURE_RETRY_REQUIRED:
2962
2963 /* Fail the I/O so it can be retried. */
2964 response = SAS_TASK_UNDELIVERED;
Dan Williams209fae12011-06-13 17:39:44 -07002965 if (!idev)
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002966 status = SAS_DEVICE_UNKNOWN;
2967 else
2968 status = SAS_ABORTED_TASK;
2969
2970 complete_to_host = isci_perform_normal_io_completion;
Dan Williams38d88792011-06-23 14:33:48 -07002971 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002972 break;
2973
2974
Dan Williams6f231dd2011-07-02 22:56:22 -07002975 default:
2976 /* Catch any otherwise unhandled error codes here. */
Dan Williamsa8a0a132011-07-01 12:07:25 -07002977 dev_dbg(&ihost->pdev->dev,
Dan Williams6f231dd2011-07-02 22:56:22 -07002978 "%s: invalid completion code: 0x%x - "
2979 "isci_request = %p\n",
2980 __func__, completion_status, request);
2981
2982 response = SAS_TASK_UNDELIVERED;
2983
2984 /* See if the device has been/is being stopped. Note
2985 * that we ignore the quiesce state, since we are
2986 * concerned about the actual device state.
2987 */
Dan Williams209fae12011-06-13 17:39:44 -07002988 if (!idev)
Dan Williams6f231dd2011-07-02 22:56:22 -07002989 status = SAS_DEVICE_UNKNOWN;
2990 else
2991 status = SAS_ABORTED_TASK;
2992
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002993 if (SAS_PROTOCOL_SMP == task->task_proto) {
Dan Williams38d88792011-06-23 14:33:48 -07002994 set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002995 complete_to_host = isci_perform_normal_io_completion;
2996 } else {
Dan Williams38d88792011-06-23 14:33:48 -07002997 clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
Jeff Skirvincde76fb2011-06-20 14:09:06 -07002998 complete_to_host = isci_perform_error_io_completion;
2999 }
Dan Williams6f231dd2011-07-02 22:56:22 -07003000 break;
3001 }
3002 break;
3003 }
3004
Dan Williamsddcc7e32011-06-17 10:40:43 -07003005 switch (task->task_proto) {
3006 case SAS_PROTOCOL_SSP:
3007 if (task->data_dir == DMA_NONE)
3008 break;
3009 if (task->num_scatter == 0)
3010 /* 0 indicates a single dma address */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003011 dma_unmap_single(&ihost->pdev->dev,
Dan Williamsddcc7e32011-06-17 10:40:43 -07003012 request->zero_scatter_daddr,
3013 task->total_xfer_len, task->data_dir);
3014 else /* unmap the sgl dma addresses */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003015 dma_unmap_sg(&ihost->pdev->dev, task->scatter,
Dan Williamsddcc7e32011-06-17 10:40:43 -07003016 request->num_sg_entries, task->data_dir);
3017 break;
Dan Williamse9bf7092011-06-16 16:59:56 -07003018 case SAS_PROTOCOL_SMP: {
3019 struct scatterlist *sg = &task->smp_task.smp_req;
3020 struct smp_req *smp_req;
3021 void *kaddr;
3022
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003023 dma_unmap_sg(&ihost->pdev->dev, sg, 1, DMA_TO_DEVICE);
Dan Williamse9bf7092011-06-16 16:59:56 -07003024
3025 /* need to swab it back in case the command buffer is re-used */
3026 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
3027 smp_req = kaddr + sg->offset;
3028 sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
3029 kunmap_atomic(kaddr, KM_IRQ0);
3030 break;
3031 }
Dan Williamsddcc7e32011-06-17 10:40:43 -07003032 default:
3033 break;
3034 }
Dan Williams6f231dd2011-07-02 22:56:22 -07003035
3036 /* Put the completed request on the correct list */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003037 isci_task_save_for_upper_layer_completion(ihost, request, response,
Dan Williams6f231dd2011-07-02 22:56:22 -07003038 status, complete_to_host
3039 );
3040
3041 /* complete the io request to the core. */
Dan Williams89a73012011-06-30 19:14:33 -07003042 sci_controller_complete_io(ihost, request->target_device, request);
Dan Williams209fae12011-06-13 17:39:44 -07003043
Dan Williams67ea8382011-05-08 11:47:15 -07003044 /* set terminated handle so it cannot be completed or
Dan Williams6f231dd2011-07-02 22:56:22 -07003045 * terminated again, and to cause any calls into abort
3046 * task to recognize the already completed case.
3047 */
Dan Williams38d88792011-06-23 14:33:48 -07003048 set_bit(IREQ_TERMINATED, &request->flags);
Dan Williams6f231dd2011-07-02 22:56:22 -07003049}
Dan Williamsf1f52e72011-05-10 02:28:45 -07003050
Dan Williams89a73012011-06-30 19:14:33 -07003051static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003052{
Dan Williams5076a1a2011-06-27 14:57:03 -07003053 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams78a6f062011-06-30 16:31:37 -07003054 struct domain_device *dev = ireq->target_device->domain_dev;
Dan Williamsb50102d2011-09-30 18:52:19 -07003055 enum sci_base_request_states state;
Dan Williamsc72086e2011-05-10 02:28:48 -07003056 struct sas_task *task;
3057
3058 /* XXX as hch said always creating an internal sas_task for tmf
3059 * requests would simplify the driver
3060 */
Jeff Skirvin3b34c162011-10-27 15:05:22 -07003061 task = (test_bit(IREQ_TMF, &ireq->flags)) ? NULL : isci_request_access_task(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003062
Dan Williams5dec6f42011-05-10 02:28:49 -07003063 /* all unaccelerated request types (non ssp or ncq) handled with
3064 * substates
Dan Williamsf1393032011-05-10 02:28:47 -07003065 */
Dan Williamsc72086e2011-05-10 02:28:48 -07003066 if (!task && dev->dev_type == SAS_END_DEV) {
Dan Williamsb50102d2011-09-30 18:52:19 -07003067 state = SCI_REQ_TASK_WAIT_TC_COMP;
Dan Williams5dec6f42011-05-10 02:28:49 -07003068 } else if (!task &&
3069 (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high ||
3070 isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) {
Dan Williamsb50102d2011-09-30 18:52:19 -07003071 state = SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED;
Dan Williamsc72086e2011-05-10 02:28:48 -07003072 } else if (task && task->task_proto == SAS_PROTOCOL_SMP) {
Dan Williamsb50102d2011-09-30 18:52:19 -07003073 state = SCI_REQ_SMP_WAIT_RESP;
Dan Williams5dec6f42011-05-10 02:28:49 -07003074 } else if (task && sas_protocol_ata(task->task_proto) &&
3075 !task->ata_task.use_ncq) {
Dan Williamsb50102d2011-09-30 18:52:19 -07003076 if (dev->sata_dev.command_set == ATAPI_COMMAND_SET &&
3077 task->ata_task.fis.command == ATA_CMD_PACKET) {
3078 state = SCI_REQ_ATAPI_WAIT_H2D;
3079 } else if (task->data_dir == DMA_NONE) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00003080 state = SCI_REQ_STP_NON_DATA_WAIT_H2D;
Dan Williamsb50102d2011-09-30 18:52:19 -07003081 } else if (task->ata_task.dma_xfer) {
Edmund Nadolskie3013702011-06-02 00:10:43 +00003082 state = SCI_REQ_STP_UDMA_WAIT_TC_COMP;
Dan Williamsb50102d2011-09-30 18:52:19 -07003083 } else /* PIO */ {
Edmund Nadolskie3013702011-06-02 00:10:43 +00003084 state = SCI_REQ_STP_PIO_WAIT_H2D;
Dan Williamsb50102d2011-09-30 18:52:19 -07003085 }
3086 } else {
3087 /* SSP or NCQ are fully accelerated, no substates */
3088 return;
Dan Williamsc72086e2011-05-10 02:28:48 -07003089 }
Dan Williamsb50102d2011-09-30 18:52:19 -07003090 sci_change_state(sm, state);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003091}
3092
Dan Williams89a73012011-06-30 19:14:33 -07003093static void sci_request_completed_state_enter(struct sci_base_state_machine *sm)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003094{
Dan Williams5076a1a2011-06-27 14:57:03 -07003095 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003096 struct isci_host *ihost = ireq->owning_controller;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003097
Dan Williamsf1f52e72011-05-10 02:28:45 -07003098 /* Tell the SCI_USER that the IO request is complete */
Dan Williams38d88792011-06-23 14:33:48 -07003099 if (!test_bit(IREQ_TMF, &ireq->flags))
Dan Williamsf1f52e72011-05-10 02:28:45 -07003100 isci_request_io_request_complete(ihost, ireq,
Dan Williams5076a1a2011-06-27 14:57:03 -07003101 ireq->sci_status);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003102 else
Dan Williams5076a1a2011-06-27 14:57:03 -07003103 isci_task_request_complete(ihost, ireq, ireq->sci_status);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003104}
3105
Dan Williams89a73012011-06-30 19:14:33 -07003106static void sci_request_aborting_state_enter(struct sci_base_state_machine *sm)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003107{
Dan Williams5076a1a2011-06-27 14:57:03 -07003108 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003109
3110 /* Setting the abort bit in the Task Context is required by the silicon. */
Dan Williams5076a1a2011-06-27 14:57:03 -07003111 ireq->tc->abort = 1;
Dan Williamsc72086e2011-05-10 02:28:48 -07003112}
3113
Dan Williams89a73012011-06-30 19:14:33 -07003114static void sci_stp_request_started_non_data_await_h2d_completion_enter(struct sci_base_state_machine *sm)
Dan Williams5dec6f42011-05-10 02:28:49 -07003115{
Dan Williams5076a1a2011-06-27 14:57:03 -07003116 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams5dec6f42011-05-10 02:28:49 -07003117
Dan Williams34a99152011-07-01 02:25:15 -07003118 ireq->target_device->working_request = ireq;
Dan Williams5dec6f42011-05-10 02:28:49 -07003119}
3120
Dan Williams89a73012011-06-30 19:14:33 -07003121static void sci_stp_request_started_pio_await_h2d_completion_enter(struct sci_base_state_machine *sm)
Dan Williams5dec6f42011-05-10 02:28:49 -07003122{
Dan Williams5076a1a2011-06-27 14:57:03 -07003123 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams5dec6f42011-05-10 02:28:49 -07003124
Dan Williams34a99152011-07-01 02:25:15 -07003125 ireq->target_device->working_request = ireq;
Dan Williams5dec6f42011-05-10 02:28:49 -07003126}
3127
Dan Williams89a73012011-06-30 19:14:33 -07003128static 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 -07003129{
Dan Williams5076a1a2011-06-27 14:57:03 -07003130 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
Dan Williams5dec6f42011-05-10 02:28:49 -07003131
Dan Williams34a99152011-07-01 02:25:15 -07003132 ireq->target_device->working_request = ireq;
Dan Williams5dec6f42011-05-10 02:28:49 -07003133}
3134
Dan Williams89a73012011-06-30 19:14:33 -07003135static 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 -07003136{
Dan Williams5076a1a2011-06-27 14:57:03 -07003137 struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
3138 struct scu_task_context *tc = ireq->tc;
Dan Williams5dec6f42011-05-10 02:28:49 -07003139 struct host_to_dev_fis *h2d_fis;
3140 enum sci_status status;
3141
3142 /* Clear the SRST bit */
Dan Williams5076a1a2011-06-27 14:57:03 -07003143 h2d_fis = &ireq->stp.cmd;
Dan Williams5dec6f42011-05-10 02:28:49 -07003144 h2d_fis->control = 0;
3145
3146 /* Clear the TC control bit */
Dan Williams312e0c22011-06-28 13:47:09 -07003147 tc->control_frame = 0;
Dan Williams5dec6f42011-05-10 02:28:49 -07003148
Dan Williams89a73012011-06-30 19:14:33 -07003149 status = sci_controller_continue_io(ireq);
Dan Williams79e2b6b2011-05-11 08:29:56 -07003150 WARN_ONCE(status != SCI_SUCCESS, "isci: continue io failure\n");
Dan Williams5dec6f42011-05-10 02:28:49 -07003151}
3152
Dan Williams89a73012011-06-30 19:14:33 -07003153static const struct sci_base_state sci_request_state_table[] = {
Edmund Nadolskie3013702011-06-02 00:10:43 +00003154 [SCI_REQ_INIT] = { },
3155 [SCI_REQ_CONSTRUCTED] = { },
3156 [SCI_REQ_STARTED] = {
Dan Williams89a73012011-06-30 19:14:33 -07003157 .enter_state = sci_request_started_state_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07003158 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003159 [SCI_REQ_STP_NON_DATA_WAIT_H2D] = {
Dan Williams89a73012011-06-30 19:14:33 -07003160 .enter_state = sci_stp_request_started_non_data_await_h2d_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07003161 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003162 [SCI_REQ_STP_NON_DATA_WAIT_D2H] = { },
3163 [SCI_REQ_STP_PIO_WAIT_H2D] = {
Dan Williams89a73012011-06-30 19:14:33 -07003164 .enter_state = sci_stp_request_started_pio_await_h2d_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07003165 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003166 [SCI_REQ_STP_PIO_WAIT_FRAME] = { },
3167 [SCI_REQ_STP_PIO_DATA_IN] = { },
3168 [SCI_REQ_STP_PIO_DATA_OUT] = { },
3169 [SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { },
3170 [SCI_REQ_STP_UDMA_WAIT_D2H] = { },
3171 [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED] = {
Dan Williams89a73012011-06-30 19:14:33 -07003172 .enter_state = sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07003173 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003174 [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG] = {
Dan Williams89a73012011-06-30 19:14:33 -07003175 .enter_state = sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
Dan Williams5dec6f42011-05-10 02:28:49 -07003176 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003177 [SCI_REQ_STP_SOFT_RESET_WAIT_D2H] = { },
3178 [SCI_REQ_TASK_WAIT_TC_COMP] = { },
3179 [SCI_REQ_TASK_WAIT_TC_RESP] = { },
3180 [SCI_REQ_SMP_WAIT_RESP] = { },
3181 [SCI_REQ_SMP_WAIT_TC_COMP] = { },
Dan Williamsb50102d2011-09-30 18:52:19 -07003182 [SCI_REQ_ATAPI_WAIT_H2D] = { },
3183 [SCI_REQ_ATAPI_WAIT_PIO_SETUP] = { },
3184 [SCI_REQ_ATAPI_WAIT_D2H] = { },
3185 [SCI_REQ_ATAPI_WAIT_TC_COMP] = { },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003186 [SCI_REQ_COMPLETED] = {
Dan Williams89a73012011-06-30 19:14:33 -07003187 .enter_state = sci_request_completed_state_enter,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003188 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003189 [SCI_REQ_ABORTING] = {
Dan Williams89a73012011-06-30 19:14:33 -07003190 .enter_state = sci_request_aborting_state_enter,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003191 },
Edmund Nadolskie3013702011-06-02 00:10:43 +00003192 [SCI_REQ_FINAL] = { },
Dan Williamsf1f52e72011-05-10 02:28:45 -07003193};
3194
Edmund Nadolskie3013702011-06-02 00:10:43 +00003195static void
Dan Williams89a73012011-06-30 19:14:33 -07003196sci_general_request_construct(struct isci_host *ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07003197 struct isci_remote_device *idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003198 struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003199{
Dan Williams89a73012011-06-30 19:14:33 -07003200 sci_init_sm(&ireq->sm, sci_request_state_table, SCI_REQ_INIT);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003201
Dan Williams78a6f062011-06-30 16:31:37 -07003202 ireq->target_device = idev;
Dan Williams5076a1a2011-06-27 14:57:03 -07003203 ireq->protocol = SCIC_NO_PROTOCOL;
3204 ireq->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003205
Dan Williams5076a1a2011-06-27 14:57:03 -07003206 ireq->sci_status = SCI_SUCCESS;
3207 ireq->scu_status = 0;
3208 ireq->post_context = 0xFFFFFFFF;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003209}
3210
3211static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07003212sci_io_request_construct(struct isci_host *ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07003213 struct isci_remote_device *idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003214 struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003215{
Dan Williams78a6f062011-06-30 16:31:37 -07003216 struct domain_device *dev = idev->domain_dev;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003217 enum sci_status status = SCI_SUCCESS;
3218
3219 /* Build the common part of the request */
Dan Williams89a73012011-06-30 19:14:33 -07003220 sci_general_request_construct(ihost, idev, ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003221
Dan Williams78a6f062011-06-30 16:31:37 -07003222 if (idev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003223 return SCI_FAILURE_INVALID_REMOTE_DEVICE;
3224
3225 if (dev->dev_type == SAS_END_DEV)
Dan Williamsc72086e2011-05-10 02:28:48 -07003226 /* pass */;
3227 else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
Dan Williams5076a1a2011-06-27 14:57:03 -07003228 memset(&ireq->stp.cmd, 0, sizeof(ireq->stp.cmd));
Dan Williamsc72086e2011-05-10 02:28:48 -07003229 else if (dev_is_expander(dev))
Dan Williamse9bf7092011-06-16 16:59:56 -07003230 /* pass */;
Dan Williamsc72086e2011-05-10 02:28:48 -07003231 else
3232 return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003233
Dan Williams5076a1a2011-06-27 14:57:03 -07003234 memset(ireq->tc, 0, offsetof(struct scu_task_context, sgl_pair_ab));
Dan Williamsf1f52e72011-05-10 02:28:45 -07003235
3236 return status;
3237}
3238
Dan Williams89a73012011-06-30 19:14:33 -07003239enum sci_status sci_task_request_construct(struct isci_host *ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07003240 struct isci_remote_device *idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003241 u16 io_tag, struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003242{
Dan Williams78a6f062011-06-30 16:31:37 -07003243 struct domain_device *dev = idev->domain_dev;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003244 enum sci_status status = SCI_SUCCESS;
3245
3246 /* Build the common part of the request */
Dan Williams89a73012011-06-30 19:14:33 -07003247 sci_general_request_construct(ihost, idev, ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003248
Dan Williamsc72086e2011-05-10 02:28:48 -07003249 if (dev->dev_type == SAS_END_DEV ||
3250 dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
Dan Williams5076a1a2011-06-27 14:57:03 -07003251 set_bit(IREQ_TMF, &ireq->flags);
3252 memset(ireq->tc, 0, sizeof(struct scu_task_context));
Dan Williamsc72086e2011-05-10 02:28:48 -07003253 } else
3254 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003255
3256 return status;
3257}
3258
3259static enum sci_status isci_request_ssp_request_construct(
3260 struct isci_request *request)
3261{
3262 enum sci_status status;
3263
3264 dev_dbg(&request->isci_host->pdev->dev,
3265 "%s: request = %p\n",
3266 __func__,
3267 request);
Dan Williams89a73012011-06-30 19:14:33 -07003268 status = sci_io_request_construct_basic_ssp(request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003269 return status;
3270}
3271
Dan Williams16ba7702011-07-01 10:52:55 -07003272static enum sci_status isci_request_stp_request_construct(struct isci_request *ireq)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003273{
Dan Williams16ba7702011-07-01 10:52:55 -07003274 struct sas_task *task = isci_request_access_task(ireq);
3275 struct host_to_dev_fis *fis = &ireq->stp.cmd;
3276 struct ata_queued_cmd *qc = task->uldd_task;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003277 enum sci_status status;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003278
Dan Williams16ba7702011-07-01 10:52:55 -07003279 dev_dbg(&ireq->isci_host->pdev->dev,
3280 "%s: ireq = %p\n",
Dan Williamsf1f52e72011-05-10 02:28:45 -07003281 __func__,
Dan Williams16ba7702011-07-01 10:52:55 -07003282 ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003283
Dan Williams16ba7702011-07-01 10:52:55 -07003284 memcpy(fis, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
3285 if (!task->ata_task.device_control_reg_update)
3286 fis->flags |= 0x80;
3287 fis->flags &= 0xF0;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003288
Dan Williams16ba7702011-07-01 10:52:55 -07003289 status = sci_io_request_construct_basic_sata(ireq);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003290
Dan Williams16ba7702011-07-01 10:52:55 -07003291 if (qc && (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
3292 qc->tf.command == ATA_CMD_FPDMA_READ)) {
3293 fis->sector_count = qc->tag << 3;
3294 ireq->tc->type.stp.ncq_tag = qc->tag;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003295 }
3296
3297 return status;
3298}
3299
Dan Williamse9bf7092011-06-16 16:59:56 -07003300static enum sci_status
Dan Williams89a73012011-06-30 19:14:33 -07003301sci_io_request_construct_smp(struct device *dev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003302 struct isci_request *ireq,
Dan Williamse9bf7092011-06-16 16:59:56 -07003303 struct sas_task *task)
Dan Williamsc72086e2011-05-10 02:28:48 -07003304{
Dan Williamse9bf7092011-06-16 16:59:56 -07003305 struct scatterlist *sg = &task->smp_task.smp_req;
Dan Williams78a6f062011-06-30 16:31:37 -07003306 struct isci_remote_device *idev;
Dan Williamsc72086e2011-05-10 02:28:48 -07003307 struct scu_task_context *task_context;
Dan Williamsffe191c2011-06-29 13:09:25 -07003308 struct isci_port *iport;
Dan Williamse9bf7092011-06-16 16:59:56 -07003309 struct smp_req *smp_req;
3310 void *kaddr;
3311 u8 req_len;
3312 u32 cmd;
3313
3314 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
3315 smp_req = kaddr + sg->offset;
3316 /*
3317 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
3318 * functions under SAS 2.0, a zero request length really indicates
3319 * a non-zero default length.
3320 */
3321 if (smp_req->req_len == 0) {
3322 switch (smp_req->func) {
3323 case SMP_DISCOVER:
3324 case SMP_REPORT_PHY_ERR_LOG:
3325 case SMP_REPORT_PHY_SATA:
3326 case SMP_REPORT_ROUTE_INFO:
3327 smp_req->req_len = 2;
3328 break;
3329 case SMP_CONF_ROUTE_INFO:
3330 case SMP_PHY_CONTROL:
3331 case SMP_PHY_TEST_FUNCTION:
3332 smp_req->req_len = 9;
3333 break;
3334 /* Default - zero is a valid default for 2.0. */
3335 }
3336 }
3337 req_len = smp_req->req_len;
3338 sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
3339 cmd = *(u32 *) smp_req;
3340 kunmap_atomic(kaddr, KM_IRQ0);
3341
3342 if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
3343 return SCI_FAILURE;
3344
Dan Williams5076a1a2011-06-27 14:57:03 -07003345 ireq->protocol = SCIC_SMP_PROTOCOL;
Dan Williamsc72086e2011-05-10 02:28:48 -07003346
3347 /* byte swap the smp request. */
Dan Williamsc72086e2011-05-10 02:28:48 -07003348
Dan Williams5076a1a2011-06-27 14:57:03 -07003349 task_context = ireq->tc;
Dan Williamsc72086e2011-05-10 02:28:48 -07003350
Dan Williams34a99152011-07-01 02:25:15 -07003351 idev = ireq->target_device;
3352 iport = idev->owning_port;
Dan Williamsc72086e2011-05-10 02:28:48 -07003353
3354 /*
3355 * Fill in the TC with the its required data
3356 * 00h
3357 */
3358 task_context->priority = 0;
3359 task_context->initiator_request = 1;
Dan Williams78a6f062011-06-30 16:31:37 -07003360 task_context->connection_rate = idev->connection_rate;
Dan Williams34a99152011-07-01 02:25:15 -07003361 task_context->protocol_engine_index = ISCI_PEG;
3362 task_context->logical_port_index = iport->physical_port_index;
Dan Williamsc72086e2011-05-10 02:28:48 -07003363 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
3364 task_context->abort = 0;
3365 task_context->valid = SCU_TASK_CONTEXT_VALID;
3366 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
3367
3368 /* 04h */
Dan Williams78a6f062011-06-30 16:31:37 -07003369 task_context->remote_node_index = idev->rnc.remote_node_index;
Dan Williamsc72086e2011-05-10 02:28:48 -07003370 task_context->command_code = 0;
3371 task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
3372
3373 /* 08h */
3374 task_context->link_layer_control = 0;
3375 task_context->do_not_dma_ssp_good_response = 1;
3376 task_context->strict_ordering = 0;
3377 task_context->control_frame = 1;
3378 task_context->timeout_enable = 0;
3379 task_context->block_guard_enable = 0;
3380
3381 /* 0ch */
3382 task_context->address_modifier = 0;
3383
3384 /* 10h */
Dave Jiang77d67382011-05-25 02:21:57 +00003385 task_context->ssp_command_iu_length = req_len;
Dan Williamsc72086e2011-05-10 02:28:48 -07003386
3387 /* 14h */
3388 task_context->transfer_length_bytes = 0;
3389
3390 /*
3391 * 18h ~ 30h, protocol specific
3392 * since commandIU has been build by framework at this point, we just
3393 * copy the frist DWord from command IU to this location. */
Dan Williamse9bf7092011-06-16 16:59:56 -07003394 memcpy(&task_context->type.smp, &cmd, sizeof(u32));
Dan Williamsc72086e2011-05-10 02:28:48 -07003395
3396 /*
3397 * 40h
3398 * "For SMP you could program it to zero. We would prefer that way
3399 * so that done code will be consistent." - Venki
3400 */
3401 task_context->task_phase = 0;
3402
Dan Williams5076a1a2011-06-27 14:57:03 -07003403 ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
Dan Williams34a99152011-07-01 02:25:15 -07003404 (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
3405 (iport->physical_port_index <<
3406 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
3407 ISCI_TAG_TCI(ireq->io_tag));
Dan Williamsc72086e2011-05-10 02:28:48 -07003408 /*
3409 * Copy the physical address for the command buffer to the SCU Task
3410 * Context command buffer should not contain command header.
3411 */
Dan Williamse9bf7092011-06-16 16:59:56 -07003412 task_context->command_iu_upper = upper_32_bits(sg_dma_address(sg));
3413 task_context->command_iu_lower = lower_32_bits(sg_dma_address(sg) + sizeof(u32));
Dan Williamsc72086e2011-05-10 02:28:48 -07003414
3415 /* SMP response comes as UF, so no need to set response IU address. */
3416 task_context->response_iu_upper = 0;
3417 task_context->response_iu_lower = 0;
Dan Williamsc72086e2011-05-10 02:28:48 -07003418
Dan Williams5076a1a2011-06-27 14:57:03 -07003419 sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
Dan Williamsc72086e2011-05-10 02:28:48 -07003420
3421 return SCI_SUCCESS;
3422}
3423
3424/*
Dan Williamsf1f52e72011-05-10 02:28:45 -07003425 * isci_smp_request_build() - This function builds the smp request.
3426 * @ireq: This parameter points to the isci_request allocated in the
3427 * request construct function.
3428 *
3429 * SCI_SUCCESS on successfull completion, or specific failure code.
3430 */
3431static enum sci_status isci_smp_request_build(struct isci_request *ireq)
3432{
Dan Williamsf1f52e72011-05-10 02:28:45 -07003433 struct sas_task *task = isci_request_access_task(ireq);
Dan Williamse9bf7092011-06-16 16:59:56 -07003434 struct device *dev = &ireq->isci_host->pdev->dev;
Dan Williamse9bf7092011-06-16 16:59:56 -07003435 enum sci_status status = SCI_FAILURE;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003436
Dan Williams89a73012011-06-30 19:14:33 -07003437 status = sci_io_request_construct_smp(dev, ireq, task);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003438 if (status != SCI_SUCCESS)
Dan Williamsa8a0a132011-07-01 12:07:25 -07003439 dev_dbg(&ireq->isci_host->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003440 "%s: failed with status = %d\n",
3441 __func__,
3442 status);
3443
3444 return status;
3445}
3446
3447/**
3448 * isci_io_request_build() - This function builds the io request object.
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003449 * @ihost: This parameter specifies the ISCI host object
Dan Williamsf1f52e72011-05-10 02:28:45 -07003450 * @request: This parameter points to the isci_request object allocated in the
3451 * request construct function.
3452 * @sci_device: This parameter is the handle for the sci core's remote device
3453 * object that is the destination for this request.
3454 *
3455 * SCI_SUCCESS on successfull completion, or specific failure code.
3456 */
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003457static enum sci_status isci_io_request_build(struct isci_host *ihost,
Dan Williams312e0c22011-06-28 13:47:09 -07003458 struct isci_request *request,
Dan Williams78a6f062011-06-30 16:31:37 -07003459 struct isci_remote_device *idev)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003460{
3461 enum sci_status status = SCI_SUCCESS;
3462 struct sas_task *task = isci_request_access_task(request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003463
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003464 dev_dbg(&ihost->pdev->dev,
Dan Williams78a6f062011-06-30 16:31:37 -07003465 "%s: idev = 0x%p; request = %p, "
Dan Williamsf1f52e72011-05-10 02:28:45 -07003466 "num_scatter = %d\n",
3467 __func__,
Dan Williams78a6f062011-06-30 16:31:37 -07003468 idev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003469 request,
3470 task->num_scatter);
3471
3472 /* map the sgl addresses, if present.
3473 * libata does the mapping for sata devices
3474 * before we get the request.
3475 */
3476 if (task->num_scatter &&
3477 !sas_protocol_ata(task->task_proto) &&
3478 !(SAS_PROTOCOL_SMP & task->task_proto)) {
3479
3480 request->num_sg_entries = dma_map_sg(
Dan Williamsd9dcb4b2011-06-30 17:38:32 -07003481 &ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003482 task->scatter,
3483 task->num_scatter,
3484 task->data_dir
3485 );
3486
3487 if (request->num_sg_entries == 0)
3488 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
3489 }
3490
Dan Williams89a73012011-06-30 19:14:33 -07003491 status = sci_io_request_construct(ihost, idev, request);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003492
3493 if (status != SCI_SUCCESS) {
Dan Williamsa8a0a132011-07-01 12:07:25 -07003494 dev_dbg(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003495 "%s: failed request construct\n",
3496 __func__);
3497 return SCI_FAILURE;
3498 }
3499
3500 switch (task->task_proto) {
3501 case SAS_PROTOCOL_SMP:
3502 status = isci_smp_request_build(request);
3503 break;
3504 case SAS_PROTOCOL_SSP:
3505 status = isci_request_ssp_request_construct(request);
3506 break;
3507 case SAS_PROTOCOL_SATA:
3508 case SAS_PROTOCOL_STP:
3509 case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
3510 status = isci_request_stp_request_construct(request);
3511 break;
3512 default:
Dan Williamsa8a0a132011-07-01 12:07:25 -07003513 dev_dbg(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003514 "%s: unknown protocol\n", __func__);
3515 return SCI_FAILURE;
3516 }
3517
3518 return SCI_SUCCESS;
3519}
3520
Dan Williamsdb056252011-06-17 14:18:39 -07003521static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003522{
Dan Williams0d0cf142011-06-13 00:51:30 -07003523 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003524
Dan Williamsdb056252011-06-17 14:18:39 -07003525 ireq = ihost->reqs[ISCI_TAG_TCI(tag)];
Dan Williams5076a1a2011-06-27 14:57:03 -07003526 ireq->io_tag = tag;
Dan Williams0d0cf142011-06-13 00:51:30 -07003527 ireq->io_request_completion = NULL;
Dan Williams38d88792011-06-23 14:33:48 -07003528 ireq->flags = 0;
Dan Williams0d0cf142011-06-13 00:51:30 -07003529 ireq->num_sg_entries = 0;
Dan Williams0d0cf142011-06-13 00:51:30 -07003530 INIT_LIST_HEAD(&ireq->completed_node);
3531 INIT_LIST_HEAD(&ireq->dev_node);
Dan Williams0d0cf142011-06-13 00:51:30 -07003532 isci_request_change_state(ireq, allocated);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003533
Dan Williams0d0cf142011-06-13 00:51:30 -07003534 return ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003535}
3536
Dan Williamsdb056252011-06-17 14:18:39 -07003537static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost,
3538 struct sas_task *task,
3539 u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003540{
Dan Williams0d0cf142011-06-13 00:51:30 -07003541 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003542
Dan Williamsdb056252011-06-17 14:18:39 -07003543 ireq = isci_request_from_tag(ihost, tag);
3544 ireq->ttype_ptr.io_task_ptr = task;
Jeff Skirvin3b34c162011-10-27 15:05:22 -07003545 clear_bit(IREQ_TMF, &ireq->flags);
Dan Williamsdb056252011-06-17 14:18:39 -07003546 task->lldd_task = ireq;
3547
Dan Williams0d0cf142011-06-13 00:51:30 -07003548 return ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003549}
3550
Dan Williamsdb056252011-06-17 14:18:39 -07003551struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
3552 struct isci_tmf *isci_tmf,
3553 u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003554{
Dan Williams0d0cf142011-06-13 00:51:30 -07003555 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003556
Dan Williamsdb056252011-06-17 14:18:39 -07003557 ireq = isci_request_from_tag(ihost, tag);
3558 ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
Jeff Skirvin3b34c162011-10-27 15:05:22 -07003559 set_bit(IREQ_TMF, &ireq->flags);
Dan Williamsdb056252011-06-17 14:18:39 -07003560
Dan Williams0d0cf142011-06-13 00:51:30 -07003561 return ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003562}
3563
Dan Williams209fae12011-06-13 17:39:44 -07003564int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev,
Dan Williamsdb056252011-06-17 14:18:39 -07003565 struct sas_task *task, u16 tag)
Dan Williamsf1f52e72011-05-10 02:28:45 -07003566{
Dan Williamsf1f52e72011-05-10 02:28:45 -07003567 enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Dan Williams0d0cf142011-06-13 00:51:30 -07003568 struct isci_request *ireq;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003569 unsigned long flags;
Dan Williams0d0cf142011-06-13 00:51:30 -07003570 int ret = 0;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003571
Dan Williamsf1f52e72011-05-10 02:28:45 -07003572 /* do common allocation and init of request object. */
Dan Williamsdb056252011-06-17 14:18:39 -07003573 ireq = isci_io_request_from_tag(ihost, task, tag);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003574
Dan Williamsdb056252011-06-17 14:18:39 -07003575 status = isci_io_request_build(ihost, ireq, idev);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003576 if (status != SCI_SUCCESS) {
Dan Williamsa8a0a132011-07-01 12:07:25 -07003577 dev_dbg(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003578 "%s: request_construct failed - status = 0x%x\n",
3579 __func__,
3580 status);
Dan Williamsdb056252011-06-17 14:18:39 -07003581 return status;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003582 }
3583
Dan Williams0d0cf142011-06-13 00:51:30 -07003584 spin_lock_irqsave(&ihost->scic_lock, flags);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003585
Jeff Skirvin9274f452011-06-23 17:09:02 -07003586 if (test_bit(IDEV_IO_NCQERROR, &idev->flags)) {
3587
3588 if (isci_task_is_ncq_recovery(task)) {
3589
3590 /* The device is in an NCQ recovery state. Issue the
3591 * request on the task side. Note that it will
3592 * complete on the I/O request side because the
3593 * request was built that way (ie.
3594 * ireq->is_task_management_request is false).
3595 */
Dan Williams89a73012011-06-30 19:14:33 -07003596 status = sci_controller_start_task(ihost,
Dan Williams78a6f062011-06-30 16:31:37 -07003597 idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003598 ireq);
Jeff Skirvin9274f452011-06-23 17:09:02 -07003599 } else {
3600 status = SCI_FAILURE;
3601 }
3602 } else {
Jeff Skirvin9274f452011-06-23 17:09:02 -07003603 /* send the request, let the core assign the IO TAG. */
Dan Williams89a73012011-06-30 19:14:33 -07003604 status = sci_controller_start_io(ihost, idev,
Dan Williams5076a1a2011-06-27 14:57:03 -07003605 ireq);
Jeff Skirvin9274f452011-06-23 17:09:02 -07003606 }
Dan Williams312e0c22011-06-28 13:47:09 -07003607
Dan Williamsf1f52e72011-05-10 02:28:45 -07003608 if (status != SCI_SUCCESS &&
3609 status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
Dan Williamsa8a0a132011-07-01 12:07:25 -07003610 dev_dbg(&ihost->pdev->dev,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003611 "%s: failed request start (0x%x)\n",
3612 __func__, status);
Dan Williams0d0cf142011-06-13 00:51:30 -07003613 spin_unlock_irqrestore(&ihost->scic_lock, flags);
Dan Williamsdb056252011-06-17 14:18:39 -07003614 return status;
Dan Williamsf1f52e72011-05-10 02:28:45 -07003615 }
3616
3617 /* Either I/O started OK, or the core has signaled that
3618 * the device needs a target reset.
3619 *
3620 * In either case, hold onto the I/O for later.
3621 *
3622 * Update it's status and add it to the list in the
3623 * remote device object.
3624 */
Dan Williams0d0cf142011-06-13 00:51:30 -07003625 list_add(&ireq->dev_node, &idev->reqs_in_process);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003626
3627 if (status == SCI_SUCCESS) {
Dan Williams0d0cf142011-06-13 00:51:30 -07003628 isci_request_change_state(ireq, started);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003629 } else {
3630 /* The request did not really start in the
3631 * hardware, so clear the request handle
3632 * here so no terminations will be done.
3633 */
Dan Williams38d88792011-06-23 14:33:48 -07003634 set_bit(IREQ_TERMINATED, &ireq->flags);
Dan Williams0d0cf142011-06-13 00:51:30 -07003635 isci_request_change_state(ireq, completed);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003636 }
Dan Williams0d0cf142011-06-13 00:51:30 -07003637 spin_unlock_irqrestore(&ihost->scic_lock, flags);
Dan Williamsf1f52e72011-05-10 02:28:45 -07003638
3639 if (status ==
3640 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
3641 /* Signal libsas that we need the SCSI error
Dan Williams312e0c22011-06-28 13:47:09 -07003642 * handler thread to work on this I/O and that
3643 * we want a device reset.
3644 */
Dan Williamsf1f52e72011-05-10 02:28:45 -07003645 spin_lock_irqsave(&task->task_state_lock, flags);
3646 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
3647 spin_unlock_irqrestore(&task->task_state_lock, flags);
3648
3649 /* Cause this task to be scheduled in the SCSI error
Dan Williams312e0c22011-06-28 13:47:09 -07003650 * handler thread.
3651 */
Dan Williams0d0cf142011-06-13 00:51:30 -07003652 isci_execpath_callback(ihost, task,
Dan Williamsf1f52e72011-05-10 02:28:45 -07003653 sas_task_abort);
3654
3655 /* Change the status, since we are holding
Dan Williams312e0c22011-06-28 13:47:09 -07003656 * the I/O until it is managed by the SCSI
3657 * error handler.
3658 */
Dan Williamsf1f52e72011-05-10 02:28:45 -07003659 status = SCI_SUCCESS;
3660 }
3661
Dan Williamsf1f52e72011-05-10 02:28:45 -07003662 return ret;
3663}