isci: namespacecheck cleanups
[deliverable/linux.git] / drivers / scsi / isci / core / scic_sds_stp_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
56
57#include "intel_ata.h"
58#include "intel_sata.h"
59#include "intel_sat.h"
60#include "sci_base_state.h"
61#include "sci_base_state_machine.h"
62#include "scic_io_request.h"
63#include "scic_remote_device.h"
64#include "scic_sds_controller.h"
65#include "scic_sds_remote_device.h"
66#include "scic_sds_request.h"
67#include "scic_sds_stp_pio_request.h"
68#include "scic_sds_stp_request.h"
69#include "scic_sds_unsolicited_frame_control.h"
6f231dda 70#include "sci_environment.h"
6f231dda
DW
71#include "sci_util.h"
72#include "scu_completion_codes.h"
73#include "scu_event_codes.h"
74#include "scu_task_context.h"
75
76/**
77 * scic_sds_stp_request_get_h2d_reg_buffer() -
78 *
79 * This macro returns the address of the stp h2d reg fis buffer in the io
80 * request memory
81 */
82#define scic_sds_stp_request_get_h2d_reg_buffer(memory) \
83 ((struct sata_fis_reg_h2d *)(\
84 ((char *)(memory)) + sizeof(struct scic_sds_stp_request) \
85 ))
86
87/**
88 * scic_sds_stp_request_get_response_buffer() -
89 *
90 * This macro returns the address of the ssp response iu buffer in the io
91 * request memory
92 */
93#define scic_sds_stp_request_get_response_buffer(memory) \
94 ((struct sata_fis_reg_d2h *)(\
95 ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \
96 + sizeof(struct sata_fis_reg_h2d) \
97 ))
98
99/**
100 * scic_sds_stp_request_get_task_context_buffer() -
101 *
102 * This macro returns the address of the task context buffer in the io request
103 * memory
104 */
105#define scic_sds_stp_request_get_task_context_buffer(memory) \
106 ((struct scu_task_context *)(\
107 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
108 + sizeof(struct sci_ssp_response_iu) \
109 ))
110
111/**
112 * scic_sds_stp_request_get_sgl_element_buffer() -
113 *
114 * This macro returns the address of the sgl elment pairs in the io request
115 * memory buffer
116 */
117#define scic_sds_stp_request_get_sgl_element_buffer(memory) \
118 ((struct scu_sgl_element_pair *)(\
119 ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \
120 + sizeof(struct scu_task_context) \
121 ))
122
123/**
124 *
125 *
126 * This method return the memory space required for STP PIO requests. u32
127 */
128u32 scic_sds_stp_request_get_object_size(void)
129{
130 return sizeof(struct scic_sds_stp_request)
131 + sizeof(struct sata_fis_reg_h2d)
132 + sizeof(struct sata_fis_reg_d2h)
133 + sizeof(struct scu_task_context)
fe9a6431 134 + SMP_CACHE_BYTES
6f231dda
DW
135 + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS;
136}
137
fe9a6431 138void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req)
6f231dda 139{
fe9a6431 140 struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent);
6f231dda 141
fe9a6431
DW
142 sci_req->command_buffer = scic_sds_stp_request_get_h2d_reg_buffer(stp_req);
143 sci_req->response_buffer = scic_sds_stp_request_get_response_buffer(stp_req);
144 sci_req->sgl_element_pair_buffer = scic_sds_stp_request_get_sgl_element_buffer(stp_req);
145 sci_req->sgl_element_pair_buffer = PTR_ALIGN(sci_req->sgl_element_pair_buffer,
146 sizeof(struct scu_sgl_element_pair));
6f231dda 147
fe9a6431
DW
148 if (sci_req->was_tag_assigned_by_user == false) {
149 sci_req->task_context_buffer =
150 scic_sds_stp_request_get_task_context_buffer(stp_req);
151 sci_req->task_context_buffer = PTR_ALIGN(sci_req->task_context_buffer,
152 SMP_CACHE_BYTES);
6f231dda
DW
153 }
154}
155
156/**
157 * This method is will fill in the SCU Task Context for any type of SATA
158 * request. This is called from the various SATA constructors.
159 * @this_request: The general IO request object which is to be used in
160 * constructing the SCU task context.
161 * @task_context: The buffer pointer for the SCU task context which is being
162 * constructed.
163 *
164 * The general io request construction is complete. The buffer assignment for
165 * the command buffer is complete. none Revisit task context construction to
166 * determine what is common for SSP/SMP/STP task context structures.
167 */
168static void scu_sata_reqeust_construct_task_context(
6389a775 169 struct scic_sds_request *sds_request,
6f231dda
DW
170 struct scu_task_context *task_context)
171{
6389a775
DJ
172 dma_addr_t dma_addr;
173 struct scic_sds_controller *controller;
6f231dda
DW
174 struct scic_sds_remote_device *target_device;
175 struct scic_sds_port *target_port;
176
6389a775
DJ
177 controller = scic_sds_request_get_controller(sds_request);
178 target_device = scic_sds_request_get_device(sds_request);
179 target_port = scic_sds_request_get_port(sds_request);
6f231dda
DW
180
181 /* Fill in the TC with the its required data */
182 task_context->abort = 0;
183 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
184 task_context->initiator_request = 1;
185 task_context->connection_rate =
186 scic_remote_device_get_connection_rate(target_device);
187 task_context->protocol_engine_index =
6389a775 188 scic_sds_controller_get_protocol_engine_group(controller);
6f231dda
DW
189 task_context->logical_port_index =
190 scic_sds_port_get_index(target_port);
191 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
192 task_context->valid = SCU_TASK_CONTEXT_VALID;
193 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
194
195 task_context->remote_node_index =
6389a775 196 scic_sds_remote_device_get_index(sds_request->target_device);
6f231dda
DW
197 task_context->command_code = 0;
198
199 task_context->link_layer_control = 0;
200 task_context->do_not_dma_ssp_good_response = 1;
201 task_context->strict_ordering = 0;
202 task_context->control_frame = 0;
203 task_context->timeout_enable = 0;
204 task_context->block_guard_enable = 0;
205
206 task_context->address_modifier = 0;
207 task_context->task_phase = 0x01;
208
209 task_context->ssp_command_iu_length =
210 (sizeof(struct sata_fis_reg_h2d) - sizeof(u32)) / sizeof(u32);
211
212 /* Set the first word of the H2D REG FIS */
6389a775 213 task_context->type.words[0] = *(u32 *)sds_request->command_buffer;
6f231dda 214
6389a775
DJ
215 if (sds_request->was_tag_assigned_by_user) {
216 /*
217 * Build the task context now since we have already read
218 * the data
219 */
220 sds_request->post_context =
221 (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
222 (scic_sds_controller_get_protocol_engine_group(
223 controller) <<
224 SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
225 (scic_sds_port_get_index(target_port) <<
226 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
227 scic_sds_io_tag_get_index(sds_request->io_tag));
6f231dda 228 } else {
6389a775
DJ
229 /*
230 * Build the task context now since we have already read
231 * the data.
232 * I/O tag index is not assigned because we have to wait
233 * until we get a TCi.
234 */
235 sds_request->post_context =
236 (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
237 (scic_sds_controller_get_protocol_engine_group(
238 controller) <<
239 SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
240 (scic_sds_port_get_index(target_port) <<
241 SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
6f231dda
DW
242 }
243
244 /*
6389a775
DJ
245 * Copy the physical address for the command buffer to the SCU Task
246 * Context. We must offset the command buffer by 4 bytes because the
247 * first 4 bytes are transfered in the body of the TC.
248 */
249 dma_addr =
250 scic_io_request_get_dma_addr(sds_request,
251 (char *)sds_request->
252 command_buffer +
253 sizeof(u32));
6f231dda 254
6389a775
DJ
255 task_context->command_iu_upper = upper_32_bits(dma_addr);
256 task_context->command_iu_lower = lower_32_bits(dma_addr);
6f231dda
DW
257
258 /* SATA Requests do not have a response buffer */
259 task_context->response_iu_upper = 0;
260 task_context->response_iu_lower = 0;
261}
262
263/**
264 *
265 * @this_request:
266 *
267 * This method will perform any general sata request construction. What part of
268 * SATA IO request construction is general? none
269 */
35173d57 270static void scic_sds_stp_non_ncq_request_construct(
6f231dda
DW
271 struct scic_sds_request *this_request)
272{
273 this_request->has_started_substate_machine = true;
274}
275
276/**
277 *
82d29928 278 * @sci_req: This parameter specifies the request to be constructed as an
6f231dda
DW
279 * optimized request.
280 * @optimized_task_type: This parameter specifies whether the request is to be
281 * an UDMA request or a NCQ request. - A value of 0 indicates UDMA. - A
282 * value of 1 indicates NCQ.
283 *
284 * This method will perform request construction common to all types of STP
285 * requests that are optimized by the silicon (i.e. UDMA, NCQ). This method
286 * returns an indication as to whether the construction was successful.
287 */
82d29928
DW
288static void scic_sds_stp_optimized_request_construct(struct scic_sds_request *sci_req,
289 u8 optimized_task_type,
290 u32 len,
291 enum dma_data_direction dir)
6f231dda 292{
82d29928 293 struct scu_task_context *task_context = sci_req->task_context_buffer;
6f231dda
DW
294
295 /* Build the STP task context structure */
82d29928 296 scu_sata_reqeust_construct_task_context(sci_req, task_context);
6f231dda
DW
297
298 /* Copy over the SGL elements */
82d29928 299 scic_sds_request_build_sgl(sci_req);
6f231dda
DW
300
301 /* Copy over the number of bytes to be transfered */
82d29928 302 task_context->transfer_length_bytes = len;
6f231dda 303
82d29928 304 if (dir == DMA_TO_DEVICE) {
6f231dda
DW
305 /*
306 * The difference between the DMA IN and DMA OUT request task type
307 * values are consistent with the difference between FPDMA READ
308 * and FPDMA WRITE values. Add the supplied task type parameter
309 * to this difference to set the task type properly for this
310 * DATA OUT (WRITE) case. */
311 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
312 - SCU_TASK_TYPE_DMA_IN);
313 } else {
314 /*
315 * For the DATA IN (READ) case, simply save the supplied
316 * optimized task type. */
317 task_context->task_type = optimized_task_type;
318 }
319}
320
6f231dda
DW
321/**
322 *
82d29928 323 * @sci_req: This parameter specifies the request to be constructed.
6f231dda
DW
324 *
325 * This method will construct the STP UDMA request and its associated TC data.
326 * This method returns an indication as to whether the construction was
327 * successful. SCI_SUCCESS Currently this method always returns this value.
328 */
82d29928
DW
329enum sci_status scic_sds_stp_ncq_request_construct(struct scic_sds_request *sci_req,
330 u32 len,
331 enum dma_data_direction dir)
6f231dda 332{
82d29928
DW
333 scic_sds_stp_optimized_request_construct(sci_req,
334 SCU_TASK_TYPE_FPDMAQ_READ,
335 len, dir);
6f231dda
DW
336 return SCI_SUCCESS;
337}
338
339/**
35173d57 340 * scu_stp_raw_request_construct_task_context -
6f231dda
DW
341 * @this_request: This parameter specifies the STP request object for which to
342 * construct a RAW command frame task context.
343 * @task_context: This parameter specifies the SCU specific task context buffer
344 * to construct.
345 *
346 * This method performs the operations common to all SATA/STP requests
347 * utilizing the raw frame method. none
348 */
35173d57 349static void scu_stp_raw_request_construct_task_context(
6f231dda
DW
350 struct scic_sds_stp_request *this_request,
351 struct scu_task_context *task_context)
352{
353 scu_sata_reqeust_construct_task_context(&this_request->parent, task_context);
354
355 task_context->control_frame = 0;
356 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
357 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME;
358 task_context->type.stp.fis_type = SATA_FIS_TYPE_REGH2D;
359 task_context->transfer_length_bytes = sizeof(struct sata_fis_reg_h2d) - sizeof(u32);
360}
361
6f231dda
DW
362void scic_stp_io_request_set_ncq_tag(
363 struct scic_sds_request *req,
364 u16 ncq_tag)
365{
366 /**
367 * @note This could be made to return an error to the user if the user
368 * attempts to set the NCQ tag in the wrong state.
369 */
370 req->task_context_buffer->type.stp.ncq_tag = ncq_tag;
371}
372
373
374void *scic_stp_io_request_get_h2d_reg_address(
375 struct scic_sds_request *req)
376{
377 return req->command_buffer;
378}
379
380
381void *scic_stp_io_request_get_d2h_reg_address(
382 struct scic_sds_request *req)
383{
384 return &((struct scic_sds_stp_request *)req)->d2h_reg_fis;
385}
386
387/**
388 *
389 * @this_request:
390 *
391 * Get the next SGL element from the request. - Check on which SGL element pair
392 * we are working - if working on SLG pair element A - advance to element B -
393 * else - check to see if there are more SGL element pairs for this IO request
394 * - if there are more SGL element pairs - advance to the next pair and return
395 * element A struct scu_sgl_element*
396 */
35173d57 397static struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(struct scic_sds_stp_request *stp_req)
103a00c2 398{
6f231dda 399 struct scu_sgl_element *current_sgl;
103a00c2
DJ
400 struct scic_sds_request *sci_req = &stp_req->parent;
401 struct scic_sds_request_pio_sgl *pio_sgl = &stp_req->type.pio.request_current;
6f231dda 402
103a00c2
DJ
403 if (pio_sgl->sgl_set == SCU_SGL_ELEMENT_PAIR_A) {
404 if (pio_sgl->sgl_pair->B.address_lower == 0 &&
405 pio_sgl->sgl_pair->B.address_upper == 0) {
6f231dda
DW
406 current_sgl = NULL;
407 } else {
103a00c2
DJ
408 pio_sgl->sgl_set = SCU_SGL_ELEMENT_PAIR_B;
409 current_sgl = &pio_sgl->sgl_pair->B;
6f231dda
DW
410 }
411 } else {
103a00c2
DJ
412 if (pio_sgl->sgl_pair->next_pair_lower == 0 &&
413 pio_sgl->sgl_pair->next_pair_upper == 0) {
6f231dda
DW
414 current_sgl = NULL;
415 } else {
103a00c2 416 u64 phys_addr;
6f231dda 417
103a00c2
DJ
418 phys_addr = pio_sgl->sgl_pair->next_pair_upper;
419 phys_addr <<= 32;
420 phys_addr |= pio_sgl->sgl_pair->next_pair_lower;
6f231dda 421
103a00c2
DJ
422 pio_sgl->sgl_pair = scic_request_get_virt_addr(sci_req, phys_addr);
423 pio_sgl->sgl_set = SCU_SGL_ELEMENT_PAIR_A;
424 current_sgl = &pio_sgl->sgl_pair->A;
6f231dda
DW
425 }
426 }
427
428 return current_sgl;
429}
430
6f231dda
DW
431/**
432 *
433 * @this_request:
434 * @completion_code:
435 *
436 * This method processes a TC completion. The expected TC completion is for
437 * the transmission of the H2D register FIS containing the SATA/STP non-data
438 * request. This method always successfully processes the TC completion.
439 * SCI_SUCCESS This value is always returned.
440 */
441static enum sci_status scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(
442 struct scic_sds_request *this_request,
443 u32 completion_code)
444{
445 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
446 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
447 scic_sds_request_set_status(
448 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
449 );
450
451 sci_base_state_machine_change_state(
452 &this_request->started_substate_machine,
453 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
454 );
455 break;
456
457 default:
458 /*
459 * All other completion status cause the IO to be complete. If a NAK
460 * was received, then it is up to the user to retry the request. */
461 scic_sds_request_set_status(
462 this_request,
463 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
464 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
465 );
466
467 sci_base_state_machine_change_state(
468 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
469 );
470 break;
471 }
472
473 return SCI_SUCCESS;
474}
475
476/**
477 *
478 * @request: This parameter specifies the request for which a frame has been
479 * received.
480 * @frame_index: This parameter specifies the index of the frame that has been
481 * received.
482 *
483 * This method processes frames received from the target while waiting for a
484 * device to host register FIS. If a non-register FIS is received during this
485 * time, it is treated as a protocol violation from an IO perspective. Indicate
486 * if the received frame was processed successfully.
487 */
488static enum sci_status scic_sds_stp_request_non_data_await_d2h_frame_handler(
489 struct scic_sds_request *request,
490 u32 frame_index)
491{
492 enum sci_status status;
493 struct sata_fis_header *frame_header;
494 u32 *frame_buffer;
495 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
496
497 status = scic_sds_unsolicited_frame_control_get_header(
498 &(this_request->parent.owning_controller->uf_control),
499 frame_index,
500 (void **)&frame_header
501 );
502
503 if (status == SCI_SUCCESS) {
504 switch (frame_header->fis_type) {
505 case SATA_FIS_TYPE_REGD2H:
506 scic_sds_unsolicited_frame_control_get_buffer(
507 &(this_request->parent.owning_controller->uf_control),
508 frame_index,
509 (void **)&frame_buffer
510 );
511
512 scic_sds_controller_copy_sata_response(
513 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
514 );
515
516 /* The command has completed with error */
517 scic_sds_request_set_status(
518 &this_request->parent,
519 SCU_TASK_DONE_CHECK_RESPONSE,
520 SCI_FAILURE_IO_RESPONSE_VALID
521 );
522 break;
523
524 default:
525 dev_warn(scic_to_dev(request->owning_controller),
526 "%s: IO Request:0x%p Frame Id:%d protocol "
527 "violation occurred\n",
528 __func__, this_request, frame_index);
529
530 scic_sds_request_set_status(
531 &this_request->parent,
532 SCU_TASK_DONE_UNEXP_FIS,
533 SCI_FAILURE_PROTOCOL_VIOLATION
534 );
535 break;
536 }
537
538 sci_base_state_machine_change_state(
539 &this_request->parent.parent.state_machine,
540 SCI_BASE_REQUEST_STATE_COMPLETED
541 );
542
543 /* Frame has been decoded return it to the controller */
544 scic_sds_controller_release_frame(
545 this_request->parent.owning_controller, frame_index
546 );
547 } else
548 dev_err(scic_to_dev(request->owning_controller),
549 "%s: SCIC IO Request 0x%p could not get frame header "
550 "for frame index %d, status %x\n",
551 __func__, this_request, frame_index, status);
552
553 return status;
554}
555
556/* --------------------------------------------------------------------------- */
557
35173d57 558static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_non_data_substate_handler_table[] = {
6f231dda
DW
559 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = {
560 .parent.start_handler = scic_sds_request_default_start_handler,
561 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
562 .parent.complete_handler = scic_sds_request_default_complete_handler,
563 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
564 .tc_completion_handler = scic_sds_stp_request_non_data_await_h2d_tc_completion_handler,
565 .event_handler = scic_sds_request_default_event_handler,
566 .frame_handler = scic_sds_request_default_frame_handler,
567 },
568 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE] = {
569 .parent.start_handler = scic_sds_request_default_start_handler,
570 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
571 .parent.complete_handler = scic_sds_request_default_complete_handler,
572 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
573 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
574 .event_handler = scic_sds_request_default_event_handler,
575 .frame_handler = scic_sds_stp_request_non_data_await_d2h_frame_handler,
576 }
577};
578
579static void scic_sds_stp_request_started_non_data_await_h2d_completion_enter(
580 struct sci_base_object *object)
581{
582 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
583
584 SET_STATE_HANDLER(
585 this_request,
586 scic_sds_stp_request_started_non_data_substate_handler_table,
587 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
588 );
589
590 scic_sds_remote_device_set_working_request(
591 this_request->target_device, this_request
592 );
593}
594
595static void scic_sds_stp_request_started_non_data_await_d2h_enter(
596 struct sci_base_object *object)
597{
598 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
599
600 SET_STATE_HANDLER(
601 this_request,
602 scic_sds_stp_request_started_non_data_substate_handler_table,
603 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
604 );
605}
606
607/* --------------------------------------------------------------------------- */
608
35173d57 609static const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table[] = {
6f231dda
DW
610 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = {
611 .enter_state = scic_sds_stp_request_started_non_data_await_h2d_completion_enter,
612 },
613 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE] = {
614 .enter_state = scic_sds_stp_request_started_non_data_await_d2h_enter,
615 },
616};
617
35173d57
DW
618enum sci_status scic_sds_stp_non_data_request_construct(struct scic_sds_request *sci_req)
619{
620 struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent);
621
622 scic_sds_stp_non_ncq_request_construct(sci_req);
623
624 /* Build the STP task context structure */
625 scu_stp_raw_request_construct_task_context(stp_req, sci_req->task_context_buffer);
626
627 sci_base_state_machine_construct(&sci_req->started_substate_machine,
628 &sci_req->parent.parent,
629 scic_sds_stp_request_started_non_data_substate_table,
630 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE);
631
632 return SCI_SUCCESS;
633}
634
6f231dda
DW
635#define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */
636
637/**
638 *
639 * @this_request:
640 * @length:
641 *
642 * This function will transmit DATA_FIS from (current sgl + offset) for input
643 * parameter length. current sgl and offset is alreay stored in the IO request
644 * enum sci_status
645 */
646
647static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame(
648 struct scic_sds_request *this_request,
649 u32 length)
650{
651 struct scic_sds_stp_request *this_sds_stp_request = (struct scic_sds_stp_request *)this_request;
652 sci_base_controller_request_handler_t continue_io;
653 struct scu_sgl_element *current_sgl;
654 struct scic_sds_controller *scic;
655 u32 state;
656
657 /*
658 * Recycle the TC and reconstruct it for sending out DATA FIS containing
659 * for the data from current_sgl+offset for the input length */
660 struct scu_task_context *task_context = scic_sds_controller_get_task_context_buffer(
661 this_request->owning_controller,
662 this_request->io_tag
663 );
664
665 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
666 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
667 else
668 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
669
670 /* update the TC */
671 task_context->command_iu_upper = current_sgl->address_upper;
672 task_context->command_iu_lower = current_sgl->address_lower;
673 task_context->transfer_length_bytes = length;
674 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
675
676 /* send the new TC out. */
677 scic = this_request->owning_controller;
678 state = scic->parent.state_machine.current_state_id;
679 continue_io = scic_sds_controller_state_handler_table[state].base.continue_io;
680 return continue_io(&scic->parent, &this_request->target_device->parent,
681 &this_request->parent);
682}
683
684/**
685 *
686 * @this_request:
687 *
688 * enum sci_status
689 */
690static enum sci_status scic_sds_stp_request_pio_data_out_transmit_data(
691 struct scic_sds_request *this_sds_request)
692{
693
694 struct scu_sgl_element *current_sgl;
695 u32 sgl_offset;
696 u32 remaining_bytes_in_current_sgl = 0;
697 enum sci_status status = SCI_SUCCESS;
698
699 struct scic_sds_stp_request *this_sds_stp_request = (struct scic_sds_stp_request *)this_sds_request;
700
701 sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset;
702
703 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) {
704 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
705 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset;
706 } else {
707 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
708 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset;
709 }
710
711
712 if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0) {
713 if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl) {
714 /* recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl */
715 status = scic_sds_stp_request_pio_data_out_trasmit_data_frame(this_sds_request, remaining_bytes_in_current_sgl);
716 if (status == SCI_SUCCESS) {
717 this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl;
718
719 /* update the current sgl, sgl_offset and save for future */
720 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_sds_stp_request);
721 sgl_offset = 0;
722 }
723 } else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl) {
724 /* recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes */
725 scic_sds_stp_request_pio_data_out_trasmit_data_frame(this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes);
726
727 if (status == SCI_SUCCESS) {
728 /* Sgl offset will be adjusted and saved for future */
729 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes;
730 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes;
731 this_sds_stp_request->type.pio.pio_transfer_bytes = 0;
732 }
733 }
734 }
735
736 if (status == SCI_SUCCESS) {
737 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset;
738 }
739
740 return status;
741}
742
743/**
744 *
103a00c2 745 * @stp_request: The request that is used for the SGL processing.
6f231dda
DW
746 * @data_buffer: The buffer of data to be copied.
747 * @length: The length of the data transfer.
748 *
749 * Copy the data from the buffer for the length specified to the IO reqeust SGL
750 * specified data region. enum sci_status
751 */
103a00c2
DJ
752static enum sci_status
753scic_sds_stp_request_pio_data_in_copy_data_buffer(struct scic_sds_stp_request *stp_req,
754 u8 *data_buf, u32 len)
6f231dda 755{
103a00c2
DJ
756 struct scic_sds_request *sci_req;
757 struct isci_request *ireq;
758 u8 *src_addr;
759 int copy_len;
760 struct sas_task *task;
761 struct scatterlist *sg;
762 void *kaddr;
763 int total_len = len;
764
765 sci_req = &stp_req->parent;
766 ireq = scic_sds_request_get_user_request(sci_req);
767 task = isci_request_access_task(ireq);
768 src_addr = data_buf;
769
770 if (task->num_scatter > 0) {
771 sg = task->scatter;
772
773 while (total_len > 0) {
774 struct page *page = sg_page(sg);
775
776 copy_len = min_t(int, total_len, sg_dma_len(sg));
777 kaddr = kmap_atomic(page, KM_IRQ0);
778 memcpy(kaddr + sg->offset, src_addr, copy_len);
779 kunmap_atomic(kaddr, KM_IRQ0);
780 total_len -= copy_len;
781 src_addr += copy_len;
782 sg = sg_next(sg);
6f231dda 783 }
103a00c2
DJ
784 } else {
785 BUG_ON(task->total_xfer_len < total_len);
786 memcpy(task->scatter, src_addr, total_len);
6f231dda
DW
787 }
788
103a00c2 789 return SCI_SUCCESS;
6f231dda
DW
790}
791
792/**
793 *
794 * @this_request: The PIO DATA IN request that is to receive the data.
795 * @data_buffer: The buffer to copy from.
796 *
797 * Copy the data buffer to the io request data region. enum sci_status
798 */
799static enum sci_status scic_sds_stp_request_pio_data_in_copy_data(
800 struct scic_sds_stp_request *this_request,
801 u8 *data_buffer)
802{
803 enum sci_status status;
804
805 /*
806 * If there is less than 1K remaining in the transfer request
807 * copy just the data for the transfer */
808 if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE) {
809 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
810 this_request, data_buffer, this_request->type.pio.pio_transfer_bytes);
811
812 if (status == SCI_SUCCESS)
813 this_request->type.pio.pio_transfer_bytes = 0;
814 } else {
815 /* We are transfering the whole frame so copy */
816 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
817 this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
818
819 if (status == SCI_SUCCESS)
820 this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE;
821 }
822
823 return status;
824}
825
826/**
827 *
828 * @this_request:
829 * @completion_code:
830 *
831 * enum sci_status
832 */
833static enum sci_status scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler(
834 struct scic_sds_request *this_request,
835 u32 completion_code)
836{
837 enum sci_status status = SCI_SUCCESS;
838
839 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
840 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
841 scic_sds_request_set_status(
842 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
843 );
844
845 sci_base_state_machine_change_state(
846 &this_request->started_substate_machine,
847 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
848 );
849 break;
850
851 default:
852 /*
853 * All other completion status cause the IO to be complete. If a NAK
854 * was received, then it is up to the user to retry the request. */
855 scic_sds_request_set_status(
856 this_request,
857 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
858 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
859 );
860
861 sci_base_state_machine_change_state(
862 &this_request->parent.state_machine,
863 SCI_BASE_REQUEST_STATE_COMPLETED
864 );
865 break;
866 }
867
868 return status;
869}
870
871/**
872 *
873 * @this_request:
874 * @frame_index:
875 *
876 * enum sci_status
877 */
878static enum sci_status scic_sds_stp_request_pio_await_frame_frame_handler(
879 struct scic_sds_request *request,
880 u32 frame_index)
881{
882 enum sci_status status;
883 struct sata_fis_header *frame_header;
884 u32 *frame_buffer;
885 struct scic_sds_stp_request *this_request;
886
887 this_request = (struct scic_sds_stp_request *)request;
888
889 status = scic_sds_unsolicited_frame_control_get_header(
890 &(this_request->parent.owning_controller->uf_control),
891 frame_index,
892 (void **)&frame_header
893 );
894
895 if (status == SCI_SUCCESS) {
896 switch (frame_header->fis_type) {
897 case SATA_FIS_TYPE_PIO_SETUP:
898 /* Get from the frame buffer the PIO Setup Data */
899 scic_sds_unsolicited_frame_control_get_buffer(
900 &(this_request->parent.owning_controller->uf_control),
901 frame_index,
902 (void **)&frame_buffer
903 );
904
905 /*
906 * Get the data from the PIO Setup
907 * The SCU Hardware returns first word in the frame_header and the rest
908 * of the data is in the frame buffer so we need to back up one dword */
909 this_request->type.pio.pio_transfer_bytes =
910 (u16)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->transfter_count;
911 this_request->type.pio.ending_status =
912 (u8)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->ending_status;
913
914 scic_sds_controller_copy_sata_response(
915 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
916 );
917
918 this_request->d2h_reg_fis.status =
919 this_request->type.pio.ending_status;
920
921 /* The next state is dependent on whether the request was PIO Data-in or Data out */
922 if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN) {
923 sci_base_state_machine_change_state(
924 &this_request->parent.started_substate_machine,
925 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
926 );
927 } else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT) {
928 /* Transmit data */
929 status = scic_sds_stp_request_pio_data_out_transmit_data(request);
930 if (status == SCI_SUCCESS) {
931 sci_base_state_machine_change_state(
932 &this_request->parent.started_substate_machine,
933 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
934 );
935 }
936 }
937 break;
938
939 case SATA_FIS_TYPE_SETDEVBITS:
940 sci_base_state_machine_change_state(
941 &this_request->parent.started_substate_machine,
942 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
943 );
944 break;
945
946 case SATA_FIS_TYPE_REGD2H:
947 if ((frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0) {
948 scic_sds_unsolicited_frame_control_get_buffer(
949 &(this_request->parent.owning_controller->uf_control),
950 frame_index,
951 (void **)&frame_buffer
952 );
953
954 scic_sds_controller_copy_sata_response(
955 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer);
956
957 scic_sds_request_set_status(
958 &this_request->parent,
959 SCU_TASK_DONE_CHECK_RESPONSE,
960 SCI_FAILURE_IO_RESPONSE_VALID
961 );
962
963 sci_base_state_machine_change_state(
964 &this_request->parent.parent.state_machine,
965 SCI_BASE_REQUEST_STATE_COMPLETED
966 );
967 } else {
968 /*
969 * Now why is the drive sending a D2H Register FIS when it is still busy?
970 * Do nothing since we are still in the right state. */
971 dev_dbg(scic_to_dev(request->owning_controller),
972 "%s: SCIC PIO Request 0x%p received "
973 "D2H Register FIS with BSY status "
974 "0x%x\n",
975 __func__,
976 this_request,
977 frame_header->status);
978 }
979 break;
980
981 default:
982 break;
983 }
984
985 /* Frame is decoded return it to the controller */
986 scic_sds_controller_release_frame(
987 this_request->parent.owning_controller,
988 frame_index
989 );
990 } else
991 dev_err(scic_to_dev(request->owning_controller),
992 "%s: SCIC IO Request 0x%p could not get frame header "
993 "for frame index %d, status %x\n",
994 __func__, this_request, frame_index, status);
995
996 return status;
997}
998
999/**
1000 *
1001 * @this_request:
1002 * @frame_index:
1003 *
1004 * enum sci_status
1005 */
1006static enum sci_status scic_sds_stp_request_pio_data_in_await_data_frame_handler(
1007 struct scic_sds_request *request,
1008 u32 frame_index)
1009{
1010 enum sci_status status;
1011 struct sata_fis_header *frame_header;
1012 struct sata_fis_data *frame_buffer;
1013 struct scic_sds_stp_request *this_request;
1014
1015 this_request = (struct scic_sds_stp_request *)request;
1016
1017 status = scic_sds_unsolicited_frame_control_get_header(
1018 &(this_request->parent.owning_controller->uf_control),
1019 frame_index,
1020 (void **)&frame_header
1021 );
1022
1023 if (status == SCI_SUCCESS) {
1024 if (frame_header->fis_type == SATA_FIS_TYPE_DATA) {
1025 if (this_request->type.pio.request_current.sgl_pair == NULL) {
1026 this_request->parent.saved_rx_frame_index = frame_index;
1027 this_request->type.pio.pio_transfer_bytes = 0;
1028 } else {
1029 status = scic_sds_unsolicited_frame_control_get_buffer(
1030 &(this_request->parent.owning_controller->uf_control),
1031 frame_index,
1032 (void **)&frame_buffer
1033 );
1034
1035 status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (u8 *)frame_buffer);
1036
1037 /* Frame is decoded return it to the controller */
1038 scic_sds_controller_release_frame(
1039 this_request->parent.owning_controller,
1040 frame_index
1041 );
1042 }
1043
1044 /*
1045 * Check for the end of the transfer, are there more bytes remaining
1046 * for this data transfer */
1047 if (
1048 (status == SCI_SUCCESS)
1049 && (this_request->type.pio.pio_transfer_bytes == 0)
1050 ) {
1051 if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0) {
1052 scic_sds_request_set_status(
1053 &this_request->parent,
1054 SCU_TASK_DONE_CHECK_RESPONSE,
1055 SCI_FAILURE_IO_RESPONSE_VALID
1056 );
1057
1058 sci_base_state_machine_change_state(
1059 &this_request->parent.parent.state_machine,
1060 SCI_BASE_REQUEST_STATE_COMPLETED
1061 );
1062 } else {
1063 sci_base_state_machine_change_state(
1064 &this_request->parent.started_substate_machine,
1065 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1066 );
1067 }
1068 }
1069 } else {
1070 dev_err(scic_to_dev(request->owning_controller),
1071 "%s: SCIC PIO Request 0x%p received frame %d "
1072 "with fis type 0x%02x when expecting a data "
1073 "fis.\n",
1074 __func__,
1075 this_request,
1076 frame_index,
1077 frame_header->fis_type);
1078
1079 scic_sds_request_set_status(
1080 &this_request->parent,
1081 SCU_TASK_DONE_GOOD,
1082 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT
1083 );
1084
1085 sci_base_state_machine_change_state(
1086 &this_request->parent.parent.state_machine,
1087 SCI_BASE_REQUEST_STATE_COMPLETED
1088 );
1089
1090 /* Frame is decoded return it to the controller */
1091 scic_sds_controller_release_frame(
1092 this_request->parent.owning_controller,
1093 frame_index
1094 );
1095 }
1096 } else
1097 dev_err(scic_to_dev(request->owning_controller),
1098 "%s: SCIC IO Request 0x%p could not get frame header "
1099 "for frame index %d, status %x\n",
1100 __func__, this_request, frame_index, status);
1101
1102 return status;
1103}
1104
1105
1106/**
1107 *
1108 * @this_request:
1109 * @completion_code:
1110 *
1111 * enum sci_status
1112 */
1113static enum sci_status scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler(
1114
1115 struct scic_sds_request *this_request,
1116 u32 completion_code)
1117{
1118 enum sci_status status = SCI_SUCCESS;
1119 bool all_frames_transferred = false;
1120
1121 struct scic_sds_stp_request *this_scic_sds_stp_request = (struct scic_sds_stp_request *)this_request;
1122
1123 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1124 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1125 /* Transmit data */
1126 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0) {
1127 status = scic_sds_stp_request_pio_data_out_transmit_data(this_request);
1128 if (status == SCI_SUCCESS) {
1129 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1130 all_frames_transferred = true;
1131 }
1132 } else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0) {
1133 /*
1134 * this will happen if the all data is written at the
1135 * first time after the pio setup fis is received
1136 */
1137 all_frames_transferred = true;
1138 }
1139
1140 /* all data transferred. */
1141 if (all_frames_transferred) {
1142 /*
1143 * Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE
1144 * and wait for PIO_SETUP fis / or D2H REg fis. */
1145 sci_base_state_machine_change_state(
1146 &this_request->started_substate_machine,
1147 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1148 );
1149 }
1150 break;
1151
1152 default:
1153 /*
1154 * All other completion status cause the IO to be complete. If a NAK
1155 * was received, then it is up to the user to retry the request. */
1156 scic_sds_request_set_status(
1157 this_request,
1158 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1159 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1160 );
1161
1162 sci_base_state_machine_change_state(
1163 &this_request->parent.state_machine,
1164 SCI_BASE_REQUEST_STATE_COMPLETED
1165 );
1166 break;
1167 }
1168
1169 return status;
1170}
1171
1172/**
1173 *
1174 * @request: This is the request which is receiving the event.
1175 * @event_code: This is the event code that the request on which the request is
1176 * expected to take action.
1177 *
1178 * This method will handle any link layer events while waiting for the data
1179 * frame. enum sci_status SCI_SUCCESS SCI_FAILURE
1180 */
1181static enum sci_status scic_sds_stp_request_pio_data_in_await_data_event_handler(
1182 struct scic_sds_request *request,
1183 u32 event_code)
1184{
1185 enum sci_status status;
1186
1187 switch (scu_get_event_specifier(event_code)) {
1188 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
1189 /*
1190 * We are waiting for data and the SCU has R_ERR the data frame.
1191 * Go back to waiting for the D2H Register FIS */
1192 sci_base_state_machine_change_state(
1193 &request->started_substate_machine,
1194 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1195 );
1196
1197 status = SCI_SUCCESS;
1198 break;
1199
1200 default:
1201 dev_err(scic_to_dev(request->owning_controller),
1202 "%s: SCIC PIO Request 0x%p received unexpected "
1203 "event 0x%08x\n",
1204 __func__, request, event_code);
1205
1206 /* / @todo Should we fail the PIO request when we get an unexpected event? */
1207 status = SCI_FAILURE;
1208 break;
1209 }
1210
1211 return status;
1212}
1213
1214/* --------------------------------------------------------------------------- */
1215
35173d57 1216static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_pio_substate_handler_table[] = {
6f231dda
DW
1217 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = {
1218 .parent.start_handler = scic_sds_request_default_start_handler,
1219 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1220 .parent.complete_handler = scic_sds_request_default_complete_handler,
1221 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1222 .tc_completion_handler = scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler,
1223 .event_handler = scic_sds_request_default_event_handler,
1224 .frame_handler = scic_sds_request_default_frame_handler
1225 },
1226 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE] = {
1227 .parent.start_handler = scic_sds_request_default_start_handler,
1228 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1229 .parent.complete_handler = scic_sds_request_default_complete_handler,
1230 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1231 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1232 .event_handler = scic_sds_request_default_event_handler,
1233 .frame_handler = scic_sds_stp_request_pio_await_frame_frame_handler
1234 },
1235 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE] = {
1236 .parent.start_handler = scic_sds_request_default_start_handler,
1237 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1238 .parent.complete_handler = scic_sds_request_default_complete_handler,
1239 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1240 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1241 .event_handler = scic_sds_stp_request_pio_data_in_await_data_event_handler,
1242 .frame_handler = scic_sds_stp_request_pio_data_in_await_data_frame_handler
1243 },
1244 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE] = {
1245 .parent.start_handler = scic_sds_request_default_start_handler,
1246 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1247 .parent.complete_handler = scic_sds_request_default_complete_handler,
1248 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1249 .tc_completion_handler = scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler,
1250 .event_handler = scic_sds_request_default_event_handler,
1251 .frame_handler = scic_sds_request_default_frame_handler,
1252 }
1253};
1254
1255static void scic_sds_stp_request_started_pio_await_h2d_completion_enter(
1256 struct sci_base_object *object)
1257{
1258 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1259
1260 SET_STATE_HANDLER(
1261 this_request,
1262 scic_sds_stp_request_started_pio_substate_handler_table,
1263 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1264 );
1265
1266 scic_sds_remote_device_set_working_request(
1267 this_request->target_device, this_request);
1268}
1269
1270static void scic_sds_stp_request_started_pio_await_frame_enter(
1271 struct sci_base_object *object)
1272{
1273 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1274
1275 SET_STATE_HANDLER(
1276 this_request,
1277 scic_sds_stp_request_started_pio_substate_handler_table,
1278 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1279 );
1280}
1281
1282static void scic_sds_stp_request_started_pio_data_in_await_data_enter(
1283 struct sci_base_object *object)
1284{
1285 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1286
1287 SET_STATE_HANDLER(
1288 this_request,
1289 scic_sds_stp_request_started_pio_substate_handler_table,
1290 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1291 );
1292}
1293
1294static void scic_sds_stp_request_started_pio_data_out_transmit_data_enter(
1295 struct sci_base_object *object)
1296{
1297 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1298
1299 SET_STATE_HANDLER(
1300 this_request,
1301 scic_sds_stp_request_started_pio_substate_handler_table,
1302 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1303 );
1304}
1305
1306/* --------------------------------------------------------------------------- */
1307
35173d57 1308static const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[] = {
6f231dda
DW
1309 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = {
1310 .enter_state = scic_sds_stp_request_started_pio_await_h2d_completion_enter,
1311 },
1312 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE] = {
1313 .enter_state = scic_sds_stp_request_started_pio_await_frame_enter,
1314 },
1315 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE] = {
1316 .enter_state = scic_sds_stp_request_started_pio_data_in_await_data_enter,
1317 },
1318 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE] = {
1319 .enter_state = scic_sds_stp_request_started_pio_data_out_transmit_data_enter,
1320 }
1321};
1322
35173d57
DW
1323enum sci_status scic_sds_stp_pio_request_construct(struct scic_sds_request *sci_req,
1324 u8 sat_protocol,
1325 bool copy_rx_frame)
1326{
1327 struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent);
1328 struct scic_sds_stp_pio_request *pio = &stp_req->type.pio;
1329
1330 scic_sds_stp_non_ncq_request_construct(sci_req);
1331
1332 scu_stp_raw_request_construct_task_context(stp_req,
1333 sci_req->task_context_buffer);
1334
1335 pio->current_transfer_bytes = 0;
1336 pio->ending_error = 0;
1337 pio->ending_status = 0;
1338
1339 pio->request_current.sgl_offset = 0;
1340 pio->request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
1341 pio->sat_protocol = sat_protocol;
1342
1343 if (copy_rx_frame) {
1344 scic_sds_request_build_sgl(sci_req);
1345 /* Since the IO request copy of the TC contains the same data as
1346 * the actual TC this pointer is vaild for either.
1347 */
1348 pio->request_current.sgl_pair = &sci_req->task_context_buffer->sgl_pair_ab;
1349 } else {
1350 /* The user does not want the data copied to the SGL buffer location */
1351 pio->request_current.sgl_pair = NULL;
1352 }
1353
1354 sci_base_state_machine_construct(&sci_req->started_substate_machine,
1355 &sci_req->parent.parent,
1356 scic_sds_stp_request_started_pio_substate_table,
1357 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE);
1358
1359 return SCI_SUCCESS;
1360}
1361
6f231dda
DW
1362static void scic_sds_stp_request_udma_complete_request(
1363 struct scic_sds_request *this_request,
1364 u32 scu_status,
1365 enum sci_status sci_status)
1366{
1367 scic_sds_request_set_status(
1368 this_request, scu_status, sci_status
1369 );
1370
1371 sci_base_state_machine_change_state(
1372 &this_request->parent.state_machine,
1373 SCI_BASE_REQUEST_STATE_COMPLETED
1374 );
1375}
1376
1377/**
1378 *
1379 * @this_request:
1380 * @frame_index:
1381 *
1382 * enum sci_status
1383 */
1384static enum sci_status scic_sds_stp_request_udma_general_frame_handler(
1385 struct scic_sds_request *this_request,
1386 u32 frame_index)
1387{
1388 enum sci_status status;
1389 struct sata_fis_header *frame_header;
1390 u32 *frame_buffer;
1391
1392 status = scic_sds_unsolicited_frame_control_get_header(
1393 &this_request->owning_controller->uf_control,
1394 frame_index,
1395 (void **)&frame_header
1396 );
1397
1398 if (
1399 (status == SCI_SUCCESS)
1400 && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1401 ) {
1402 scic_sds_unsolicited_frame_control_get_buffer(
1403 &this_request->owning_controller->uf_control,
1404 frame_index,
1405 (void **)&frame_buffer
1406 );
1407
1408 scic_sds_controller_copy_sata_response(
1409 &((struct scic_sds_stp_request *)this_request)->d2h_reg_fis,
1410 (u32 *)frame_header,
1411 frame_buffer
1412 );
1413 }
1414
1415 scic_sds_controller_release_frame(
1416 this_request->owning_controller, frame_index);
1417
1418 return status;
1419}
1420
1421/**
1422 * This method process TC completions while in the state where we are waiting
1423 * for TC completions.
1424 * @this_request:
1425 * @completion_code:
1426 *
1427 * enum sci_status
1428 */
1429static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler(
1430 struct scic_sds_request *request,
1431 u32 completion_code)
1432{
1433 enum sci_status status = SCI_SUCCESS;
1434 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
1435
1436 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1437 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1438 scic_sds_stp_request_udma_complete_request(
1439 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1440 );
1441 break;
1442
1443 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
1444 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
1445 /*
1446 * We must check ther response buffer to see if the D2H Register FIS was
1447 * received before we got the TC completion. */
1448 if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H) {
1449 scic_sds_remote_device_suspend(
1450 this_request->parent.target_device,
1451 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
1452 );
1453
1454 scic_sds_stp_request_udma_complete_request(
1455 &this_request->parent,
1456 SCU_TASK_DONE_CHECK_RESPONSE,
1457 SCI_FAILURE_IO_RESPONSE_VALID
1458 );
1459 } else {
1460 /*
1461 * If we have an error completion status for the TC then we can expect a
1462 * D2H register FIS from the device so we must change state to wait for it */
1463 sci_base_state_machine_change_state(
1464 &this_request->parent.started_substate_machine,
1465 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
1466 );
1467 }
1468 break;
1469
1470 /*
1471 * / @todo Check to see if any of these completion status need to wait for
1472 * / the device to host register fis. */
52b957c8 1473 /* / @todo We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR - this comes only for B0 */
6f231dda
DW
1474 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
1475 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
1476 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
52b957c8 1477 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
6f231dda
DW
1478 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
1479 scic_sds_remote_device_suspend(
1480 this_request->parent.target_device,
1481 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
1482 );
1483 /* Fall through to the default case */
1484 default:
1485 /* All other completion status cause the IO to be complete. */
1486 scic_sds_stp_request_udma_complete_request(
1487 &this_request->parent,
1488 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1489 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1490 );
1491 break;
1492 }
1493
1494 return status;
1495}
1496
1497static enum sci_status scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler(
1498 struct scic_sds_request *this_request,
1499 u32 frame_index)
1500{
1501 enum sci_status status;
1502
1503 /* Use the general frame handler to copy the resposne data */
1504 status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index);
1505
1506 if (status == SCI_SUCCESS) {
1507 scic_sds_stp_request_udma_complete_request(
1508 this_request,
1509 SCU_TASK_DONE_CHECK_RESPONSE,
1510 SCI_FAILURE_IO_RESPONSE_VALID
1511 );
1512 }
1513
1514 return status;
1515}
1516
1517/* --------------------------------------------------------------------------- */
1518
35173d57 1519static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_udma_substate_handler_table[] = {
6f231dda
DW
1520 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = {
1521 .parent.start_handler = scic_sds_request_default_start_handler,
1522 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1523 .parent.complete_handler = scic_sds_request_default_complete_handler,
1524 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1525 .tc_completion_handler = scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler,
1526 .event_handler = scic_sds_request_default_event_handler,
1527 .frame_handler = scic_sds_stp_request_udma_general_frame_handler,
1528 },
1529 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE] = {
1530 .parent.start_handler = scic_sds_request_default_start_handler,
1531 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1532 .parent.complete_handler = scic_sds_request_default_complete_handler,
1533 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1534 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1535 .event_handler = scic_sds_request_default_event_handler,
1536 .frame_handler = scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler,
1537 },
1538};
1539
1540static void scic_sds_stp_request_started_udma_await_tc_completion_enter(
1541 struct sci_base_object *object)
1542{
1543 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1544
1545 SET_STATE_HANDLER(
1546 this_request,
1547 scic_sds_stp_request_started_udma_substate_handler_table,
1548 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
1549 );
1550}
1551
1552/**
1553 *
1554 *
1555 * This state is entered when there is an TC completion failure. The hardware
1556 * received an unexpected condition while processing the IO request and now
1557 * will UF the D2H register FIS to complete the IO.
1558 */
1559static void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter(
1560 struct sci_base_object *object)
1561{
1562 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1563
1564 SET_STATE_HANDLER(
1565 this_request,
1566 scic_sds_stp_request_started_udma_substate_handler_table,
1567 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
1568 );
1569}
1570
1571/* --------------------------------------------------------------------------- */
1572
35173d57 1573static const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[] = {
6f231dda
DW
1574 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = {
1575 .enter_state = scic_sds_stp_request_started_udma_await_tc_completion_enter,
1576 },
1577 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE] = {
1578 .enter_state = scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter,
1579 },
1580};
1581
35173d57
DW
1582enum sci_status scic_sds_stp_udma_request_construct(struct scic_sds_request *sci_req,
1583 u32 len,
1584 enum dma_data_direction dir)
1585{
1586 scic_sds_stp_non_ncq_request_construct(sci_req);
1587
1588 scic_sds_stp_optimized_request_construct(sci_req, SCU_TASK_TYPE_DMA_IN,
1589 len, dir);
1590
1591 sci_base_state_machine_construct(
1592 &sci_req->started_substate_machine,
1593 &sci_req->parent.parent,
1594 scic_sds_stp_request_started_udma_substate_table,
1595 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
1596 );
1597
1598 return SCI_SUCCESS;
1599}
1600
6f231dda
DW
1601/**
1602 *
1603 * @this_request:
1604 * @completion_code:
1605 *
1606 * This method processes a TC completion. The expected TC completion is for
1607 * the transmission of the H2D register FIS containing the SATA/STP non-data
1608 * request. This method always successfully processes the TC completion.
1609 * SCI_SUCCESS This value is always returned.
1610 */
1611static enum sci_status scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler(
1612 struct scic_sds_request *this_request,
1613 u32 completion_code)
1614{
1615 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1616 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1617 scic_sds_request_set_status(
1618 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1619 );
1620
1621 sci_base_state_machine_change_state(
1622 &this_request->started_substate_machine,
1623 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
1624 );
1625 break;
1626
1627 default:
1628 /*
1629 * All other completion status cause the IO to be complete. If a NAK
1630 * was received, then it is up to the user to retry the request. */
1631 scic_sds_request_set_status(
1632 this_request,
1633 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1634 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1635 );
1636
1637 sci_base_state_machine_change_state(
1638 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
1639 );
1640 break;
1641 }
1642
1643 return SCI_SUCCESS;
1644}
1645
1646/**
1647 *
1648 * @this_request:
1649 * @completion_code:
1650 *
1651 * This method processes a TC completion. The expected TC completion is for
1652 * the transmission of the H2D register FIS containing the SATA/STP non-data
1653 * request. This method always successfully processes the TC completion.
1654 * SCI_SUCCESS This value is always returned.
1655 */
1656static enum sci_status scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler(
1657 struct scic_sds_request *this_request,
1658 u32 completion_code)
1659{
1660 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1661 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1662 scic_sds_request_set_status(
1663 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1664 );
1665
1666 sci_base_state_machine_change_state(
1667 &this_request->started_substate_machine,
1668 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
1669 );
1670 break;
1671
1672 default:
1673 /*
1674 * All other completion status cause the IO to be complete. If a NAK
1675 * was received, then it is up to the user to retry the request. */
1676 scic_sds_request_set_status(
1677 this_request,
1678 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1679 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1680 );
1681
1682 sci_base_state_machine_change_state(
1683 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
1684 );
1685 break;
1686 }
1687
1688 return SCI_SUCCESS;
1689}
1690
1691/**
1692 *
1693 * @request: This parameter specifies the request for which a frame has been
1694 * received.
1695 * @frame_index: This parameter specifies the index of the frame that has been
1696 * received.
1697 *
1698 * This method processes frames received from the target while waiting for a
1699 * device to host register FIS. If a non-register FIS is received during this
1700 * time, it is treated as a protocol violation from an IO perspective. Indicate
1701 * if the received frame was processed successfully.
1702 */
1703static enum sci_status scic_sds_stp_request_soft_reset_await_d2h_frame_handler(
1704 struct scic_sds_request *request,
1705 u32 frame_index)
1706{
1707 enum sci_status status;
1708 struct sata_fis_header *frame_header;
1709 u32 *frame_buffer;
1710 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
1711
1712 status = scic_sds_unsolicited_frame_control_get_header(
1713 &(this_request->parent.owning_controller->uf_control),
1714 frame_index,
1715 (void **)&frame_header
1716 );
1717
1718 if (status == SCI_SUCCESS) {
1719 switch (frame_header->fis_type) {
1720 case SATA_FIS_TYPE_REGD2H:
1721 scic_sds_unsolicited_frame_control_get_buffer(
1722 &(this_request->parent.owning_controller->uf_control),
1723 frame_index,
1724 (void **)&frame_buffer
1725 );
1726
1727 scic_sds_controller_copy_sata_response(
1728 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
1729 );
1730
1731 /* The command has completed with error */
1732 scic_sds_request_set_status(
1733 &this_request->parent,
1734 SCU_TASK_DONE_CHECK_RESPONSE,
1735 SCI_FAILURE_IO_RESPONSE_VALID
1736 );
1737 break;
1738
1739 default:
1740 dev_warn(scic_to_dev(request->owning_controller),
1741 "%s: IO Request:0x%p Frame Id:%d protocol "
1742 "violation occurred\n",
1743 __func__,
1744 this_request,
1745 frame_index);
1746
1747 scic_sds_request_set_status(
1748 &this_request->parent,
1749 SCU_TASK_DONE_UNEXP_FIS,
1750 SCI_FAILURE_PROTOCOL_VIOLATION
1751 );
1752 break;
1753 }
1754
1755 sci_base_state_machine_change_state(
1756 &this_request->parent.parent.state_machine,
1757 SCI_BASE_REQUEST_STATE_COMPLETED
1758 );
1759
1760 /* Frame has been decoded return it to the controller */
1761 scic_sds_controller_release_frame(
1762 this_request->parent.owning_controller, frame_index
1763 );
1764 } else
1765 dev_err(scic_to_dev(request->owning_controller),
1766 "%s: SCIC IO Request 0x%p could not get frame header "
1767 "for frame index %d, status %x\n",
1768 __func__, this_request, frame_index, status);
1769
1770 return status;
1771}
1772
1773/* --------------------------------------------------------------------------- */
1774
35173d57 1775static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_soft_reset_substate_handler_table[] = {
6f231dda
DW
1776 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE] = {
1777 .parent.start_handler = scic_sds_request_default_start_handler,
1778 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1779 .parent.complete_handler = scic_sds_request_default_complete_handler,
1780 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1781 .tc_completion_handler = scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler,
1782 .event_handler = scic_sds_request_default_event_handler,
1783 .frame_handler = scic_sds_request_default_frame_handler,
1784 },
1785 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE] = {
1786 .parent.start_handler = scic_sds_request_default_start_handler,
1787 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1788 .parent.complete_handler = scic_sds_request_default_complete_handler,
1789 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1790 .tc_completion_handler = scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler,
1791 .event_handler = scic_sds_request_default_event_handler,
1792 .frame_handler = scic_sds_request_default_frame_handler,
1793 },
1794 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE] = {
1795 .parent.start_handler = scic_sds_request_default_start_handler,
1796 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1797 .parent.complete_handler = scic_sds_request_default_complete_handler,
1798 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1799 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1800 .event_handler = scic_sds_request_default_event_handler,
1801 .frame_handler = scic_sds_stp_request_soft_reset_await_d2h_frame_handler,
1802 },
1803};
1804
1805static void scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(
1806 struct sci_base_object *object)
1807{
1808 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1809
1810 SET_STATE_HANDLER(
1811 this_request,
1812 scic_sds_stp_request_started_soft_reset_substate_handler_table,
1813 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
1814 );
1815
1816 scic_sds_remote_device_set_working_request(
1817 this_request->target_device, this_request
1818 );
1819}
1820
1821static void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(
1822 struct sci_base_object *object)
1823{
1824 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1825 sci_base_controller_request_handler_t continue_io;
1826 struct scu_task_context *task_context;
1827 struct sata_fis_reg_h2d *h2d_fis;
1828 struct scic_sds_controller *scic;
1829 enum sci_status status;
1830 u32 state;
1831
1832 /* Clear the SRST bit */
1833 h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request);
1834 h2d_fis->control = 0;
1835
1836 /* Clear the TC control bit */
1837 task_context = scic_sds_controller_get_task_context_buffer(
1838 this_request->owning_controller, this_request->io_tag);
1839 task_context->control_frame = 0;
1840
1841 scic = this_request->owning_controller;
1842 state = scic->parent.state_machine.current_state_id;
1843 continue_io = scic_sds_controller_state_handler_table[state].base.continue_io;
1844
1845 status = continue_io(&scic->parent, &this_request->target_device->parent,
1846 &this_request->parent);
1847
1848 if (status == SCI_SUCCESS) {
1849 SET_STATE_HANDLER(
1850 this_request,
1851 scic_sds_stp_request_started_soft_reset_substate_handler_table,
1852 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
1853 );
1854 }
1855}
1856
1857static void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter(
1858 struct sci_base_object *object)
1859{
1860 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1861
1862 SET_STATE_HANDLER(
1863 this_request,
1864 scic_sds_stp_request_started_soft_reset_substate_handler_table,
1865 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
1866 );
1867}
1868
35173d57 1869static const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_table[] = {
6f231dda
DW
1870 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE] = {
1871 .enter_state = scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
1872 },
1873 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE] = {
1874 .enter_state = scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
1875 },
1876 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE] = {
1877 .enter_state = scic_sds_stp_request_started_soft_reset_await_d2h_response_enter,
1878 },
1879};
1880
35173d57
DW
1881enum sci_status scic_sds_stp_soft_reset_request_construct(struct scic_sds_request *sci_req)
1882{
1883 struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent);
1884
1885 scic_sds_stp_non_ncq_request_construct(sci_req);
1886
1887 /* Build the STP task context structure */
1888 scu_stp_raw_request_construct_task_context(stp_req, sci_req->task_context_buffer);
1889
1890 sci_base_state_machine_construct(&sci_req->started_substate_machine,
1891 &sci_req->parent.parent,
1892 scic_sds_stp_request_started_soft_reset_substate_table,
1893 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE);
1894
1895 return SCI_SUCCESS;
1896}
This page took 0.101587 seconds and 5 git commands to generate.