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 * @sci_req: This parameter specifies the stp packet request object being
82 enum sci_status scic_sds_stp_packet_request_construct(
83 struct scic_sds_request *sci_req)
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(sci_req);
97 /* Build the Packet Fis task context structure */
98 scu_stp_raw_request_construct_task_context(
99 (struct scic_sds_stp_request *)sci_req,
100 sci_req->task_context_buffer
103 sci_base_state_machine_construct(
104 &sci_req->started_substate_machine,
105 &sci_req->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 * @sci_req: 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 *sci_req,
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 *)sci_req;
137 * reference: SSTL 1.13.4.2
138 * task_type, sata_direction */
139 if (scic_cb_io_request_get_data_direction(sci_req->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(sci_req->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
158 scic_cb_stp_packet_io_request_get_cdb_address(sci_req->user_request);
161 scic_cb_stp_packet_io_request_get_cdb_length(sci_req->user_request);
163 memcpy(((u8 *)sci_req->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(sci_req->user_request)) {
179 /* data transfer size. */
180 task_context->transfer_length_bytes =
181 scic_cb_io_request_get_transfer_length(sci_req->user_request);
184 scic_sds_request_build_sgl(sci_req);
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(sci_req);
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 * @sci_req: 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 *sci_req,
205 struct scu_task_context *task_context)
208 scic_cb_stp_packet_io_request_get_cdb_address(sci_req->user_request);
210 u32 atapi_cdb_length =
211 scic_cb_stp_packet_io_request_get_cdb_length(sci_req->user_request);
213 memset(sci_req->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
214 memcpy(((u8 *)sci_req->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] sci_req 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 *sci_req,
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] sci_req The request receive request sense data.
255 void scic_sds_stp_packet_internal_request_sense_build_sgl(
256 struct scic_sds_request *sds_request)
259 struct scu_sgl_element_pair *scu_sgl_list = NULL;
260 struct scu_task_context *task_context;
263 struct sci_ssp_response_iu *rsp_iu =
264 (struct sci_ssp_response_iu *)sds_request->response_buffer;
266 sge = (void *)&rsp_iu->data[0];
269 (struct scu_task_context *)sds_request->task_context_buffer;
270 scu_sgl_list = &task_context->sgl_pair_ab;
272 dma_addr = scic_io_request_get_dma_addr(sds_request, sge);
274 scu_sgl_list->A.address_upper = upper_32_bits(dma_addr);
275 scu_sgl_list->A.address_lower = lower_32_bits(dma_addr);
276 scu_sgl_list->A.length = task_context->transfer_length_bytes;
277 scu_sgl_list->A.address_modifier = 0;
279 SCU_SGL_ZERO(scu_sgl_list->B);
283 * This method processes the completions transport layer (TL) status to
284 * determine if the Packet FIS was sent successfully. If the Packet FIS was
285 * sent successfully, then the state for the Packet request transits to
286 * waiting for a PIO SETUP frame.
287 * @sci_req: This parameter specifies the request for which the TC
288 * completion was received.
289 * @completion_code: This parameter indicates the completion status information
292 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
293 * this method always returns success.
295 enum sci_status scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(
296 struct scic_sds_request *sci_req,
299 enum sci_status status = SCI_SUCCESS;
301 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
302 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
303 scic_sds_request_set_status(
304 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
307 sci_base_state_machine_change_state(
308 &sci_req->started_substate_machine,
309 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
315 * All other completion status cause the IO to be complete. If a NAK
316 * was received, then it is up to the user to retry the request. */
317 scic_sds_request_set_status(
319 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
320 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
323 sci_base_state_machine_change_state(
324 &sci_req->parent.state_machine,
325 SCI_BASE_REQUEST_STATE_COMPLETED
335 * This method processes an unsolicited frame while the Packet request is
336 * waiting for a PIO SETUP FIS. It will release the unsolicited frame, and
337 * transition the request to the COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
339 * @sci_req: This parameter specifies the request for which the
340 * unsolicited frame was received.
341 * @frame_index: This parameter indicates the unsolicited frame index that
342 * should contain the response.
344 * This method returns an indication of whether the pio setup frame was handled
345 * successfully or not. SCI_SUCCESS Currently this value is always returned and
346 * indicates successful processing of the TC response.
348 enum sci_status scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(
349 struct scic_sds_request *request,
352 enum sci_status status;
353 struct sata_fis_header *frame_header;
355 struct scic_sds_stp_request *sci_req;
357 sci_req = (struct scic_sds_stp_request *)request;
359 status = scic_sds_unsolicited_frame_control_get_header(
360 &(sci_req->parent.owning_controller->uf_control),
362 (void **)&frame_header
365 if (status == SCI_SUCCESS) {
366 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_PIO_SETUP);
369 * Get from the frame buffer the PIO Setup Data, although we don't need
370 * any info from this pio setup fis. */
371 scic_sds_unsolicited_frame_control_get_buffer(
372 &(sci_req->parent.owning_controller->uf_control),
374 (void **)&frame_buffer
378 * Get the data from the PIO Setup
379 * The SCU Hardware returns first word in the frame_header and the rest
380 * of the data is in the frame buffer so we need to back up one dword */
381 sci_req->type.packet.device_preferred_cdb_length =
382 (u16)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->transfter_count;
384 /* Frame has been decoded return it to the controller */
385 scic_sds_controller_release_frame(
386 sci_req->parent.owning_controller, frame_index
389 sci_base_state_machine_change_state(
390 &sci_req->parent.started_substate_machine,
391 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
394 dev_err(scic_to_dev(request->owning_controller),
395 "%s: SCIC IO Request 0x%p could not get frame header "
396 "for frame index %d, status %x\n",
397 __func__, sci_req, frame_index, status);
404 * This method processes the completions transport layer (TL) status to
405 * determine if the PACKET command data FIS was sent successfully. If
406 * successfully, then the state for the packet request transits to COMPLETE
407 * state. If not successfuly, the request transits to
408 * COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE.
409 * @sci_req: This parameter specifies the request for which the TC
410 * completion was received.
411 * @completion_code: This parameter indicates the completion status information
414 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
415 * this method always returns success.
417 enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(
418 struct scic_sds_request *sci_req,
421 enum sci_status status = SCI_SUCCESS;
422 u8 sat_packet_protocol =
423 scic_cb_request_get_sat_protocol(sci_req->user_request);
425 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
426 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
427 scic_sds_request_set_status(
428 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
431 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_IN
432 || sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_OUT
434 sci_base_state_machine_change_state(
435 &sci_req->parent.state_machine,
436 SCI_BASE_REQUEST_STATE_COMPLETED
439 sci_base_state_machine_change_state(
440 &sci_req->started_substate_machine,
441 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
445 case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT):
446 if (scic_io_request_get_number_of_bytes_transferred(sci_req) <
447 scic_cb_io_request_get_transfer_length(sci_req->user_request)) {
448 scic_sds_request_set_status(
449 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
452 sci_base_state_machine_change_state(
453 &sci_req->parent.state_machine,
454 SCI_BASE_REQUEST_STATE_COMPLETED
457 status = sci_req->sci_status;
461 case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT):
462 /* In this case, there is no UF coming after. compelte the IO now. */
463 scic_sds_request_set_status(
464 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
467 sci_base_state_machine_change_state(
468 &sci_req->parent.state_machine,
469 SCI_BASE_REQUEST_STATE_COMPLETED
475 if (sci_req->sci_status != SCI_SUCCESS) { /* The io status was set already. This means an UF for the status
476 * fis was received already.
480 * A device suspension event is expected, we need to have the device
481 * coming out of suspension, then complete the IO. */
482 sci_base_state_machine_change_state(
483 &sci_req->started_substate_machine,
484 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
487 /* change the device state to ATAPI_ERROR. */
488 sci_base_state_machine_change_state(
489 &sci_req->target_device->ready_substate_machine,
490 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
493 status = sci_req->sci_status;
494 } else { /* If receiving any non-sucess TC status, no UF received yet, then an UF for
495 * the status fis is coming after.
497 scic_sds_request_set_status(
499 SCU_TASK_DONE_CHECK_RESPONSE,
500 SCI_FAILURE_IO_RESPONSE_VALID
503 sci_base_state_machine_change_state(
504 &sci_req->started_substate_machine,
505 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
516 * This method processes an unsolicited frame.
517 * @sci_req: This parameter specifies the request for which the
518 * unsolicited frame was received.
519 * @frame_index: This parameter indicates the unsolicited frame index that
520 * should contain the response.
522 * This method returns an indication of whether the UF frame was handled
523 * successfully or not. SCI_SUCCESS Currently this value is always returned and
524 * indicates successful processing of the TC response.
526 enum sci_status scic_sds_stp_packet_request_command_phase_common_frame_handler(
527 struct scic_sds_request *request,
530 enum sci_status status;
531 struct sata_fis_header *frame_header;
533 struct scic_sds_stp_request *sci_req;
535 sci_req = (struct scic_sds_stp_request *)request;
537 status = scic_sds_unsolicited_frame_control_get_header(
538 &(sci_req->parent.owning_controller->uf_control),
540 (void **)&frame_header
543 if (status == SCI_SUCCESS) {
544 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_REGD2H);
547 * Get from the frame buffer the PIO Setup Data, although we don't need
548 * any info from this pio setup fis. */
549 scic_sds_unsolicited_frame_control_get_buffer(
550 &(sci_req->parent.owning_controller->uf_control),
552 (void **)&frame_buffer
555 scic_sds_controller_copy_sata_response(
556 &sci_req->d2h_reg_fis, (u32 *)frame_header, frame_buffer
559 /* Frame has been decoded return it to the controller */
560 scic_sds_controller_release_frame(
561 sci_req->parent.owning_controller, frame_index
569 * This method processes an unsolicited frame while the packet request is
570 * expecting TC completion. It will process the FIS and construct sense data.
571 * @sci_req: This parameter specifies the request for which the
572 * unsolicited frame was received.
573 * @frame_index: This parameter indicates the unsolicited frame index that
574 * should contain the response.
576 * This method returns an indication of whether the UF frame was handled
577 * successfully or not. SCI_SUCCESS Currently this value is always returned and
578 * indicates successful processing of the TC response.
580 enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler(
581 struct scic_sds_request *request,
584 struct scic_sds_stp_request *sci_req = (struct scic_sds_stp_request *)request;
586 enum sci_status status =
587 scic_sds_stp_packet_request_command_phase_common_frame_handler(
588 request, frame_index);
590 if (status == SCI_SUCCESS) {
591 /* The command has completed with error status from target device. */
592 status = scic_sds_stp_packet_request_process_status_fis(
593 request, &sci_req->d2h_reg_fis);
595 if (status != SCI_SUCCESS) {
596 scic_sds_request_set_status(
598 SCU_TASK_DONE_CHECK_RESPONSE,
602 scic_sds_request_set_status(
603 &sci_req->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
612 * This method processes an unsolicited frame while the packet request is
613 * expecting TC completion. It will process the FIS and construct sense data.
614 * @sci_req: This parameter specifies the request for which the
615 * unsolicited frame was received.
616 * @frame_index: This parameter indicates the unsolicited frame index that
617 * should contain the response.
619 * This method returns an indication of whether the UF frame was handled
620 * successfully or not. SCI_SUCCESS Currently this value is always returned and
621 * indicates successful processing of the TC response.
623 enum sci_status scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler(
624 struct scic_sds_request *request,
627 enum sci_status status =
628 scic_sds_stp_packet_request_command_phase_common_frame_handler(
629 request, frame_index);
631 struct scic_sds_stp_request *sci_req = (struct scic_sds_stp_request *)request;
633 if (status == SCI_SUCCESS) {
634 /* The command has completed with error status from target device. */
635 status = scic_sds_stp_packet_request_process_status_fis(
636 request, &sci_req->d2h_reg_fis);
638 if (status != SCI_SUCCESS) {
639 scic_sds_request_set_status(
641 SCU_TASK_DONE_CHECK_RESPONSE,
645 scic_sds_request_set_status(
646 request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
650 * Always complete the NON_DATA command right away, no need to delay completion
651 * even an error status fis came from target device. */
652 sci_base_state_machine_change_state(
653 &request->parent.state_machine,
654 SCI_BASE_REQUEST_STATE_COMPLETED
661 enum sci_status scic_sds_stp_packet_request_started_completion_delay_complete_handler(
662 struct scic_sds_request *request)
664 sci_base_state_machine_change_state(&request->parent.state_machine,
665 SCI_BASE_REQUEST_STATE_COMPLETED);
667 return request->sci_status;
670 /* --------------------------------------------------------------------------- */
672 const struct scic_sds_io_request_state_handler scic_sds_stp_packet_request_started_substate_handler_table[] = {
673 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
674 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
675 .tc_completion_handler = scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler,
677 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
678 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
679 .frame_handler = scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler
681 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
682 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
683 .tc_completion_handler = scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler,
684 .frame_handler = scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler
686 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
687 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
688 .frame_handler = scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler
690 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
691 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
692 .parent.complete_handler = scic_sds_stp_packet_request_started_completion_delay_complete_handler,
696 void scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter(
697 struct sci_base_object *object)
699 struct scic_sds_request *sci_req = (struct scic_sds_request *)object;
703 scic_sds_stp_packet_request_started_substate_handler_table,
704 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
707 scic_sds_remote_device_set_working_request(
708 sci_req->target_device, sci_req
712 void scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter(
713 struct sci_base_object *object)
715 struct scic_sds_request *sci_req = (struct scic_sds_request *)object;
719 scic_sds_stp_packet_request_started_substate_handler_table,
720 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
724 void scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter(
725 struct sci_base_object *object)
727 struct scic_sds_request *sci_req = (struct scic_sds_request *)object;
728 u8 sat_packet_protocol =
729 scic_cb_request_get_sat_protocol(sci_req->user_request);
731 struct scu_task_context *task_context;
732 enum sci_status status;
735 * Recycle the TC and reconstruct it for sending out data fis containing
737 task_context = scic_sds_controller_get_task_context_buffer(
738 sci_req->owning_controller, sci_req->io_tag);
740 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_NON_DATA)
741 scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
742 sci_req, task_context);
744 scu_stp_packet_request_command_phase_construct_task_context(
745 sci_req, task_context);
747 /* send the new TC out. */
748 status = sci_req->owning_controller->state_handlers->parent.continue_io_handler(
749 &sci_req->owning_controller->parent,
750 &sci_req->target_device->parent,
754 if (status == SCI_SUCCESS)
757 scic_sds_stp_packet_request_started_substate_handler_table,
758 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
762 void scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter(
763 struct sci_base_object *object)
765 struct scic_sds_request *sci_req = (struct scic_sds_request *)object;
769 scic_sds_stp_packet_request_started_substate_handler_table,
770 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
774 void scic_sds_stp_packet_request_started_completion_delay_enter(
775 struct sci_base_object *object)
777 struct scic_sds_request *sci_req = (struct scic_sds_request *)object;
781 scic_sds_stp_packet_request_started_substate_handler_table,
782 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
787 /* --------------------------------------------------------------------------- */
788 const struct sci_base_state scic_sds_stp_packet_request_started_substate_table[] = {
789 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
790 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter,
792 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
793 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter,
795 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
796 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter,
798 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
799 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter,
801 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
802 .enter_state scic_sds_stp_packet_request_started_completion_delay_enter,
806 #endif /* !defined(DISABLE_ATAPI) */