2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23 * The full GNU General Public License is included in this distribution
24 * in the file called LICENSE.GPL.
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
35 * * Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * * Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in
39 * the documentation and/or other materials provided with the
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
58 #if !defined(DISABLE_ATAPI)
60 #include <dev/isci/scil/scic_sds_stp_packet_request.h>
61 #include <dev/isci/scil/scic_sds_logger.h>
62 #include <dev/isci/scil/scic_sds_controller.h>
63 #include <dev/isci/scil/scic_sds_remote_device.h>
64 #include <dev/isci/scil/scic_remote_device.h>
65 #include <dev/isci/scil/sci_util.h>
66 #include <dev/isci/scil/intel_sas.h>
67 #include <dev/isci/scil/intel_ata.h>
68 #include <dev/isci/scil/intel_sata.h>
69 #include <dev/isci/scil/scic_user_callback.h>
70 #include <dev/isci/sci_environment.h>
71 #include <dev/isci/scil/intel_sat.h>
72 #include <dev/isci/scil/scic_sds_request.h>
73 #include <dev/isci/scil/scic_controller.h>
74 #include <dev/isci/scil/scu_completion_codes.h>
75 #include <dev/isci/scil/scu_task_context.h>
76 #include <dev/isci/scil/scic_sds_stp_packet_request.h>
77 #include <dev/isci/scil/sci_base_state.h>
80 * @brief This method will fill in the SCU Task Context for a PACKET fis. And
81 * construct the request STARTED sub-state machine for Packet Protocol
84 * @param[in] this_request This parameter specifies the stp packet request object
89 SCI_STATUS scic_sds_stp_packet_request_construct(
90 SCIC_SDS_REQUEST_T *this_request
93 SATA_FIS_REG_H2D_T * h2d_fis =
94 scic_stp_io_request_get_h2d_reg_address(
98 // Work around, we currently only support PACKET DMA protocol, so we
99 // need to make change to Packet Fis features field.
100 h2d_fis->features = h2d_fis->features | ATA_PACKET_FEATURE_DMA;
102 scic_sds_stp_non_ncq_request_construct(this_request);
104 // Build the Packet Fis task context structure
105 scu_stp_raw_request_construct_task_context(
106 (SCIC_SDS_STP_REQUEST_T*) this_request,
107 this_request->task_context_buffer
110 sci_base_state_machine_construct(
111 &this_request->started_substate_machine,
112 &this_request->parent.parent,
113 scic_sds_stp_packet_request_started_substate_table,
114 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
122 * @brief This method will fill in the SCU Task Context for a Packet request
123 * command phase in PACKET DMA DATA (IN/OUT) type. The following
124 * important settings are utilized:
126 * -# task_type == SCU_TASK_TYPE_PACKET_DMA. This simply indicates
127 * that a normal request type (i.e. non-raw frame) is being
128 * utilized to perform task management.
129 * -# control_frame == 1. This ensures that the proper endianness
130 * is set so that the bytes are transmitted in the right order
131 * for a smp request frame.
133 * @param[in] this_request This parameter specifies the smp request object
135 * @param[in] task_context The task_context to be reconstruct for packet
136 * request command phase.
139 void scu_stp_packet_request_command_phase_construct_task_context(
140 SCIC_SDS_REQUEST_T * this_request,
141 SCU_TASK_CONTEXT_T * task_context
145 U32 atapi_cdb_length;
146 SCIC_SDS_STP_REQUEST_T * stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request;
148 // reference: SSTL 1.13.4.2
149 // task_type, sata_direction
150 if ( scic_cb_io_request_get_data_direction(this_request->user_request)
151 == SCI_IO_REQUEST_DATA_OUT )
153 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_OUT;
154 task_context->sata_direction = 0;
156 else // todo: for NO_DATA command, we need to send out raw frame.
158 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_IN;
159 task_context->sata_direction = 1;
163 memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
164 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
166 // Copy in the command IU with CDB so that the commandIU address doesn't
168 memset(this_request->command_buffer, 0, sizeof(SATA_FIS_REG_H2D_T));
171 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
174 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
176 memcpy(((U8 *)this_request->command_buffer+sizeof(U32)), atapi_cdb, atapi_cdb_length);
179 MAX(atapi_cdb_length, stp_request->type.packet.device_preferred_cdb_length);
181 task_context->ssp_command_iu_length =
182 ((atapi_cdb_length % 4) == 0) ?
183 (atapi_cdb_length / 4) : ((atapi_cdb_length / 4) + 1);
185 // task phase is set to TX_CMD
186 task_context->task_phase = 0x1;
189 task_context->stp_retry_count = 0;
191 if (scic_cb_request_is_initial_construction(this_request->user_request))
193 // data transfer size.
194 task_context->transfer_length_bytes =
195 scic_cb_io_request_get_transfer_length(this_request->user_request);
197 // sgls were already built when request was constructed, so don't need to
202 // data transfer size, need to be 4 bytes aligned.
203 task_context->transfer_length_bytes = (SCSI_FIXED_SENSE_DATA_BASE_LENGTH + 2);
205 scic_sds_stp_packet_internal_request_sense_build_sgl(this_request);
210 * @brief This method will fill in the SCU Task Context for a DATA fis
211 * containing CDB in Raw Frame type. The TC for previous Packet
212 * fis was already there, we only need to change the H2D fis content.
214 * @param[in] this_request This parameter specifies the smp request object
216 * @param[in] task_context The task_context to be reconstruct for packet
217 * request command phase.
220 void scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
221 SCIC_SDS_REQUEST_T * this_request,
222 SCU_TASK_CONTEXT_T * task_context
226 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
228 U32 atapi_cdb_length =
229 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
231 memset(this_request->command_buffer, 0, sizeof(SATA_FIS_REG_H2D_T));
232 memcpy( ((U8 *)this_request->command_buffer+sizeof(U32)), atapi_cdb, atapi_cdb_length);
234 memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
235 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
237 //Note the data send out has to be 4 bytes aligned. Or else out hardware will
238 //patch non-zero bytes and cause the target device unhappy.
239 task_context->transfer_length_bytes = 12;
244 *@brief This methods decode the D2H status FIS and retrieve the sense data,
245 * then pass the sense data to user request.
247 *@param[in] this_request The request receive D2H status FIS.
248 *@param[in] status_fis The D2H status fis to be processed.
251 SCI_STATUS scic_sds_stp_packet_request_process_status_fis(
252 SCIC_SDS_REQUEST_T * this_request,
253 SATA_FIS_REG_D2H_T * status_fis
256 SCI_STATUS status = SCI_SUCCESS;
258 //TODO: Process the error status fis, retrieve sense data.
259 if (status_fis->status & ATA_STATUS_REG_ERROR_BIT)
260 status = SCI_FAILURE_IO_RESPONSE_VALID;
266 *@brief This methods builds sgl for internal REQUEST SENSE stp packet
267 * command using this request response buffer, only one sge is
270 *@param[in] this_request The request receive request sense data.
273 void scic_sds_stp_packet_internal_request_sense_build_sgl(
274 SCIC_SDS_REQUEST_T * this_request
278 SCU_SGL_ELEMENT_PAIR_T *scu_sgl_list = NULL;
279 SCU_TASK_CONTEXT_T *task_context;
280 SCI_PHYSICAL_ADDRESS physical_address;
282 SCI_SSP_RESPONSE_IU_T * rsp_iu =
283 (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer;
284 sge = (void*)&rsp_iu->data[0];
286 task_context = (SCU_TASK_CONTEXT_T *)this_request->task_context_buffer;
287 scu_sgl_list = &task_context->sgl_pair_ab;
289 scic_cb_io_request_get_physical_address(
290 scic_sds_request_get_controller(this_request),
296 scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address);
297 scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address);
298 scu_sgl_list->A.length = task_context->transfer_length_bytes;
299 scu_sgl_list->A.address_modifier = 0;
301 SCU_SGL_ZERO(scu_sgl_list->B);
304 //******************************************************************************
305 //* STP PACKET REQUEST STATE MACHINES
306 //******************************************************************************
309 * @brief This method processes the completions transport layer (TL) status
310 * to determine if the Packet FIS was sent successfully. If the Packet
311 * FIS was sent successfully, then the state for the Packet request
312 * transits to waiting for a PIO SETUP frame.
314 * @param[in] this_request This parameter specifies the request for which
315 * the TC completion was received.
316 * @param[in] completion_code This parameter indicates the completion status
317 * information for the TC.
319 * @return Indicate if the tc completion handler was successful.
320 * @retval SCI_SUCCESS currently this method always returns success.
323 SCI_STATUS scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(
324 SCIC_SDS_REQUEST_T * this_request,
328 SCI_STATUS status = SCI_SUCCESS;
331 sci_base_object_get_logger(this_request),
332 SCIC_LOG_OBJECT_STP_IO_REQUEST,
333 "scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
334 this_request, completion_code
337 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
339 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
340 scic_sds_request_set_status(
341 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
344 sci_base_state_machine_change_state(
345 &this_request->started_substate_machine,
346 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
351 // All other completion status cause the IO to be complete. If a NAK
352 // was received, then it is up to the user to retry the request.
353 scic_sds_request_set_status(
355 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
356 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
359 sci_base_state_machine_change_state(
360 &this_request->parent.state_machine,
361 SCI_BASE_REQUEST_STATE_COMPLETED
371 * @brief This method processes an unsolicited frame while the Packet request
372 * is waiting for a PIO SETUP FIS. It will release
373 * the unsolicited frame, and transition the request to the
374 * COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE state.
376 * @param[in] this_request This parameter specifies the request for which
377 * the unsolicited frame was received.
378 * @param[in] frame_index This parameter indicates the unsolicited frame
379 * index that should contain the response.
381 * @return This method returns an indication of whether the pio setup
382 * frame was handled successfully or not.
383 * @retval SCI_SUCCESS Currently this value is always returned and indicates
384 * successful processing of the TC response.
388 SCI_STATUS scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(
389 SCIC_SDS_REQUEST_T * request,
394 SATA_FIS_HEADER_T * frame_header;
396 SCIC_SDS_STP_REQUEST_T * this_request;
398 this_request = (SCIC_SDS_STP_REQUEST_T *)request;
401 sci_base_object_get_logger(this_request),
402 SCIC_LOG_OBJECT_STP_IO_REQUEST,
403 "scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(0x%x, 0x%x) enter\n",
404 this_request, frame_index
407 status = scic_sds_unsolicited_frame_control_get_header(
408 &(this_request->parent.owning_controller->uf_control),
410 (void**) &frame_header
413 if (status == SCI_SUCCESS)
415 ASSERT(frame_header->fis_type == SATA_FIS_TYPE_PIO_SETUP);
417 // Get from the frame buffer the PIO Setup Data, although we don't need
418 // any info from this pio setup fis.
419 scic_sds_unsolicited_frame_control_get_buffer(
420 &(this_request->parent.owning_controller->uf_control),
422 (void**) &frame_buffer
425 // Get the data from the PIO Setup
426 // The SCU Hardware returns first word in the frame_header and the rest
427 // of the data is in the frame buffer so we need to back up one dword
428 this_request->type.packet.device_preferred_cdb_length =
429 (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count;
431 // Frame has been decoded return it to the controller
432 scic_sds_controller_release_frame(
433 this_request->parent.owning_controller, frame_index
436 sci_base_state_machine_change_state(
437 &this_request->parent.started_substate_machine,
438 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
444 sci_base_object_get_logger(this_request),
445 SCIC_LOG_OBJECT_STP_IO_REQUEST,
446 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
447 this_request, frame_index, status
456 * @brief This method processes the completions transport layer (TL) status
457 * to determine if the PACKET command data FIS was sent successfully.
458 * If successfully, then the state for the packet request
459 * transits to COMPLETE state. If not successfully, the request transits
460 * to COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE.
462 * @param[in] this_request This parameter specifies the request for which
463 * the TC completion was received.
464 * @param[in] completion_code This parameter indicates the completion status
465 * information for the TC.
467 * @return Indicate if the tc completion handler was successful.
468 * @retval SCI_SUCCESS currently this method always returns success.
471 SCI_STATUS scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(
472 SCIC_SDS_REQUEST_T * this_request,
476 SCI_STATUS status = SCI_SUCCESS;
477 U8 sat_packet_protocol = this_request->sat_protocol;
480 sci_base_object_get_logger(this_request),
481 SCIC_LOG_OBJECT_STP_IO_REQUEST,
482 "scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
483 this_request, completion_code
486 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
488 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
489 scic_sds_request_set_status(
490 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
493 if ( sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_IN
494 || sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_OUT
496 sci_base_state_machine_change_state(
497 &this_request->parent.state_machine,
498 SCI_BASE_REQUEST_STATE_COMPLETED
501 sci_base_state_machine_change_state(
502 &this_request->started_substate_machine,
503 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
507 case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT):
508 if (scic_io_request_get_number_of_bytes_transferred(this_request) <
509 scic_cb_io_request_get_transfer_length(this_request->user_request))
511 scic_sds_request_set_status(
512 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
515 sci_base_state_machine_change_state(
516 &this_request->started_substate_machine,
517 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
520 //change the device state to ATAPI_ERROR.
521 sci_base_state_machine_change_state(
522 &this_request->target_device->ready_substate_machine,
523 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
526 status = this_request->sci_status;
530 case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT):
531 //In this case, there is no UF coming after. compelte the IO now.
532 scic_sds_request_set_status(
533 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
536 sci_base_state_machine_change_state(
537 &this_request->parent.state_machine,
538 SCI_BASE_REQUEST_STATE_COMPLETED
544 if (this_request->sci_status != SCI_SUCCESS)
545 { //The io status was set already. This means an UF for the status
546 //fis was received already.
548 //A device suspension event is expected, we need to have the device
549 //coming out of suspension, then complete the IO.
550 sci_base_state_machine_change_state(
551 &this_request->started_substate_machine,
552 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
555 //change the device state to ATAPI_ERROR.
556 sci_base_state_machine_change_state(
557 &this_request->target_device->ready_substate_machine,
558 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
561 status = this_request->sci_status;
564 { //If receiving any non-sucess TC status, no UF received yet, then an UF for
565 //the status fis is coming after.
566 scic_sds_request_set_status(
568 SCU_TASK_DONE_CHECK_RESPONSE,
569 SCI_FAILURE_IO_RESPONSE_VALID
572 sci_base_state_machine_change_state(
573 &this_request->started_substate_machine,
574 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
585 * @brief This method processes an unsolicited frame.
587 * @param[in] this_request This parameter specifies the request for which
588 * the unsolicited frame was received.
589 * @param[in] frame_index This parameter indicates the unsolicited frame
590 * index that should contain the response.
592 * @return This method returns an indication of whether the UF
593 * frame was handled successfully or not.
594 * @retval SCI_SUCCESS Currently this value is always returned and indicates
595 * successful processing of the TC response.
599 SCI_STATUS scic_sds_stp_packet_request_command_phase_common_frame_handler(
600 SCIC_SDS_REQUEST_T * request,
605 SATA_FIS_HEADER_T * frame_header;
607 SCIC_SDS_STP_REQUEST_T * this_request;
609 this_request = (SCIC_SDS_STP_REQUEST_T *)request;
612 sci_base_object_get_logger(this_request),
613 SCIC_LOG_OBJECT_STP_IO_REQUEST,
614 "scic_sds_stp_packet_request_command_phase_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
615 this_request, frame_index
618 status = scic_sds_unsolicited_frame_control_get_header(
619 &(this_request->parent.owning_controller->uf_control),
621 (void**) &frame_header
624 if (status == SCI_SUCCESS)
626 ASSERT(frame_header->fis_type == SATA_FIS_TYPE_REGD2H);
628 // Get from the frame buffer the PIO Setup Data, although we don't need
629 // any info from this pio setup fis.
630 scic_sds_unsolicited_frame_control_get_buffer(
631 &(this_request->parent.owning_controller->uf_control),
633 (void**) &frame_buffer
636 scic_sds_controller_copy_sata_response(
637 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
640 // Frame has been decoded return it to the controller
641 scic_sds_controller_release_frame(
642 this_request->parent.owning_controller, frame_index
650 * @brief This method processes an unsolicited frame while the packet request is
651 * expecting TC completion. It will process the FIS and construct sense
654 * @param[in] this_request This parameter specifies the request for which
655 * the unsolicited frame was received.
656 * @param[in] frame_index This parameter indicates the unsolicited frame
657 * index that should contain the response.
659 * @return This method returns an indication of whether the UF
660 * frame was handled successfully or not.
661 * @retval SCI_SUCCESS Currently this value is always returned and indicates
662 * successful processing of the TC response.
666 SCI_STATUS scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler(
667 SCIC_SDS_REQUEST_T * request,
671 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
674 scic_sds_stp_packet_request_command_phase_common_frame_handler(
675 request, frame_index);
677 if (status == SCI_SUCCESS)
679 // The command has completed with error status from target device.
680 status = scic_sds_stp_packet_request_process_status_fis(
681 request, &this_request->d2h_reg_fis);
683 if (status != SCI_SUCCESS)
685 scic_sds_request_set_status(
686 &this_request->parent,
687 SCU_TASK_DONE_CHECK_RESPONSE,
692 scic_sds_request_set_status(
693 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
702 * @brief This method processes an unsolicited frame while the packet request is
703 * expecting TC completion. It will process the FIS and construct sense
706 * @param[in] this_request This parameter specifies the request for which
707 * the unsolicited frame was received.
708 * @param[in] frame_index This parameter indicates the unsolicited frame
709 * index that should contain the response.
711 * @return This method returns an indication of whether the UF
712 * frame was handled successfully or not.
713 * @retval SCI_SUCCESS Currently this value is always returned and indicates
714 * successful processing of the TC response.
718 SCI_STATUS scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler(
719 SCIC_SDS_REQUEST_T * request,
724 scic_sds_stp_packet_request_command_phase_common_frame_handler(
725 request, frame_index);
727 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
729 if (status == SCI_SUCCESS)
731 // The command has completed with error status from target device.
732 status = scic_sds_stp_packet_request_process_status_fis(
733 request, &this_request->d2h_reg_fis);
735 if (status != SCI_SUCCESS)
737 scic_sds_request_set_status(
739 SCU_TASK_DONE_CHECK_RESPONSE,
744 scic_sds_request_set_status(
745 request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
748 //Always complete the NON_DATA command right away, no need to delay completion
749 //even an error status fis came from target device.
750 sci_base_state_machine_change_state(
751 &request->parent.state_machine,
752 SCI_BASE_REQUEST_STATE_COMPLETED
760 SCI_STATUS scic_sds_stp_packet_request_started_completion_delay_complete_handler(
761 SCI_BASE_REQUEST_T *request
764 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)request;
766 sci_base_state_machine_change_state(
767 &this_request->parent.state_machine,
768 SCI_BASE_REQUEST_STATE_COMPLETED
771 return this_request->sci_status;
774 // ---------------------------------------------------------------------------
776 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
777 scic_sds_stp_packet_request_started_substate_handler_table
778 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_MAX_SUBSTATES] =
780 // SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
783 scic_sds_request_default_start_handler,
784 scic_sds_request_started_state_abort_handler,
785 scic_sds_request_default_complete_handler,
786 scic_sds_request_default_destruct_handler
788 scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler,
789 scic_sds_request_default_event_handler,
790 scic_sds_request_default_frame_handler
792 // SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
795 scic_sds_request_default_start_handler,
796 scic_sds_request_started_state_abort_handler,
797 scic_sds_request_default_complete_handler,
798 scic_sds_request_default_destruct_handler
800 scic_sds_request_default_tc_completion_handler,
801 scic_sds_request_default_event_handler,
802 scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler
804 // SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
807 scic_sds_request_default_start_handler,
808 scic_sds_request_started_state_abort_handler,
809 scic_sds_request_default_complete_handler,
810 scic_sds_request_default_destruct_handler
812 scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler,
813 scic_sds_request_default_event_handler,
814 scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler
816 // SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
819 scic_sds_request_default_start_handler,
820 scic_sds_request_started_state_abort_handler,
821 scic_sds_request_default_complete_handler,
822 scic_sds_request_default_destruct_handler
824 scic_sds_request_default_tc_completion_handler,
825 scic_sds_request_default_event_handler,
826 scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler
828 // SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
831 scic_sds_request_default_start_handler,
832 scic_sds_request_started_state_abort_handler,
833 scic_sds_stp_packet_request_started_completion_delay_complete_handler,
834 scic_sds_request_default_destruct_handler
836 scic_sds_request_default_tc_completion_handler,
837 scic_sds_request_default_event_handler,
838 scic_sds_request_default_frame_handler
845 * @brief This file contains the Packet IO started substate machine
846 * for the SCIC_SDS_IO_REQUEST object.
849 void scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter(
850 SCI_BASE_OBJECT_T *object
853 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
857 scic_sds_stp_packet_request_started_substate_handler_table,
858 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
861 scic_sds_remote_device_set_working_request(
862 this_request->target_device, this_request
867 void scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter(
868 SCI_BASE_OBJECT_T *object
871 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
875 scic_sds_stp_packet_request_started_substate_handler_table,
876 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
881 void scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter(
882 SCI_BASE_OBJECT_T *object
885 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
886 U8 sat_packet_protocol = this_request->sat_protocol;
888 SCU_TASK_CONTEXT_T *task_context;
891 // Recycle the TC and reconstruct it for sending out data fis containing
893 task_context = scic_sds_controller_get_task_context_buffer(
894 this_request->owning_controller, this_request->io_tag);
896 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_NON_DATA)
897 scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
898 this_request, task_context);
900 scu_stp_packet_request_command_phase_construct_task_context(
901 this_request, task_context);
903 // send the new TC out.
904 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
905 &this_request->owning_controller->parent,
906 &this_request->target_device->parent,
907 &this_request->parent
910 if (status == SCI_SUCCESS)
913 scic_sds_stp_packet_request_started_substate_handler_table,
914 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
919 void scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter(
920 SCI_BASE_OBJECT_T *object
923 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
927 scic_sds_stp_packet_request_started_substate_handler_table,
928 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
933 void scic_sds_stp_packet_request_started_completion_delay_enter(
934 SCI_BASE_OBJECT_T *object
937 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
941 scic_sds_stp_packet_request_started_substate_handler_table,
942 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
947 // ---------------------------------------------------------------------------
949 scic_sds_stp_packet_request_started_substate_table
950 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_MAX_SUBSTATES] =
953 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE,
954 scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter,
958 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE,
959 scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter,
963 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE,
964 scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter,
968 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE,
969 scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter,
973 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE,
974 scic_sds_stp_packet_request_started_completion_delay_enter,
979 #endif //#if !defined(DISABLE_ATAPI)