isci: unify constants
[deliverable/linux.git] / drivers / scsi / isci / core / scic_sds_request.c
CommitLineData
6f231dda
DW
1/*
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
f2f30080 56#include <scsi/sas.h>
6f231dda
DW
57#include "scic_controller.h"
58#include "scic_io_request.h"
6f231dda 59#include "scic_sds_controller.h"
bc99aa47 60#include "scu_registers.h"
6f231dda 61#include "scic_sds_port.h"
88f3b62a 62#include "remote_device.h"
6f231dda
DW
63#include "scic_sds_request.h"
64#include "scic_sds_smp_request.h"
65#include "scic_sds_stp_request.h"
66#include "scic_sds_unsolicited_frame_control.h"
6f231dda 67#include "sci_environment.h"
6f231dda
DW
68#include "sci_util.h"
69#include "scu_completion_codes.h"
6f231dda 70#include "scu_task_context.h"
ce2b3261
DW
71#include "request.h"
72#include "task.h"
6f231dda 73
6f231dda
DW
74/*
75 * ****************************************************************************
76 * * SCIC SDS IO REQUEST CONSTANTS
77 * **************************************************************************** */
78
79/**
80 *
81 *
82 * We have no timer requirements for IO requests right now
83 */
84#define SCIC_SDS_IO_REQUEST_MINIMUM_TIMER_COUNT (0)
85#define SCIC_SDS_IO_REQUEST_MAXIMUM_TIMER_COUNT (0)
86
6f231dda
DW
87/**
88 * This method returns the sgl element pair for the specificed sgl_pair index.
e2023b87 89 * @sci_req: This parameter specifies the IO request for which to retrieve
6f231dda
DW
90 * the Scatter-Gather List element pair.
91 * @sgl_pair_index: This parameter specifies the index into the SGL element
92 * pair to be retrieved.
93 *
94 * This method returns a pointer to an struct scu_sgl_element_pair.
95 */
96static struct scu_sgl_element_pair *scic_sds_request_get_sgl_element_pair(
e2023b87 97 struct scic_sds_request *sci_req,
6f231dda
DW
98 u32 sgl_pair_index
99 ) {
100 struct scu_task_context *task_context;
101
e2023b87 102 task_context = (struct scu_task_context *)sci_req->task_context_buffer;
6f231dda
DW
103
104 if (sgl_pair_index == 0) {
105 return &task_context->sgl_pair_ab;
106 } else if (sgl_pair_index == 1) {
107 return &task_context->sgl_pair_cd;
108 }
109
0d84366f 110 return &sci_req->sg_table[sgl_pair_index - 2];
6f231dda
DW
111}
112
113/**
114 * This function will build the SGL list for an IO request.
e2023b87 115 * @sci_req: This parameter specifies the IO request for which to build
6f231dda
DW
116 * the Scatter-Gather List.
117 *
118 */
6389a775 119void scic_sds_request_build_sgl(struct scic_sds_request *sds_request)
6f231dda 120{
67ea838d 121 struct isci_request *isci_request = sci_req_to_ireq(sds_request);
6389a775
DJ
122 struct isci_host *isci_host = isci_request->isci_host;
123 struct sas_task *task = isci_request_access_task(isci_request);
124 struct scatterlist *sg = NULL;
125 dma_addr_t dma_addr;
126 u32 sg_idx = 0;
127 struct scu_sgl_element_pair *scu_sg = NULL;
128 struct scu_sgl_element_pair *prev_sg = NULL;
129
130 if (task->num_scatter > 0) {
131 sg = task->scatter;
132
133 while (sg) {
134 scu_sg = scic_sds_request_get_sgl_element_pair(
135 sds_request,
136 sg_idx);
137
138 SCU_SGL_COPY(scu_sg->A, sg);
139
140 sg = sg_next(sg);
141
142 if (sg) {
143 SCU_SGL_COPY(scu_sg->B, sg);
144 sg = sg_next(sg);
145 } else
146 SCU_SGL_ZERO(scu_sg->B);
147
148 if (prev_sg) {
149 dma_addr =
150 scic_io_request_get_dma_addr(
151 sds_request,
152 scu_sg);
153
154 prev_sg->next_pair_upper =
155 upper_32_bits(dma_addr);
156 prev_sg->next_pair_lower =
157 lower_32_bits(dma_addr);
158 }
159
160 prev_sg = scu_sg;
161 sg_idx++;
6f231dda 162 }
6389a775
DJ
163 } else { /* handle when no sg */
164 scu_sg = scic_sds_request_get_sgl_element_pair(sds_request,
165 sg_idx);
6f231dda 166
6389a775
DJ
167 dma_addr = dma_map_single(&isci_host->pdev->dev,
168 task->scatter,
169 task->total_xfer_len,
170 task->data_dir);
6f231dda 171
6389a775
DJ
172 isci_request->zero_scatter_daddr = dma_addr;
173
174 scu_sg->A.length = task->total_xfer_len;
175 scu_sg->A.address_upper = upper_32_bits(dma_addr);
176 scu_sg->A.address_lower = lower_32_bits(dma_addr);
6f231dda
DW
177 }
178
6389a775
DJ
179 if (scu_sg) {
180 scu_sg->next_pair_upper = 0;
181 scu_sg->next_pair_lower = 0;
6f231dda
DW
182 }
183}
184
b7645818 185static void scic_sds_ssp_io_request_assign_buffers(struct scic_sds_request *sci_req)
6f231dda 186{
26298264
DW
187 if (sci_req->was_tag_assigned_by_user == false)
188 sci_req->task_context_buffer = &sci_req->tc;
6f231dda
DW
189}
190
0cfa890e 191static void scic_sds_io_request_build_ssp_command_iu(struct scic_sds_request *sci_req)
6f231dda 192{
0cfa890e 193 struct ssp_cmd_iu *cmd_iu;
67ea838d 194 struct isci_request *ireq = sci_req_to_ireq(sci_req);
0cfa890e 195 struct sas_task *task = isci_request_access_task(ireq);
6f231dda 196
b7645818 197 cmd_iu = &sci_req->ssp.cmd;
6f231dda 198
0cfa890e
DJ
199 memcpy(cmd_iu->LUN, task->ssp_task.LUN, 8);
200 cmd_iu->add_cdb_len = 0;
201 cmd_iu->_r_a = 0;
202 cmd_iu->_r_b = 0;
203 cmd_iu->en_fburst = 0; /* unsupported */
204 cmd_iu->task_prio = task->ssp_task.task_prio;
205 cmd_iu->task_attr = task->ssp_task.task_attr;
206 cmd_iu->_r_c = 0;
6f231dda 207
51a57cff
DJ
208 sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
209 sizeof(task->ssp_task.cdb) / sizeof(u32));
6f231dda
DW
210}
211
0cfa890e 212static void scic_sds_task_request_build_ssp_task_iu(struct scic_sds_request *sci_req)
6f231dda 213{
0cfa890e 214 struct ssp_task_iu *task_iu;
67ea838d 215 struct isci_request *ireq = sci_req_to_ireq(sci_req);
0cfa890e
DJ
216 struct sas_task *task = isci_request_access_task(ireq);
217 struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
6f231dda 218
b7645818 219 task_iu = &sci_req->ssp.tmf;
6f231dda 220
0cfa890e 221 memset(task_iu, 0, sizeof(struct ssp_task_iu));
6f231dda 222
0cfa890e 223 memcpy(task_iu->LUN, task->ssp_task.LUN, 8);
6f231dda 224
0cfa890e
DJ
225 task_iu->task_func = isci_tmf->tmf_code;
226 task_iu->task_tag =
227 (ireq->ttype == tmf_task) ?
228 isci_tmf->io_tag :
229 SCI_CONTROLLER_INVALID_IO_TAG;
6f231dda
DW
230}
231
6f231dda
DW
232/**
233 * This method is will fill in the SCU Task Context for any type of SSP request.
e2023b87 234 * @sci_req:
6f231dda
DW
235 * @task_context:
236 *
237 */
238static void scu_ssp_reqeust_construct_task_context(
6389a775 239 struct scic_sds_request *sds_request,
6f231dda
DW
240 struct scu_task_context *task_context)
241{
6389a775
DJ
242 dma_addr_t dma_addr;
243 struct scic_sds_controller *controller;
6f231dda
DW
244 struct scic_sds_remote_device *target_device;
245 struct scic_sds_port *target_port;
246
6389a775
DJ
247 controller = scic_sds_request_get_controller(sds_request);
248 target_device = scic_sds_request_get_device(sds_request);
249 target_port = scic_sds_request_get_port(sds_request);
6f231dda
DW
250
251 /* Fill in the TC with the its required data */
252 task_context->abort = 0;
253 task_context->priority = 0;
254 task_context->initiator_request = 1;
8f304c36 255 task_context->connection_rate = target_device->connection_rate;
6f231dda 256 task_context->protocol_engine_index =
6389a775 257 scic_sds_controller_get_protocol_engine_group(controller);
6f231dda
DW
258 task_context->logical_port_index =
259 scic_sds_port_get_index(target_port);
260 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
261 task_context->valid = SCU_TASK_CONTEXT_VALID;
262 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
263
264 task_context->remote_node_index =
6389a775 265 scic_sds_remote_device_get_index(sds_request->target_device);
6f231dda
DW
266 task_context->command_code = 0;
267
268 task_context->link_layer_control = 0;
269 task_context->do_not_dma_ssp_good_response = 1;
270 task_context->strict_ordering = 0;
271 task_context->control_frame = 0;
272 task_context->timeout_enable = 0;
273 task_context->block_guard_enable = 0;
274
275 task_context->address_modifier = 0;
276
e2023b87 277 /* task_context->type.ssp.tag = sci_req->io_tag; */
6f231dda
DW
278 task_context->task_phase = 0x01;
279
6389a775
DJ
280 if (sds_request->was_tag_assigned_by_user) {
281 /*
282 * Build the task context now since we have already read
283 * the data
284 */
285 sds_request->post_context =
286 (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
287 (scic_sds_controller_get_protocol_engine_group(
288 controller) <<
289 SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
290 (scic_sds_port_get_index(target_port) <<
291 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
292 scic_sds_io_tag_get_index(sds_request->io_tag));
6f231dda 293 } else {
6389a775
DJ
294 /*
295 * Build the task context now since we have already read
296 * the data
297 *
298 * I/O tag index is not assigned because we have to wait
299 * until we get a TCi
300 */
301 sds_request->post_context =
302 (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
303 (scic_sds_controller_get_protocol_engine_group(
304 owning_controller) <<
305 SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
306 (scic_sds_port_get_index(target_port) <<
307 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
6f231dda
DW
308 }
309
6389a775
DJ
310 /*
311 * Copy the physical address for the command buffer to the
312 * SCU Task Context
313 */
314 dma_addr = scic_io_request_get_dma_addr(sds_request,
b7645818 315 &sds_request->ssp.cmd);
6389a775
DJ
316
317 task_context->command_iu_upper = upper_32_bits(dma_addr);
318 task_context->command_iu_lower = lower_32_bits(dma_addr);
319
320 /*
321 * Copy the physical address for the response buffer to the
322 * SCU Task Context
323 */
324 dma_addr = scic_io_request_get_dma_addr(sds_request,
b7645818 325 &sds_request->ssp.rsp);
6389a775
DJ
326
327 task_context->response_iu_upper = upper_32_bits(dma_addr);
328 task_context->response_iu_lower = lower_32_bits(dma_addr);
6f231dda
DW
329}
330
331/**
332 * This method is will fill in the SCU Task Context for a SSP IO request.
e2023b87 333 * @sci_req:
6f231dda
DW
334 *
335 */
336static void scu_ssp_io_request_construct_task_context(
82d29928
DW
337 struct scic_sds_request *sci_req,
338 enum dma_data_direction dir,
339 u32 len)
6f231dda
DW
340{
341 struct scu_task_context *task_context;
342
82d29928 343 task_context = scic_sds_request_get_task_context(sci_req);
6f231dda 344
82d29928 345 scu_ssp_reqeust_construct_task_context(sci_req, task_context);
6f231dda 346
0cfa890e
DJ
347 task_context->ssp_command_iu_length =
348 sizeof(struct ssp_cmd_iu) / sizeof(u32);
8694e792 349 task_context->type.ssp.frame_type = SSP_COMMAND;
6f231dda 350
82d29928
DW
351 switch (dir) {
352 case DMA_FROM_DEVICE:
353 case DMA_NONE:
354 default:
6f231dda
DW
355 task_context->task_type = SCU_TASK_TYPE_IOREAD;
356 break;
82d29928 357 case DMA_TO_DEVICE:
6f231dda
DW
358 task_context->task_type = SCU_TASK_TYPE_IOWRITE;
359 break;
360 }
361
82d29928 362 task_context->transfer_length_bytes = len;
6f231dda 363
82d29928
DW
364 if (task_context->transfer_length_bytes > 0)
365 scic_sds_request_build_sgl(sci_req);
6f231dda
DW
366}
367
b7645818 368static void scic_sds_ssp_task_request_assign_buffers(struct scic_sds_request *sci_req)
6f231dda 369{
26298264
DW
370 if (sci_req->was_tag_assigned_by_user == false)
371 sci_req->task_context_buffer = &sci_req->tc;
6f231dda
DW
372}
373
374/**
375 * This method will fill in the SCU Task Context for a SSP Task request. The
376 * following important settings are utilized: -# priority ==
377 * SCU_TASK_PRIORITY_HIGH. This ensures that the task request is issued
378 * ahead of other task destined for the same Remote Node. -# task_type ==
379 * SCU_TASK_TYPE_IOREAD. This simply indicates that a normal request type
380 * (i.e. non-raw frame) is being utilized to perform task management. -#
381 * control_frame == 1. This ensures that the proper endianess is set so
382 * that the bytes are transmitted in the right order for a task frame.
e2023b87 383 * @sci_req: This parameter specifies the task request object being
6f231dda
DW
384 * constructed.
385 *
386 */
387static void scu_ssp_task_request_construct_task_context(
e2023b87 388 struct scic_sds_request *sci_req)
6f231dda
DW
389{
390 struct scu_task_context *task_context;
391
e2023b87 392 task_context = scic_sds_request_get_task_context(sci_req);
6f231dda 393
e2023b87 394 scu_ssp_reqeust_construct_task_context(sci_req, task_context);
6f231dda
DW
395
396 task_context->control_frame = 1;
397 task_context->priority = SCU_TASK_PRIORITY_HIGH;
398 task_context->task_type = SCU_TASK_TYPE_RAW_FRAME;
399 task_context->transfer_length_bytes = 0;
8694e792 400 task_context->type.ssp.frame_type = SSP_TASK;
0cfa890e
DJ
401 task_context->ssp_command_iu_length =
402 sizeof(struct ssp_task_iu) / sizeof(u32);
6f231dda
DW
403}
404
405
406/**
407 * This method constructs the SSP Command IU data for this ssp passthrough
408 * comand request object.
e2023b87 409 * @sci_req: This parameter specifies the request object for which the SSP
6f231dda
DW
410 * command information unit is being built.
411 *
412 * enum sci_status, returns invalid parameter is cdb > 16
413 */
414
415
416/**
417 * This method constructs the SATA request object.
e2023b87 418 * @sci_req:
6f231dda
DW
419 * @sat_protocol:
420 * @transfer_length:
421 * @data_direction:
422 * @copy_rx_frame:
423 *
424 * enum sci_status
425 */
e76d6180
DJ
426static enum sci_status
427scic_io_request_construct_sata(struct scic_sds_request *sci_req,
428 u32 len,
429 enum dma_data_direction dir,
430 bool copy)
6f231dda
DW
431{
432 enum sci_status status = SCI_SUCCESS;
67ea838d 433 struct isci_request *ireq = sci_req_to_ireq(sci_req);
e76d6180
DJ
434 struct sas_task *task = isci_request_access_task(ireq);
435
436 /* check for management protocols */
437 if (ireq->ttype == tmf_task) {
438 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
439
440 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
441 tmf->tmf_code == isci_tmf_sata_srst_low)
442 return scic_sds_stp_soft_reset_request_construct(sci_req);
443 else {
444 dev_err(scic_to_dev(sci_req->owning_controller),
445 "%s: Request 0x%p received un-handled SAT "
446 "management protocol 0x%x.\n",
447 __func__, sci_req, tmf->tmf_code);
448
449 return SCI_FAILURE;
450 }
451 }
6f231dda 452
e76d6180
DJ
453 if (!sas_protocol_ata(task->task_proto)) {
454 dev_err(scic_to_dev(sci_req->owning_controller),
455 "%s: Non-ATA protocol in SATA path: 0x%x\n",
456 __func__,
457 task->task_proto);
458 return SCI_FAILURE;
6f231dda 459
e76d6180 460 }
6f231dda 461
e76d6180
DJ
462 /* non data */
463 if (task->data_dir == DMA_NONE)
464 return scic_sds_stp_non_data_request_construct(sci_req);
6f231dda 465
e76d6180
DJ
466 /* NCQ */
467 if (task->ata_task.use_ncq)
468 return scic_sds_stp_ncq_request_construct(sci_req, len, dir);
6f231dda 469
e76d6180
DJ
470 /* DMA */
471 if (task->ata_task.dma_xfer)
472 return scic_sds_stp_udma_request_construct(sci_req, len, dir);
473 else /* PIO */
474 return scic_sds_stp_pio_request_construct(sci_req, copy);
6f231dda
DW
475
476 return status;
477}
478
6f231dda
DW
479enum sci_status scic_io_request_construct_basic_ssp(
480 struct scic_sds_request *sci_req)
481{
67ea838d 482 struct isci_request *ireq = sci_req_to_ireq(sci_req);
9286a195 483 struct sas_task *task = isci_request_access_task(ireq);
6f231dda
DW
484
485 sci_req->protocol = SCIC_SSP_PROTOCOL;
486
9286a195
DJ
487 scu_ssp_io_request_construct_task_context(sci_req,
488 task->data_dir,
489 task->total_xfer_len);
6f231dda
DW
490
491 scic_sds_io_request_build_ssp_command_iu(sci_req);
492
9286a195
DJ
493 sci_base_state_machine_change_state(
494 &sci_req->state_machine,
495 SCI_BASE_REQUEST_STATE_CONSTRUCTED);
6f231dda
DW
496
497 return SCI_SUCCESS;
498}
499
500
501enum sci_status scic_task_request_construct_ssp(
502 struct scic_sds_request *sci_req)
503{
504 /* Construct the SSP Task SCU Task Context */
505 scu_ssp_task_request_construct_task_context(sci_req);
506
507 /* Fill in the SSP Task IU */
508 scic_sds_task_request_build_ssp_task_iu(sci_req);
509
38aa74eb
CH
510 sci_base_state_machine_change_state(&sci_req->state_machine,
511 SCI_BASE_REQUEST_STATE_CONSTRUCTED);
6f231dda
DW
512
513 return SCI_SUCCESS;
514}
515
516
7392d275
DJ
517enum sci_status scic_io_request_construct_basic_sata(
518 struct scic_sds_request *sci_req)
6f231dda
DW
519{
520 enum sci_status status;
82d29928 521 struct scic_sds_stp_request *stp_req;
82d29928 522 bool copy = false;
67ea838d 523 struct isci_request *isci_request = sci_req_to_ireq(sci_req);
7392d275 524 struct sas_task *task = isci_request_access_task(isci_request);
6f231dda 525
827a84d4 526 stp_req = &sci_req->stp.req;
6f231dda
DW
527 sci_req->protocol = SCIC_STP_PROTOCOL;
528
7392d275 529 copy = (task->data_dir == DMA_NONE) ? false : true;
6f231dda 530
9286a195
DJ
531 status = scic_io_request_construct_sata(sci_req,
532 task->total_xfer_len,
533 task->data_dir,
534 copy);
6f231dda
DW
535
536 if (status == SCI_SUCCESS)
38aa74eb
CH
537 sci_base_state_machine_change_state(&sci_req->state_machine,
538 SCI_BASE_REQUEST_STATE_CONSTRUCTED);
6f231dda
DW
539
540 return status;
541}
542
543
67ea838d 544enum sci_status scic_task_request_construct_sata(struct scic_sds_request *sci_req)
6f231dda 545{
e76d6180 546 enum sci_status status = SCI_SUCCESS;
67ea838d 547 struct isci_request *ireq = sci_req_to_ireq(sci_req);
e76d6180
DJ
548
549 /* check for management protocols */
550 if (ireq->ttype == tmf_task) {
551 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
552
553 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
554 tmf->tmf_code == isci_tmf_sata_srst_low) {
555 status = scic_sds_stp_soft_reset_request_construct(sci_req);
556 } else {
557 dev_err(scic_to_dev(sci_req->owning_controller),
558 "%s: Request 0x%p received un-handled SAT "
559 "Protocol 0x%x.\n",
560 __func__, sci_req, tmf->tmf_code);
561
562 return SCI_FAILURE;
563 }
6f231dda
DW
564 }
565
566 if (status == SCI_SUCCESS)
e76d6180
DJ
567 sci_base_state_machine_change_state(
568 &sci_req->state_machine,
569 SCI_BASE_REQUEST_STATE_CONSTRUCTED);
6f231dda
DW
570
571 return status;
572}
573
574
575u16 scic_io_request_get_io_tag(
576 struct scic_sds_request *sci_req)
577{
578 return sci_req->io_tag;
579}
580
581
582u32 scic_request_get_controller_status(
583 struct scic_sds_request *sci_req)
584{
585 return sci_req->scu_status;
586}
587
6f231dda
DW
588#define SCU_TASK_CONTEXT_SRAM 0x200000
589u32 scic_io_request_get_number_of_bytes_transferred(
590 struct scic_sds_request *scic_sds_request)
591{
467e855a 592 struct scic_sds_controller *scic = scic_sds_request->owning_controller;
6f231dda
DW
593 u32 ret_val = 0;
594
467e855a
BB
595 if (readl(&scic->smu_registers->address_modifier) == 0) {
596 void __iomem *scu_reg_base = scic->scu_registers;
6f231dda
DW
597 /*
598 * get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where
599 * BAR1 is the scu_registers
600 * 0x20002C = 0x200000 + 0x2c
601 * = start of task context SRAM + offset of (type.ssp.data_offset)
602 * TCi is the io_tag of struct scic_sds_request */
467e855a
BB
603 ret_val = readl(scu_reg_base +
604 (SCU_TASK_CONTEXT_SRAM + offsetof(struct scu_task_context, type.ssp.data_offset)) +
605 ((sizeof(struct scu_task_context)) * scic_sds_io_tag_get_index(scic_sds_request->io_tag)));
6f231dda
DW
606 }
607
608 return ret_val;
609}
610
611
612/*
613 * ****************************************************************************
614 * * SCIC SDS Interface Implementation
615 * **************************************************************************** */
616
38aa74eb
CH
617enum sci_status
618scic_sds_request_start(struct scic_sds_request *request)
6f231dda 619{
524b5f72 620 if (request->device_sequence !=
38aa74eb 621 scic_sds_remote_device_get_sequence(request->target_device))
524b5f72
CH
622 return SCI_FAILURE;
623
624 if (request->state_handlers->start_handler)
38aa74eb 625 return request->state_handlers->start_handler(request);
524b5f72
CH
626
627 dev_warn(scic_to_dev(request->owning_controller),
628 "%s: SCIC IO Request requested to start while in wrong "
629 "state %d\n",
630 __func__,
631 sci_base_state_machine_get_state(&request->state_machine));
632
633 return SCI_FAILURE_INVALID_STATE;
6f231dda
DW
634}
635
38aa74eb
CH
636enum sci_status
637scic_sds_io_request_terminate(struct scic_sds_request *request)
6f231dda 638{
524b5f72
CH
639 if (request->state_handlers->abort_handler)
640 return request->state_handlers->abort_handler(request);
641
642 dev_warn(scic_to_dev(request->owning_controller),
643 "%s: SCIC IO Request requested to abort while in wrong "
644 "state %d\n",
645 __func__,
646 sci_base_state_machine_get_state(&request->state_machine));
647
648 return SCI_FAILURE_INVALID_STATE;
6f231dda
DW
649}
650
38aa74eb
CH
651enum sci_status
652scic_sds_io_request_complete(struct scic_sds_request *request)
6f231dda 653{
524b5f72
CH
654 if (request->state_handlers->complete_handler)
655 return request->state_handlers->complete_handler(request);
656
657 dev_warn(scic_to_dev(request->owning_controller),
658 "%s: SCIC IO Request requested to complete while in wrong "
659 "state %d\n",
660 __func__,
661 sci_base_state_machine_get_state(&request->state_machine));
662
663 return SCI_FAILURE_INVALID_STATE;
6f231dda
DW
664}
665
6f231dda 666enum sci_status scic_sds_io_request_event_handler(
524b5f72 667 struct scic_sds_request *request,
6f231dda
DW
668 u32 event_code)
669{
524b5f72
CH
670 if (request->state_handlers->event_handler)
671 return request->state_handlers->event_handler(request, event_code);
672
673 dev_warn(scic_to_dev(request->owning_controller),
674 "%s: SCIC IO Request given event code notification %x while "
675 "in wrong state %d\n",
676 __func__,
677 event_code,
678 sci_base_state_machine_get_state(&request->state_machine));
679
680 return SCI_FAILURE_INVALID_STATE;
6f231dda
DW
681}
682
524b5f72
CH
683enum sci_status
684scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completion_code)
685{
686 if (request->state_machine.current_state_id == SCI_BASE_REQUEST_STATE_STARTED &&
687 request->has_started_substate_machine == false)
688 return scic_sds_request_started_state_tc_completion_handler(request, completion_code);
689 else if (request->state_handlers->tc_completion_handler)
690 return request->state_handlers->tc_completion_handler(request, completion_code);
691
692 dev_warn(scic_to_dev(request->owning_controller),
693 "%s: SCIC IO Request given task completion notification %x "
694 "while in wrong state %d\n",
695 __func__,
696 completion_code,
697 sci_base_state_machine_get_state(&request->state_machine));
698
699 return SCI_FAILURE_INVALID_STATE;
700
701}
702
703
6f231dda
DW
704/**
705 *
e2023b87 706 * @sci_req: The SCIC_SDS_IO_REQUEST_T object for which the start
6f231dda
DW
707 * operation is to be executed.
708 * @frame_index: The frame index returned by the hardware for the reqeust
709 * object.
710 *
711 * This method invokes the core state frame handler for the
712 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
713 */
714enum sci_status scic_sds_io_request_frame_handler(
524b5f72 715 struct scic_sds_request *request,
6f231dda
DW
716 u32 frame_index)
717{
524b5f72
CH
718 if (request->state_handlers->frame_handler)
719 return request->state_handlers->frame_handler(request, frame_index);
720
721 dev_warn(scic_to_dev(request->owning_controller),
722 "%s: SCIC IO Request given unexpected frame %x while in "
723 "state %d\n",
724 __func__,
725 frame_index,
726 sci_base_state_machine_get_state(&request->state_machine));
727
728 scic_sds_controller_release_frame(request->owning_controller, frame_index);
729 return SCI_FAILURE_INVALID_STATE;
6f231dda
DW
730}
731
6f231dda 732/*
af5ae893 733 * This function copies response data for requests returning response data
6f231dda 734 * instead of sense data.
e2023b87 735 * @sci_req: This parameter specifies the request object for which to copy
6f231dda 736 * the response data.
6f231dda 737 */
af5ae893 738void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req)
6f231dda 739{
af5ae893
DJ
740 void *resp_buf;
741 u32 len;
742 struct ssp_response_iu *ssp_response;
67ea838d 743 struct isci_request *ireq = sci_req_to_ireq(sci_req);
af5ae893 744 struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
6f231dda 745
b7645818 746 ssp_response = &sci_req->ssp.rsp;
6f231dda 747
af5ae893 748 resp_buf = &isci_tmf->resp.resp_iu;
6f231dda 749
af5ae893
DJ
750 len = min_t(u32,
751 SSP_RESP_IU_MAX_SIZE,
752 be32_to_cpu(ssp_response->response_data_len));
6f231dda 753
af5ae893 754 memcpy(resp_buf, ssp_response->resp_data, len);
6f231dda
DW
755}
756
6f231dda
DW
757/*
758 * *****************************************************************************
759 * * CONSTRUCTED STATE HANDLERS
760 * ***************************************************************************** */
761
38aa74eb 762/*
6f231dda
DW
763 * This method implements the action taken when a constructed
764 * SCIC_SDS_IO_REQUEST_T object receives a scic_sds_request_start() request.
765 * This method will, if necessary, allocate a TCi for the io request object and
766 * then will, if necessary, copy the constructed TC data into the actual TC
767 * buffer. If everything is successful the post context field is updated with
768 * the TCi so the controller can post the request to the hardware. enum sci_status
769 * SCI_SUCCESS SCI_FAILURE_INSUFFICIENT_RESOURCES
770 */
771static enum sci_status scic_sds_request_constructed_state_start_handler(
38aa74eb 772 struct scic_sds_request *request)
6f231dda
DW
773{
774 struct scu_task_context *task_context;
6f231dda 775
38aa74eb
CH
776 if (request->io_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
777 request->io_tag =
778 scic_controller_allocate_io_tag(request->owning_controller);
6f231dda
DW
779 }
780
781 /* Record the IO Tag in the request */
38aa74eb
CH
782 if (request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG) {
783 task_context = request->task_context_buffer;
6f231dda 784
38aa74eb 785 task_context->task_index = scic_sds_io_tag_get_index(request->io_tag);
6f231dda
DW
786
787 switch (task_context->protocol_type) {
788 case SCU_TASK_CONTEXT_PROTOCOL_SMP:
789 case SCU_TASK_CONTEXT_PROTOCOL_SSP:
790 /* SSP/SMP Frame */
38aa74eb 791 task_context->type.ssp.tag = request->io_tag;
6f231dda
DW
792 task_context->type.ssp.target_port_transfer_tag = 0xFFFF;
793 break;
794
795 case SCU_TASK_CONTEXT_PROTOCOL_STP:
796 /*
797 * STP/SATA Frame
38aa74eb 798 * task_context->type.stp.ncq_tag = request->ncq_tag; */
6f231dda
DW
799 break;
800
801 case SCU_TASK_CONTEXT_PROTOCOL_NONE:
802 /* / @todo When do we set no protocol type? */
803 break;
804
805 default:
806 /* This should never happen since we build the IO requests */
807 break;
808 }
809
810 /*
811 * Check to see if we need to copy the task context buffer
812 * or have been building into the task context buffer */
38aa74eb 813 if (request->was_tag_assigned_by_user == false) {
6f231dda 814 scic_sds_controller_copy_task_context(
38aa74eb 815 request->owning_controller, request);
6f231dda
DW
816 }
817
818 /* Add to the post_context the io tag value */
38aa74eb 819 request->post_context |= scic_sds_io_tag_get_index(request->io_tag);
6f231dda
DW
820
821 /* Everything is good go ahead and change state */
38aa74eb
CH
822 sci_base_state_machine_change_state(&request->state_machine,
823 SCI_BASE_REQUEST_STATE_STARTED);
6f231dda
DW
824
825 return SCI_SUCCESS;
826 }
827
828 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
829}
830
38aa74eb 831/*
6f231dda
DW
832 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
833 * object receives a scic_sds_request_terminate() request. Since the request
834 * has not yet been posted to the hardware the request transitions to the
835 * completed state. enum sci_status SCI_SUCCESS
836 */
837static enum sci_status scic_sds_request_constructed_state_abort_handler(
38aa74eb 838 struct scic_sds_request *request)
6f231dda 839{
6f231dda
DW
840 /*
841 * This request has been terminated by the user make sure that the correct
842 * status code is returned */
38aa74eb 843 scic_sds_request_set_status(request,
6f231dda 844 SCU_TASK_DONE_TASK_ABORT,
38aa74eb 845 SCI_FAILURE_IO_TERMINATED);
6f231dda 846
38aa74eb
CH
847 sci_base_state_machine_change_state(&request->state_machine,
848 SCI_BASE_REQUEST_STATE_COMPLETED);
6f231dda
DW
849 return SCI_SUCCESS;
850}
851
852/*
853 * *****************************************************************************
854 * * STARTED STATE HANDLERS
855 * ***************************************************************************** */
856
38aa74eb 857/*
6f231dda
DW
858 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
859 * object receives a scic_sds_request_terminate() request. Since the request
860 * has been posted to the hardware the io request state is changed to the
861 * aborting state. enum sci_status SCI_SUCCESS
862 */
863enum sci_status scic_sds_request_started_state_abort_handler(
38aa74eb 864 struct scic_sds_request *request)
6f231dda 865{
38aa74eb
CH
866 if (request->has_started_substate_machine)
867 sci_base_state_machine_stop(&request->started_substate_machine);
6f231dda 868
38aa74eb
CH
869 sci_base_state_machine_change_state(&request->state_machine,
870 SCI_BASE_REQUEST_STATE_ABORTING);
6f231dda
DW
871 return SCI_SUCCESS;
872}
873
af5ae893 874/*
6f231dda
DW
875 * scic_sds_request_started_state_tc_completion_handler() - This method process
876 * TC (task context) completions for normal IO request (i.e. Task/Abort
877 * Completions of type 0). This method will update the
878 * SCIC_SDS_IO_REQUEST_T::status field.
e2023b87 879 * @sci_req: This parameter specifies the request for which a completion
6f231dda
DW
880 * occurred.
881 * @completion_code: This parameter specifies the completion code received from
882 * the SCU.
883 *
884 */
af5ae893
DJ
885enum sci_status
886scic_sds_request_started_state_tc_completion_handler(
887 struct scic_sds_request *sci_req,
888 u32 completion_code)
6f231dda 889{
af5ae893
DJ
890 u8 datapres;
891 struct ssp_response_iu *resp_iu;
6f231dda 892
af5ae893
DJ
893 /*
894 * TODO: Any SDMA return code of other than 0 is bad
6f231dda
DW
895 * decode 0x003C0000 to determine SDMA status
896 */
897 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
898 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
af5ae893
DJ
899 scic_sds_request_set_status(sci_req,
900 SCU_TASK_DONE_GOOD,
901 SCI_SUCCESS);
6f231dda
DW
902 break;
903
904 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP):
905 {
906 /*
af5ae893
DJ
907 * There are times when the SCU hardware will return an early
908 * response because the io request specified more data than is
909 * returned by the target device (mode pages, inquiry data,
910 * etc.). We must check the response stats to see if this is
911 * truly a failed request or a good request that just got
912 * completed early.
913 */
b7645818 914 struct ssp_response_iu *resp = &sci_req->ssp.rsp;
51a57cff
DJ
915 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
916
b7645818
DW
917 sci_swab32_cpy(&sci_req->ssp.rsp,
918 &sci_req->ssp.rsp,
51a57cff 919 word_cnt);
6f231dda 920
af5ae893 921 if (resp->status == 0) {
6f231dda 922 scic_sds_request_set_status(
af5ae893
DJ
923 sci_req,
924 SCU_TASK_DONE_GOOD,
925 SCI_SUCCESS_IO_DONE_EARLY);
6f231dda
DW
926 } else {
927 scic_sds_request_set_status(
e2023b87 928 sci_req,
6f231dda 929 SCU_TASK_DONE_CHECK_RESPONSE,
af5ae893 930 SCI_FAILURE_IO_RESPONSE_VALID);
6f231dda
DW
931 }
932 }
933 break;
934
935 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE):
51a57cff
DJ
936 {
937 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
6f231dda 938
b7645818
DW
939 sci_swab32_cpy(&sci_req->ssp.rsp,
940 &sci_req->ssp.rsp,
51a57cff
DJ
941 word_cnt);
942
943 scic_sds_request_set_status(sci_req,
944 SCU_TASK_DONE_CHECK_RESPONSE,
945 SCI_FAILURE_IO_RESPONSE_VALID);
6f231dda 946 break;
51a57cff 947 }
6f231dda
DW
948
949 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
950 /*
af5ae893
DJ
951 * / @todo With TASK_DONE_RESP_LEN_ERR is the response frame
952 * guaranteed to be received before this completion status is
953 * posted?
954 */
b7645818 955 resp_iu = &sci_req->ssp.rsp;
af5ae893
DJ
956 datapres = resp_iu->datapres;
957
958 if ((datapres == 0x01) || (datapres == 0x02)) {
6f231dda 959 scic_sds_request_set_status(
e2023b87 960 sci_req,
6f231dda 961 SCU_TASK_DONE_CHECK_RESPONSE,
af5ae893
DJ
962 SCI_FAILURE_IO_RESPONSE_VALID);
963 } else
6f231dda 964 scic_sds_request_set_status(
af5ae893 965 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS);
6f231dda
DW
966 break;
967
968 /* only stp device gets suspended. */
969 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
970 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR):
971 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR):
972 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR):
973 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR):
974 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN):
975 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
976 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP):
977 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS):
978 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
979 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR):
e2023b87 980 if (sci_req->protocol == SCIC_STP_PROTOCOL) {
6f231dda 981 scic_sds_request_set_status(
e2023b87 982 sci_req,
af5ae893
DJ
983 SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
984 SCU_COMPLETION_TL_STATUS_SHIFT,
985 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED);
6f231dda
DW
986 } else {
987 scic_sds_request_set_status(
e2023b87 988 sci_req,
af5ae893
DJ
989 SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
990 SCU_COMPLETION_TL_STATUS_SHIFT,
991 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR);
6f231dda
DW
992 }
993 break;
994
995 /* both stp/ssp device gets suspended */
996 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR):
997 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION):
998 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1):
999 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2):
1000 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3):
1001 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION):
1002 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION):
1003 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY):
1004 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED):
1005 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
1006 scic_sds_request_set_status(
e2023b87 1007 sci_req,
af5ae893
DJ
1008 SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
1009 SCU_COMPLETION_TL_STATUS_SHIFT,
1010 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED);
6f231dda
DW
1011 break;
1012
1013 /* neither ssp nor stp gets suspended. */
1014 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR):
1015 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR):
1016 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR):
1017 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR):
1018 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR):
1019 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA):
1020 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
1021 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
1022 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
1023 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
1024 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA):
1025 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL):
1026 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV):
1027 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV):
1028 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND):
1029 default:
1030 scic_sds_request_set_status(
e2023b87 1031 sci_req,
af5ae893
DJ
1032 SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
1033 SCU_COMPLETION_TL_STATUS_SHIFT,
1034 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR);
6f231dda
DW
1035 break;
1036 }
1037
af5ae893
DJ
1038 /*
1039 * TODO: This is probably wrong for ACK/NAK timeout conditions
6f231dda
DW
1040 */
1041
af5ae893
DJ
1042 /* In all cases we will treat this as the completion of the IO req. */
1043 sci_base_state_machine_change_state(
1044 &sci_req->state_machine,
1045 SCI_BASE_REQUEST_STATE_COMPLETED);
6f231dda
DW
1046 return SCI_SUCCESS;
1047}
1048
38aa74eb 1049/*
6f231dda
DW
1050 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1051 * object receives a scic_sds_request_frame_handler() request. This method
1052 * first determines the frame type received. If this is a response frame then
1053 * the response data is copied to the io request response buffer for processing
1054 * at completion time. If the frame type is not a response buffer an error is
1055 * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE
1056 */
af5ae893
DJ
1057static enum sci_status
1058scic_sds_request_started_state_frame_handler(struct scic_sds_request *sci_req,
1059 u32 frame_index)
6f231dda
DW
1060{
1061 enum sci_status status;
2d9c2240
DJ
1062 u32 *frame_header;
1063 struct ssp_frame_hdr ssp_hdr;
1064 ssize_t word_cnt;
6f231dda 1065
6f231dda 1066 status = scic_sds_unsolicited_frame_control_get_header(
e2023b87 1067 &(scic_sds_request_get_controller(sci_req)->uf_control),
6f231dda 1068 frame_index,
af5ae893 1069 (void **)&frame_header);
6f231dda 1070
2d9c2240
DJ
1071 word_cnt = sizeof(struct ssp_frame_hdr) / sizeof(u32);
1072 sci_swab32_cpy(&ssp_hdr, frame_header, word_cnt);
1073
1074 if (ssp_hdr.frame_type == SSP_RESPONSE) {
af5ae893 1075 struct ssp_response_iu *resp_iu;
51a57cff 1076 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
6f231dda
DW
1077
1078 status = scic_sds_unsolicited_frame_control_get_buffer(
e2023b87 1079 &(scic_sds_request_get_controller(sci_req)->uf_control),
6f231dda 1080 frame_index,
af5ae893 1081 (void **)&resp_iu);
6f231dda 1082
b7645818 1083 sci_swab32_cpy(&sci_req->ssp.rsp,
51a57cff 1084 resp_iu, word_cnt);
6f231dda 1085
b7645818 1086 resp_iu = &sci_req->ssp.rsp;
6f231dda 1087
af5ae893
DJ
1088 if ((resp_iu->datapres == 0x01) ||
1089 (resp_iu->datapres == 0x02)) {
6f231dda 1090 scic_sds_request_set_status(
e2023b87 1091 sci_req,
6f231dda 1092 SCU_TASK_DONE_CHECK_RESPONSE,
af5ae893 1093 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR);
6f231dda
DW
1094 } else
1095 scic_sds_request_set_status(
af5ae893
DJ
1096 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS);
1097 } else {
6f231dda 1098 /* This was not a response frame why did it get forwarded? */
e2023b87 1099 dev_err(scic_to_dev(sci_req->owning_controller),
6f231dda
DW
1100 "%s: SCIC IO Request 0x%p received unexpected "
1101 "frame %d type 0x%02x\n",
1102 __func__,
e2023b87 1103 sci_req,
6f231dda 1104 frame_index,
2d9c2240 1105 ssp_hdr.frame_type);
af5ae893 1106 }
6f231dda
DW
1107
1108 /*
1109 * In any case we are done with this frame buffer return it to the
af5ae893
DJ
1110 * controller
1111 */
6f231dda 1112 scic_sds_controller_release_frame(
af5ae893 1113 sci_req->owning_controller, frame_index);
6f231dda
DW
1114
1115 return SCI_SUCCESS;
1116}
1117
1118/*
1119 * *****************************************************************************
1120 * * COMPLETED STATE HANDLERS
1121 * ***************************************************************************** */
1122
1123
38aa74eb 1124/*
6f231dda
DW
1125 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1126 * object receives a scic_sds_request_complete() request. This method frees up
1127 * any io request resources that have been allocated and transitions the
1128 * request to its final state. Consider stopping the state machine instead of
1129 * transitioning to the final state? enum sci_status SCI_SUCCESS
1130 */
1131static enum sci_status scic_sds_request_completed_state_complete_handler(
38aa74eb 1132 struct scic_sds_request *request)
6f231dda 1133{
38aa74eb 1134 if (request->was_tag_assigned_by_user != true) {
6f231dda 1135 scic_controller_free_io_tag(
38aa74eb 1136 request->owning_controller, request->io_tag);
6f231dda
DW
1137 }
1138
38aa74eb 1139 if (request->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX) {
6f231dda 1140 scic_sds_controller_release_frame(
38aa74eb 1141 request->owning_controller, request->saved_rx_frame_index);
6f231dda
DW
1142 }
1143
38aa74eb
CH
1144 sci_base_state_machine_change_state(&request->state_machine,
1145 SCI_BASE_REQUEST_STATE_FINAL);
6f231dda
DW
1146 return SCI_SUCCESS;
1147}
1148
1149/*
1150 * *****************************************************************************
1151 * * ABORTING STATE HANDLERS
1152 * ***************************************************************************** */
1153
38aa74eb 1154/*
6f231dda
DW
1155 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1156 * object receives a scic_sds_request_terminate() request. This method is the
1157 * io request aborting state abort handlers. On receipt of a multiple
1158 * terminate requests the io request will transition to the completed state.
1159 * This should not happen in normal operation. enum sci_status SCI_SUCCESS
1160 */
1161static enum sci_status scic_sds_request_aborting_state_abort_handler(
38aa74eb 1162 struct scic_sds_request *request)
6f231dda 1163{
38aa74eb
CH
1164 sci_base_state_machine_change_state(&request->state_machine,
1165 SCI_BASE_REQUEST_STATE_COMPLETED);
6f231dda
DW
1166 return SCI_SUCCESS;
1167}
1168
38aa74eb 1169/*
6f231dda
DW
1170 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1171 * object receives a scic_sds_request_task_completion() request. This method
1172 * decodes the completion type waiting for the abort task complete
1173 * notification. When the abort task complete is received the io request
1174 * transitions to the completed state. enum sci_status SCI_SUCCESS
1175 */
1176static enum sci_status scic_sds_request_aborting_state_tc_completion_handler(
e2023b87 1177 struct scic_sds_request *sci_req,
6f231dda
DW
1178 u32 completion_code)
1179{
1180 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1181 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
1182 case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT):
1183 scic_sds_request_set_status(
e2023b87 1184 sci_req, SCU_TASK_DONE_TASK_ABORT, SCI_FAILURE_IO_TERMINATED
6f231dda
DW
1185 );
1186
e2023b87 1187 sci_base_state_machine_change_state(&sci_req->state_machine,
38aa74eb 1188 SCI_BASE_REQUEST_STATE_COMPLETED);
6f231dda
DW
1189 break;
1190
1191 default:
1192 /*
1193 * Unless we get some strange error wait for the task abort to complete
1194 * TODO: Should there be a state change for this completion? */
1195 break;
1196 }
1197
1198 return SCI_SUCCESS;
1199}
1200
38aa74eb 1201/*
6f231dda
DW
1202 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1203 * object receives a scic_sds_request_frame_handler() request. This method
1204 * discards the unsolicited frame since we are waiting for the abort task
1205 * completion. enum sci_status SCI_SUCCESS
1206 */
1207static enum sci_status scic_sds_request_aborting_state_frame_handler(
e2023b87 1208 struct scic_sds_request *sci_req,
6f231dda
DW
1209 u32 frame_index)
1210{
1211 /* TODO: Is it even possible to get an unsolicited frame in the aborting state? */
1212
1213 scic_sds_controller_release_frame(
e2023b87 1214 sci_req->owning_controller, frame_index);
6f231dda
DW
1215
1216 return SCI_SUCCESS;
1217}
1218
35173d57 1219static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = {
6f231dda 1220 [SCI_BASE_REQUEST_STATE_INITIAL] = {
6f231dda
DW
1221 },
1222 [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {
38aa74eb
CH
1223 .start_handler = scic_sds_request_constructed_state_start_handler,
1224 .abort_handler = scic_sds_request_constructed_state_abort_handler,
6f231dda
DW
1225 },
1226 [SCI_BASE_REQUEST_STATE_STARTED] = {
38aa74eb 1227 .abort_handler = scic_sds_request_started_state_abort_handler,
38aa74eb 1228 .tc_completion_handler = scic_sds_request_started_state_tc_completion_handler,
38aa74eb 1229 .frame_handler = scic_sds_request_started_state_frame_handler,
6f231dda
DW
1230 },
1231 [SCI_BASE_REQUEST_STATE_COMPLETED] = {
38aa74eb 1232 .complete_handler = scic_sds_request_completed_state_complete_handler,
6f231dda
DW
1233 },
1234 [SCI_BASE_REQUEST_STATE_ABORTING] = {
38aa74eb 1235 .abort_handler = scic_sds_request_aborting_state_abort_handler,
38aa74eb 1236 .tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler,
38aa74eb 1237 .frame_handler = scic_sds_request_aborting_state_frame_handler,
6f231dda
DW
1238 },
1239 [SCI_BASE_REQUEST_STATE_FINAL] = {
6f231dda
DW
1240 },
1241};
1242
1243/**
1244 * scic_sds_request_initial_state_enter() -
1245 * @object: This parameter specifies the base object for which the state
1246 * transition is occurring.
1247 *
1248 * This method implements the actions taken when entering the
1249 * SCI_BASE_REQUEST_STATE_INITIAL state. This state is entered when the initial
1250 * base request is constructed. Entry into the initial state sets all handlers
1251 * for the io request object to their default handlers. none
1252 */
9a0fff7b 1253static void scic_sds_request_initial_state_enter(void *object)
6f231dda 1254{
890cae9b 1255 struct scic_sds_request *sci_req = object;
6f231dda
DW
1256
1257 SET_STATE_HANDLER(
e2023b87 1258 sci_req,
6f231dda
DW
1259 scic_sds_request_state_handler_table,
1260 SCI_BASE_REQUEST_STATE_INITIAL
1261 );
1262}
1263
1264/**
1265 * scic_sds_request_constructed_state_enter() -
1266 * @object: The io request object that is to enter the constructed state.
1267 *
1268 * This method implements the actions taken when entering the
1269 * SCI_BASE_REQUEST_STATE_CONSTRUCTED state. The method sets the state handlers
1270 * for the the constructed state. none
1271 */
9a0fff7b 1272static void scic_sds_request_constructed_state_enter(void *object)
6f231dda 1273{
890cae9b 1274 struct scic_sds_request *sci_req = object;
6f231dda
DW
1275
1276 SET_STATE_HANDLER(
e2023b87 1277 sci_req,
6f231dda
DW
1278 scic_sds_request_state_handler_table,
1279 SCI_BASE_REQUEST_STATE_CONSTRUCTED
1280 );
1281}
1282
1283/**
1284 * scic_sds_request_started_state_enter() -
1285 * @object: This parameter specifies the base object for which the state
9a0fff7b 1286 * transition is occurring. This is cast into a SCIC_SDS_IO_REQUEST object.
6f231dda
DW
1287 *
1288 * This method implements the actions taken when entering the
1289 * SCI_BASE_REQUEST_STATE_STARTED state. If the io request object type is a
1290 * SCSI Task request we must enter the started substate machine. none
1291 */
9a0fff7b 1292static void scic_sds_request_started_state_enter(void *object)
6f231dda 1293{
890cae9b 1294 struct scic_sds_request *sci_req = object;
6f231dda
DW
1295
1296 SET_STATE_HANDLER(
e2023b87 1297 sci_req,
6f231dda
DW
1298 scic_sds_request_state_handler_table,
1299 SCI_BASE_REQUEST_STATE_STARTED
1300 );
1301
1302 /*
1303 * Most of the request state machines have a started substate machine so
1304 * start its execution on the entry to the started state. */
e2023b87
DJ
1305 if (sci_req->has_started_substate_machine == true)
1306 sci_base_state_machine_start(&sci_req->started_substate_machine);
6f231dda
DW
1307}
1308
1309/**
1310 * scic_sds_request_started_state_exit() -
1311 * @object: This parameter specifies the base object for which the state
9a0fff7b 1312 * transition is occurring. This object is cast into a SCIC_SDS_IO_REQUEST
6f231dda
DW
1313 * object.
1314 *
1315 * This method implements the actions taken when exiting the
1316 * SCI_BASE_REQUEST_STATE_STARTED state. For task requests the action will be
1317 * to stop the started substate machine. none
1318 */
9a0fff7b 1319static void scic_sds_request_started_state_exit(void *object)
6f231dda 1320{
890cae9b 1321 struct scic_sds_request *sci_req = object;
6f231dda 1322
e2023b87
DJ
1323 if (sci_req->has_started_substate_machine == true)
1324 sci_base_state_machine_stop(&sci_req->started_substate_machine);
6f231dda
DW
1325}
1326
1327/**
1328 * scic_sds_request_completed_state_enter() -
1329 * @object: This parameter specifies the base object for which the state
9a0fff7b 1330 * transition is occurring. This object is cast into a SCIC_SDS_IO_REQUEST
6f231dda
DW
1331 * object.
1332 *
1333 * This method implements the actions taken when entering the
1334 * SCI_BASE_REQUEST_STATE_COMPLETED state. This state is entered when the
1335 * SCIC_SDS_IO_REQUEST has completed. The method will decode the request
1336 * completion status and convert it to an enum sci_status to return in the
1337 * completion callback function. none
1338 */
9a0fff7b 1339static void scic_sds_request_completed_state_enter(void *object)
6f231dda 1340{
890cae9b 1341 struct scic_sds_request *sci_req = object;
09d7da13
DJ
1342 struct scic_sds_controller *scic =
1343 scic_sds_request_get_controller(sci_req);
cc3dbd0a 1344 struct isci_host *ihost = scic_to_ihost(scic);
67ea838d 1345 struct isci_request *ireq = sci_req_to_ireq(sci_req);
6f231dda 1346
09d7da13
DJ
1347 SET_STATE_HANDLER(sci_req,
1348 scic_sds_request_state_handler_table,
1349 SCI_BASE_REQUEST_STATE_COMPLETED);
6f231dda
DW
1350
1351 /* Tell the SCI_USER that the IO request is complete */
09d7da13
DJ
1352 if (sci_req->is_task_management_request == false)
1353 isci_request_io_request_complete(ihost,
1354 ireq,
1355 sci_req->sci_status);
1356 else
1357 isci_task_request_complete(ihost, ireq, sci_req->sci_status);
6f231dda
DW
1358}
1359
1360/**
1361 * scic_sds_request_aborting_state_enter() -
1362 * @object: This parameter specifies the base object for which the state
9a0fff7b 1363 * transition is occurring. This object is cast into a SCIC_SDS_IO_REQUEST
6f231dda
DW
1364 * object.
1365 *
1366 * This method implements the actions taken when entering the
1367 * SCI_BASE_REQUEST_STATE_ABORTING state. none
1368 */
9a0fff7b 1369static void scic_sds_request_aborting_state_enter(void *object)
6f231dda 1370{
890cae9b 1371 struct scic_sds_request *sci_req = object;
6f231dda
DW
1372
1373 /* Setting the abort bit in the Task Context is required by the silicon. */
e2023b87 1374 sci_req->task_context_buffer->abort = 1;
6f231dda
DW
1375
1376 SET_STATE_HANDLER(
e2023b87 1377 sci_req,
6f231dda
DW
1378 scic_sds_request_state_handler_table,
1379 SCI_BASE_REQUEST_STATE_ABORTING
1380 );
1381}
1382
1383/**
1384 * scic_sds_request_final_state_enter() -
1385 * @object: This parameter specifies the base object for which the state
9a0fff7b 1386 * transition is occurring. This is cast into a SCIC_SDS_IO_REQUEST object.
6f231dda
DW
1387 *
1388 * This method implements the actions taken when entering the
1389 * SCI_BASE_REQUEST_STATE_FINAL state. The only action required is to put the
1390 * state handlers in place. none
1391 */
9a0fff7b 1392static void scic_sds_request_final_state_enter(void *object)
6f231dda 1393{
890cae9b 1394 struct scic_sds_request *sci_req = object;
6f231dda
DW
1395
1396 SET_STATE_HANDLER(
e2023b87 1397 sci_req,
6f231dda
DW
1398 scic_sds_request_state_handler_table,
1399 SCI_BASE_REQUEST_STATE_FINAL
1400 );
1401}
1402
35173d57 1403static const struct sci_base_state scic_sds_request_state_table[] = {
6f231dda
DW
1404 [SCI_BASE_REQUEST_STATE_INITIAL] = {
1405 .enter_state = scic_sds_request_initial_state_enter,
1406 },
1407 [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {
1408 .enter_state = scic_sds_request_constructed_state_enter,
1409 },
1410 [SCI_BASE_REQUEST_STATE_STARTED] = {
1411 .enter_state = scic_sds_request_started_state_enter,
1412 .exit_state = scic_sds_request_started_state_exit
1413 },
1414 [SCI_BASE_REQUEST_STATE_COMPLETED] = {
1415 .enter_state = scic_sds_request_completed_state_enter,
1416 },
1417 [SCI_BASE_REQUEST_STATE_ABORTING] = {
1418 .enter_state = scic_sds_request_aborting_state_enter,
1419 },
1420 [SCI_BASE_REQUEST_STATE_FINAL] = {
1421 .enter_state = scic_sds_request_final_state_enter,
1422 },
1423};
1424
35173d57
DW
1425static void scic_sds_general_request_construct(struct scic_sds_controller *scic,
1426 struct scic_sds_remote_device *sci_dev,
67ea838d 1427 u16 io_tag, struct scic_sds_request *sci_req)
35173d57 1428{
890cae9b 1429 sci_base_state_machine_construct(&sci_req->state_machine, sci_req,
38aa74eb
CH
1430 scic_sds_request_state_table, SCI_BASE_REQUEST_STATE_INITIAL);
1431 sci_base_state_machine_start(&sci_req->state_machine);
1432
35173d57 1433 sci_req->io_tag = io_tag;
35173d57
DW
1434 sci_req->owning_controller = scic;
1435 sci_req->target_device = sci_dev;
1436 sci_req->has_started_substate_machine = false;
1437 sci_req->protocol = SCIC_NO_PROTOCOL;
1438 sci_req->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX;
1439 sci_req->device_sequence = scic_sds_remote_device_get_sequence(sci_dev);
1440
1441 sci_req->sci_status = SCI_SUCCESS;
1442 sci_req->scu_status = 0;
1443 sci_req->post_context = 0xFFFFFFFF;
1444
1445 sci_req->is_task_management_request = false;
1446
1447 if (io_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
1448 sci_req->was_tag_assigned_by_user = false;
1449 sci_req->task_context_buffer = NULL;
1450 } else {
1451 sci_req->was_tag_assigned_by_user = true;
1452
1453 sci_req->task_context_buffer =
1454 scic_sds_controller_get_task_context_buffer(scic, io_tag);
1455 }
1456}
1457
2ec53eb4
DJ
1458enum sci_status
1459scic_io_request_construct(struct scic_sds_controller *scic,
1460 struct scic_sds_remote_device *sci_dev,
67ea838d 1461 u16 io_tag, struct scic_sds_request *sci_req)
35173d57 1462{
a1a113b0 1463 struct domain_device *dev = sci_dev_to_domain(sci_dev);
35173d57 1464 enum sci_status status = SCI_SUCCESS;
35173d57
DW
1465
1466 /* Build the common part of the request */
67ea838d 1467 scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req);
2ec53eb4
DJ
1468
1469 if (sci_dev->rnc.remote_node_index ==
1470 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
35173d57
DW
1471 return SCI_FAILURE_INVALID_REMOTE_DEVICE;
1472
2ec53eb4 1473 if (dev->dev_type == SAS_END_DEV)
35173d57 1474 scic_sds_ssp_io_request_assign_buffers(sci_req);
2ec53eb4
DJ
1475 else if ((dev->dev_type == SATA_DEV) ||
1476 (dev->tproto & SAS_PROTOCOL_STP)) {
35173d57 1477 scic_sds_stp_request_assign_buffers(sci_req);
b7645818 1478 memset(&sci_req->stp.cmd, 0, sizeof(sci_req->stp.cmd));
a1a113b0 1479 } else if (dev_is_expander(dev)) {
35173d57 1480 scic_sds_smp_request_assign_buffers(sci_req);
b7645818 1481 memset(&sci_req->smp.cmd, 0, sizeof(sci_req->smp.cmd));
a1a113b0 1482 } else
35173d57 1483 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
35173d57
DW
1484
1485 if (status == SCI_SUCCESS) {
67ea838d
DW
1486 memset(sci_req->task_context_buffer, 0,
1487 offsetof(struct scu_task_context, sgl_pair_ab));
35173d57
DW
1488 }
1489
1490 return status;
1491}
1492
1493enum sci_status scic_task_request_construct(struct scic_sds_controller *scic,
1494 struct scic_sds_remote_device *sci_dev,
67ea838d 1495 u16 io_tag, struct scic_sds_request *sci_req)
35173d57 1496{
a1a113b0 1497 struct domain_device *dev = sci_dev_to_domain(sci_dev);
35173d57 1498 enum sci_status status = SCI_SUCCESS;
35173d57
DW
1499
1500 /* Build the common part of the request */
67ea838d 1501 scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req);
35173d57 1502
a1a113b0 1503 if (dev->dev_type == SAS_END_DEV) {
35173d57
DW
1504 scic_sds_ssp_task_request_assign_buffers(sci_req);
1505
1506 sci_req->has_started_substate_machine = true;
1507
1508 /* Construct the started sub-state machine. */
1509 sci_base_state_machine_construct(
1510 &sci_req->started_substate_machine,
890cae9b 1511 sci_req,
35173d57
DW
1512 scic_sds_io_request_started_task_mgmt_substate_table,
1513 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
1514 );
a1a113b0 1515 } else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
35173d57 1516 scic_sds_stp_request_assign_buffers(sci_req);
a1a113b0 1517 else
35173d57 1518 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
35173d57
DW
1519
1520 if (status == SCI_SUCCESS) {
1521 sci_req->is_task_management_request = true;
1522 memset(sci_req->task_context_buffer, 0, sizeof(struct scu_task_context));
35173d57
DW
1523 }
1524
1525 return status;
1526}
This page took 0.112482 seconds and 5 git commands to generate.