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.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
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
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.
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.
55 #if !defined(DISABLE_ATAPI)
57 #include "intel_ata.h"
58 #include "intel_sas.h"
59 #include "intel_sata.h"
60 #include "intel_sat.h"
61 #include "sati_translator_sequence.h"
62 #include "sci_base_state.h"
63 #include "scic_controller.h"
64 #include "scic_remote_device.h"
65 #include "scic_sds_controller.h"
66 #include "scic_sds_remote_device.h"
67 #include "scic_sds_request.h"
68 #include "scic_sds_stp_packet_request.h"
69 #include "scic_user_callback.h"
71 #include "scu_completion_codes.h"
72 #include "scu_task_context.h"
76 * This method will fill in the SCU Task Context for a PACKET fis. And
77 * construct the request STARTED sub-state machine for Packet Protocol IO.
78 * @this_request: This parameter specifies the stp packet request object being
82 enum sci_status scic_sds_stp_packet_request_construct(
83 struct scic_sds_request *this_request)
85 struct sata_fis_reg_h2d *h2d_fis =
86 scic_stp_io_request_get_h2d_reg_address(
91 * Work around, we currently only support PACKET DMA protocol, so we
92 * need to make change to Packet Fis features field. */
93 h2d_fis->features = h2d_fis->features | ATA_PACKET_FEATURE_DMA;
95 scic_sds_stp_non_ncq_request_construct(this_request);
97 /* Build the Packet Fis task context structure */
98 scu_stp_raw_request_construct_task_context(
99 (struct scic_sds_stp_request *)this_request,
100 this_request->task_context_buffer
103 sci_base_state_machine_construct(
104 &this_request->started_substate_machine,
105 &this_request->parent.parent,
106 scic_sds_stp_packet_request_started_substate_table,
107 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
115 * This method will fill in the SCU Task Context for a Packet request command
116 * phase in PACKET DMA DATA (IN/OUT) type. The following important settings
117 * are utilized: -# task_type == SCU_TASK_TYPE_PACKET_DMA. This simply
118 * indicates that a normal request type (i.e. non-raw frame) is being
119 * utilized to perform task management. -# control_frame == 1. This ensures
120 * that the proper endianess is set so that the bytes are transmitted in the
121 * right order for a smp request frame.
122 * @this_request: This parameter specifies the smp request object being
124 * @task_context: The task_context to be reconstruct for packet request command
128 void scu_stp_packet_request_command_phase_construct_task_context(
129 struct scic_sds_request *this_request,
130 struct scu_task_context *task_context)
133 u32 atapi_cdb_length;
134 struct scic_sds_stp_request *stp_request = (struct scic_sds_stp_request *)this_request;
137 * reference: SSTL 1.13.4.2
138 * task_type, sata_direction */
139 if (scic_cb_io_request_get_data_direction(this_request->user_request)
140 == SCI_IO_REQUEST_DATA_OUT) {
141 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_OUT;
142 task_context->sata_direction = 0;
143 } else { /* todo: for NO_DATA command, we need to send out raw frame. */
144 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_IN;
145 task_context->sata_direction = 1;
149 memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
150 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
153 * Copy in the command IU with CDB so that the commandIU address doesn't
155 memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
158 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
161 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
163 memcpy(((u8 *)this_request->command_buffer + sizeof(u32)), atapi_cdb, atapi_cdb_length);
166 max(atapi_cdb_length, stp_request->type.packet.device_preferred_cdb_length);
168 task_context->ssp_command_iu_length =
169 ((atapi_cdb_length % 4) == 0) ?
170 (atapi_cdb_length / 4) : ((atapi_cdb_length / 4) + 1);
172 /* task phase is set to TX_CMD */
173 task_context->task_phase = 0x1;
176 task_context->stp_retry_count = 0;
178 if (scic_cb_request_is_initial_construction(this_request->user_request)) {
179 /* data transfer size. */
180 task_context->transfer_length_bytes =
181 scic_cb_io_request_get_transfer_length(this_request->user_request);
184 scic_sds_request_build_sgl(this_request);
186 /* data transfer size, need to be 4 bytes aligned. */
187 task_context->transfer_length_bytes = (SCSI_FIXED_SENSE_DATA_BASE_LENGTH + 2);
189 scic_sds_stp_packet_internal_request_sense_build_sgl(this_request);
194 * This method will fill in the SCU Task Context for a DATA fis containing CDB
195 * in Raw Frame type. The TC for previous Packet fis was already there, we
196 * only need to change the H2D fis content.
197 * @this_request: This parameter specifies the smp request object being
199 * @task_context: The task_context to be reconstruct for packet request command
203 void scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
204 struct scic_sds_request *this_request,
205 struct scu_task_context *task_context)
208 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
210 u32 atapi_cdb_length =
211 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
213 memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
214 memcpy(((u8 *)this_request->command_buffer + sizeof(u32)), atapi_cdb, atapi_cdb_length);
216 memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
217 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
220 * Note the data send out has to be 4 bytes aligned. Or else out hardware will
221 * patch non-zero bytes and cause the target device unhappy. */
222 task_context->transfer_length_bytes = 12;
227 * *@brief This methods decode the D2H status FIS and retrieve the sense data,
228 * then pass the sense data to user request.
230 ***@param[in] this_request The request receive D2H status FIS.
231 ***@param[in] status_fis The D2H status fis to be processed.
234 enum sci_status scic_sds_stp_packet_request_process_status_fis(
235 struct scic_sds_request *this_request,
236 struct sata_fis_reg_d2h *status_fis)
238 enum sci_status status = SCI_SUCCESS;
240 /* TODO: Process the error status fis, retrieve sense data. */
241 if (status_fis->status & ATA_STATUS_REG_ERROR_BIT)
242 status = SCI_FAILURE_IO_RESPONSE_VALID;
248 * *@brief This methods builds sgl for internal REQUEST SENSE stp packet
249 * command using this request response buffer, only one sge is
252 ***@param[in] this_request The request receive request sense data.
255 void scic_sds_stp_packet_internal_request_sense_build_sgl(
256 struct scic_sds_request *this_request)
259 struct scu_sgl_element_pair *scu_sgl_list = NULL;
260 struct scu_task_context *task_context;
261 dma_addr_t physical_address;
263 struct sci_ssp_response_iu *rsp_iu =
264 (struct sci_ssp_response_iu *)this_request->response_buffer;
266 sge = (void *)&rsp_iu->data[0];
268 task_context = (struct scu_task_context *)this_request->task_context_buffer;
269 scu_sgl_list = &task_context->sgl_pair_ab;
271 scic_cb_io_request_get_physical_address(
272 scic_sds_request_get_controller(this_request),
278 scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address);
279 scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address);
280 scu_sgl_list->A.length = task_context->transfer_length_bytes;
281 scu_sgl_list->A.address_modifier = 0;
283 SCU_SGL_ZERO(scu_sgl_list->B);
287 * This method processes the completions transport layer (TL) status to
288 * determine if the Packet FIS was sent successfully. If the Packet FIS was
289 * sent successfully, then the state for the Packet request transits to
290 * waiting for a PIO SETUP frame.
291 * @this_request: This parameter specifies the request for which the TC
292 * completion was received.
293 * @completion_code: This parameter indicates the completion status information
296 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
297 * this method always returns success.
299 enum sci_status scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(
300 struct scic_sds_request *this_request,
303 enum sci_status status = SCI_SUCCESS;
305 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
306 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
307 scic_sds_request_set_status(
308 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
311 sci_base_state_machine_change_state(
312 &this_request->started_substate_machine,
313 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
319 * All other completion status cause the IO to be complete. If a NAK
320 * was received, then it is up to the user to retry the request. */
321 scic_sds_request_set_status(
323 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
324 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
327 sci_base_state_machine_change_state(
328 &this_request->parent.state_machine,
329 SCI_BASE_REQUEST_STATE_COMPLETED
339 * This method processes an unsolicited frame while the Packet request is
340 * waiting for a PIO SETUP FIS. It will release the unsolicited frame, and
341 * transition the request to the COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
343 * @this_request: This parameter specifies the request for which the
344 * unsolicited frame was received.
345 * @frame_index: This parameter indicates the unsolicited frame index that
346 * should contain the response.
348 * This method returns an indication of whether the pio setup frame was handled
349 * successfully or not. SCI_SUCCESS Currently this value is always returned and
350 * indicates successful processing of the TC response.
352 enum sci_status scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(
353 struct scic_sds_request *request,
356 enum sci_status status;
357 struct sata_fis_header *frame_header;
359 struct scic_sds_stp_request *this_request;
361 this_request = (struct scic_sds_stp_request *)request;
363 status = scic_sds_unsolicited_frame_control_get_header(
364 &(this_request->parent.owning_controller->uf_control),
366 (void **)&frame_header
369 if (status == SCI_SUCCESS) {
370 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_PIO_SETUP);
373 * Get from the frame buffer the PIO Setup Data, although we don't need
374 * any info from this pio setup fis. */
375 scic_sds_unsolicited_frame_control_get_buffer(
376 &(this_request->parent.owning_controller->uf_control),
378 (void **)&frame_buffer
382 * Get the data from the PIO Setup
383 * The SCU Hardware returns first word in the frame_header and the rest
384 * of the data is in the frame buffer so we need to back up one dword */
385 this_request->type.packet.device_preferred_cdb_length =
386 (u16)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->transfter_count;
388 /* Frame has been decoded return it to the controller */
389 scic_sds_controller_release_frame(
390 this_request->parent.owning_controller, frame_index
393 sci_base_state_machine_change_state(
394 &this_request->parent.started_substate_machine,
395 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
398 dev_err(scic_to_dev(request->owning_controller),
399 "%s: SCIC IO Request 0x%p could not get frame header "
400 "for frame index %d, status %x\n",
401 __func__, this_request, frame_index, status);
408 * This method processes the completions transport layer (TL) status to
409 * determine if the PACKET command data FIS was sent successfully. If
410 * successfully, then the state for the packet request transits to COMPLETE
411 * state. If not successfuly, the request transits to
412 * COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE.
413 * @this_request: This parameter specifies the request for which the TC
414 * completion was received.
415 * @completion_code: This parameter indicates the completion status information
418 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
419 * this method always returns success.
421 enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(
422 struct scic_sds_request *this_request,
425 enum sci_status status = SCI_SUCCESS;
426 u8 sat_packet_protocol =
427 scic_cb_request_get_sat_protocol(this_request->user_request);
429 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
430 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
431 scic_sds_request_set_status(
432 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
435 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_IN
436 || sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_OUT
438 sci_base_state_machine_change_state(
439 &this_request->parent.state_machine,
440 SCI_BASE_REQUEST_STATE_COMPLETED
443 sci_base_state_machine_change_state(
444 &this_request->started_substate_machine,
445 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
449 case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT):
450 if (scic_io_request_get_number_of_bytes_transferred(this_request) <
451 scic_cb_io_request_get_transfer_length(this_request->user_request)) {
452 scic_sds_request_set_status(
453 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
456 sci_base_state_machine_change_state(
457 &this_request->parent.state_machine,
458 SCI_BASE_REQUEST_STATE_COMPLETED
461 status = this_request->sci_status;
465 case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT):
466 /* In this case, there is no UF coming after. compelte the IO now. */
467 scic_sds_request_set_status(
468 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
471 sci_base_state_machine_change_state(
472 &this_request->parent.state_machine,
473 SCI_BASE_REQUEST_STATE_COMPLETED
479 if (this_request->sci_status != SCI_SUCCESS) { /* The io status was set already. This means an UF for the status
480 * fis was received already.
484 * A device suspension event is expected, we need to have the device
485 * coming out of suspension, then complete the IO. */
486 sci_base_state_machine_change_state(
487 &this_request->started_substate_machine,
488 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
491 /* change the device state to ATAPI_ERROR. */
492 sci_base_state_machine_change_state(
493 &this_request->target_device->ready_substate_machine,
494 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
497 status = this_request->sci_status;
498 } else { /* If receiving any non-sucess TC status, no UF received yet, then an UF for
499 * the status fis is coming after.
501 scic_sds_request_set_status(
503 SCU_TASK_DONE_CHECK_RESPONSE,
504 SCI_FAILURE_IO_RESPONSE_VALID
507 sci_base_state_machine_change_state(
508 &this_request->started_substate_machine,
509 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
520 * This method processes an unsolicited frame.
521 * @this_request: This parameter specifies the request for which the
522 * unsolicited frame was received.
523 * @frame_index: This parameter indicates the unsolicited frame index that
524 * should contain the response.
526 * This method returns an indication of whether the UF frame was handled
527 * successfully or not. SCI_SUCCESS Currently this value is always returned and
528 * indicates successful processing of the TC response.
530 enum sci_status scic_sds_stp_packet_request_command_phase_common_frame_handler(
531 struct scic_sds_request *request,
534 enum sci_status status;
535 struct sata_fis_header *frame_header;
537 struct scic_sds_stp_request *this_request;
539 this_request = (struct scic_sds_stp_request *)request;
541 status = scic_sds_unsolicited_frame_control_get_header(
542 &(this_request->parent.owning_controller->uf_control),
544 (void **)&frame_header
547 if (status == SCI_SUCCESS) {
548 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_REGD2H);
551 * Get from the frame buffer the PIO Setup Data, although we don't need
552 * any info from this pio setup fis. */
553 scic_sds_unsolicited_frame_control_get_buffer(
554 &(this_request->parent.owning_controller->uf_control),
556 (void **)&frame_buffer
559 scic_sds_controller_copy_sata_response(
560 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
563 /* Frame has been decoded return it to the controller */
564 scic_sds_controller_release_frame(
565 this_request->parent.owning_controller, frame_index
573 * This method processes an unsolicited frame while the packet request is
574 * expecting TC completion. It will process the FIS and construct sense data.
575 * @this_request: This parameter specifies the request for which the
576 * unsolicited frame was received.
577 * @frame_index: This parameter indicates the unsolicited frame index that
578 * should contain the response.
580 * This method returns an indication of whether the UF frame was handled
581 * successfully or not. SCI_SUCCESS Currently this value is always returned and
582 * indicates successful processing of the TC response.
584 enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler(
585 struct scic_sds_request *request,
588 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
590 enum sci_status status =
591 scic_sds_stp_packet_request_command_phase_common_frame_handler(
592 request, frame_index);
594 if (status == SCI_SUCCESS) {
595 /* The command has completed with error status from target device. */
596 status = scic_sds_stp_packet_request_process_status_fis(
597 request, &this_request->d2h_reg_fis);
599 if (status != SCI_SUCCESS) {
600 scic_sds_request_set_status(
601 &this_request->parent,
602 SCU_TASK_DONE_CHECK_RESPONSE,
606 scic_sds_request_set_status(
607 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
616 * This method processes an unsolicited frame while the packet request is
617 * expecting TC completion. It will process the FIS and construct sense data.
618 * @this_request: This parameter specifies the request for which the
619 * unsolicited frame was received.
620 * @frame_index: This parameter indicates the unsolicited frame index that
621 * should contain the response.
623 * This method returns an indication of whether the UF frame was handled
624 * successfully or not. SCI_SUCCESS Currently this value is always returned and
625 * indicates successful processing of the TC response.
627 enum sci_status scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler(
628 struct scic_sds_request *request,
631 enum sci_status status =
632 scic_sds_stp_packet_request_command_phase_common_frame_handler(
633 request, frame_index);
635 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
637 if (status == SCI_SUCCESS) {
638 /* The command has completed with error status from target device. */
639 status = scic_sds_stp_packet_request_process_status_fis(
640 request, &this_request->d2h_reg_fis);
642 if (status != SCI_SUCCESS) {
643 scic_sds_request_set_status(
645 SCU_TASK_DONE_CHECK_RESPONSE,
649 scic_sds_request_set_status(
650 request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
654 * Always complete the NON_DATA command right away, no need to delay completion
655 * even an error status fis came from target device. */
656 sci_base_state_machine_change_state(
657 &request->parent.state_machine,
658 SCI_BASE_REQUEST_STATE_COMPLETED
665 enum sci_status scic_sds_stp_packet_request_started_completion_delay_complete_handler(
666 struct sci_base_request *request)
668 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
670 sci_base_state_machine_change_state(
671 &this_request->parent.state_machine,
672 SCI_BASE_REQUEST_STATE_COMPLETED
675 return this_request->sci_status;
678 /* --------------------------------------------------------------------------- */
680 const struct scic_sds_io_request_state_handler scic_sds_stp_packet_request_started_substate_handler_table[] = {
681 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
682 .parent.start_handler = scic_sds_request_default_start_handler,
683 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
684 .parent.complete_handler = scic_sds_request_default_complete_handler,
685 .parent.destruct_handler = scic_sds_request_default_destruct_handler
686 .tc_completion_handler = scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler,
687 .event_handler = scic_sds_request_default_event_handler,
688 .frame_handler = scic_sds_request_default_frame_handler
690 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
691 .parent.start_handler = scic_sds_request_default_start_handler,
692 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
693 .parent.complete_handler = scic_sds_request_default_complete_handler,
694 .parent.destruct_handler = scic_sds_request_default_destruct_handler
695 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
696 .event_handler = scic_sds_request_default_event_handler,
697 .frame_handler = scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler
699 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
700 .parent.start_handler = scic_sds_request_default_start_handler,
701 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
702 .parent.complete_handler = scic_sds_request_default_complete_handler,
703 .parent.destruct_handler = scic_sds_request_default_destruct_handler
704 .tc_completion_handler = scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler,
705 .event_handler = scic_sds_request_default_event_handler,
706 .frame_handler = scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler
708 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
709 .parent.start_handler = scic_sds_request_default_start_handler,
710 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
711 .parent.complete_handler = scic_sds_request_default_complete_handler,
712 .parent.destruct_handler = scic_sds_request_default_destruct_handler
713 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
714 .event_handler = scic_sds_request_default_event_handler,
715 .frame_handler = scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler
717 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
718 .parent.start_handler = scic_sds_request_default_start_handler,
719 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
720 .parent.complete_handler = scic_sds_stp_packet_request_started_completion_delay_complete_handler,
721 .parent.destruct_handler = scic_sds_request_default_destruct_handler
722 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
723 .event_handler = scic_sds_request_default_event_handler,
724 .frame_handler = scic_sds_request_default_frame_handler
728 void scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter(
729 struct sci_base_object *object)
731 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
735 scic_sds_stp_packet_request_started_substate_handler_table,
736 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
739 scic_sds_remote_device_set_working_request(
740 this_request->target_device, this_request
744 void scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter(
745 struct sci_base_object *object)
747 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
751 scic_sds_stp_packet_request_started_substate_handler_table,
752 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
756 void scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter(
757 struct sci_base_object *object)
759 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
760 u8 sat_packet_protocol =
761 scic_cb_request_get_sat_protocol(this_request->user_request);
763 struct scu_task_context *task_context;
764 enum sci_status status;
767 * Recycle the TC and reconstruct it for sending out data fis containing
769 task_context = scic_sds_controller_get_task_context_buffer(
770 this_request->owning_controller, this_request->io_tag);
772 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_NON_DATA)
773 scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
774 this_request, task_context);
776 scu_stp_packet_request_command_phase_construct_task_context(
777 this_request, task_context);
779 /* send the new TC out. */
780 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
781 &this_request->owning_controller->parent,
782 &this_request->target_device->parent,
783 &this_request->parent
786 if (status == SCI_SUCCESS)
789 scic_sds_stp_packet_request_started_substate_handler_table,
790 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
794 void scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter(
795 struct sci_base_object *object)
797 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
801 scic_sds_stp_packet_request_started_substate_handler_table,
802 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
806 void scic_sds_stp_packet_request_started_completion_delay_enter(
807 struct sci_base_object *object)
809 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
813 scic_sds_stp_packet_request_started_substate_handler_table,
814 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
819 /* --------------------------------------------------------------------------- */
820 const struct sci_base_state scic_sds_stp_packet_request_started_substate_table[] = {
821 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
822 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter,
824 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
825 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter,
827 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
828 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter,
830 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
831 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter,
833 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
834 .enter_state scic_sds_stp_packet_request_started_completion_delay_enter,
838 #endif /* !defined(DISABLE_ATAPI) */