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$");
61 * @brief This file contains the methods and state machines for SATA/STP
65 #include <dev/isci/scil/intel_sat.h>
66 #include <dev/isci/scil/intel_ata.h>
67 #include <dev/isci/scil/intel_sata.h>
68 #include <dev/isci/scil/scic_remote_device.h>
69 #include <dev/isci/scil/scic_user_callback.h>
70 #include <dev/isci/scil/scic_sds_logger.h>
71 #include <dev/isci/scil/scic_sds_controller.h>
72 #include <dev/isci/scil/scic_sds_port.h>
73 #include <dev/isci/scil/scic_sds_remote_device.h>
74 #include <dev/isci/scil/scic_sds_request.h>
75 #include <dev/isci/scil/scu_event_codes.h>
76 #include <dev/isci/scil/scu_completion_codes.h>
77 #include <dev/isci/scil/sci_base_state.h>
80 * This method will perform the STP request completion processing common
81 * to IO requests and task requests of all types
83 * @param[in] device This parameter specifies the device for which the
84 * request is being completed.
85 * @param[in] request This parameter specifies the request being completed.
87 * @return This method returns an indication as to whether the request
88 * processing completed successfully.
91 SCI_STATUS scic_sds_stp_remote_device_complete_request(
92 SCI_BASE_REMOTE_DEVICE_T * device,
93 SCI_BASE_REQUEST_T * request
96 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
97 SCIC_SDS_REQUEST_T * the_request = (SCIC_SDS_REQUEST_T *)request;
100 status = scic_sds_io_request_complete(the_request);
102 if (status == SCI_SUCCESS)
104 status = scic_sds_port_complete_io(
105 this_device->owning_port, this_device, the_request
108 if (status == SCI_SUCCESS)
110 scic_sds_remote_device_decrement_request_count(this_device);
111 if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED)
113 //This request causes hardware error, device needs to be Lun Reset.
114 //So here we force the state machine to IDLE state so the rest IOs
115 //can reach RNC state handler, these IOs will be completed by RNC with
116 //status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
117 sci_base_state_machine_change_state(
118 &this_device->ready_substate_machine,
119 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
122 else if (scic_sds_remote_device_get_request_count(this_device) == 0)
124 sci_base_state_machine_change_state(
125 &this_device->ready_substate_machine,
126 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
132 if (status != SCI_SUCCESS)
135 sci_base_object_get_logger(this_device),
136 SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
137 "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
138 this_device->owning_port, this_device, the_request, status
145 //*****************************************************************************
146 //* STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
147 //*****************************************************************************
150 * This is the READY NCQ substate handler to start task management request. In this
151 * routine, we suspend and resume the RNC.
153 * @param[in] device The target device a task management request towards to.
154 * @param[in] request The task request.
156 * @return SCI_STATUS Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status
157 * to let controller_start_task_handler know that the controller can't post TC for
158 * task request yet, instead, when RNC gets resumed, a controller_continue_task
159 * callback will be called.
162 SCI_STATUS scic_sds_stp_remote_device_ready_substate_start_request_handler(
163 SCI_BASE_REMOTE_DEVICE_T * device,
164 SCI_BASE_REQUEST_T * request
168 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
169 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)request;
171 // Will the port allow the io request to start?
172 status = this_device->owning_port->state_handlers->start_io_handler(
173 this_device->owning_port,
178 if (SCI_SUCCESS == status)
181 scic_sds_remote_node_context_start_task(this_device->rnc, this_request);
183 if (SCI_SUCCESS == status)
185 status = this_request->state_handlers->parent.start_handler(request);
188 if (status == SCI_SUCCESS)
190 /// @note If the remote device state is not IDLE this will replace
191 /// the request that probably resulted in the task management
193 this_device->working_request = this_request;
195 sci_base_state_machine_change_state(
196 &this_device->ready_substate_machine,
197 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
200 //The remote node context must cleanup the TCi to NCQ mapping table.
201 //The only way to do this correctly is to either write to the TLCR
202 //register or to invalidate and repost the RNC. In either case the
203 //remote node context state machine will take the correct action when
204 //the remote node context is suspended and later resumed.
205 scic_sds_remote_node_context_suspend(
206 this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
208 scic_sds_remote_node_context_resume(
210 (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
211 scic_sds_remote_device_continue_request,
215 scic_sds_remote_device_start_request(this_device,this_request,status);
217 //We need to let the controller start request handler know that it can't
218 //post TC yet. We will provide a callback function to post TC when RNC gets
220 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
226 //*****************************************************************************
227 //* STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
228 //*****************************************************************************
231 * This method will handle the start io operation for a sata device that is in
232 * the command idle state.
233 * - Evalute the type of IO request to be started
234 * - If its an NCQ request change to NCQ substate
235 * - If its any other command change to the CMD substate
237 * @note If this is a softreset we may want to have a different substate.
240 * @param [in] request
245 SCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
246 SCI_BASE_REMOTE_DEVICE_T * device,
247 SCI_BASE_REQUEST_T * request
251 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
252 SCIC_SDS_REQUEST_T * io_request = (SCIC_SDS_REQUEST_T *)request;
255 // Will the port allow the io request to start?
256 status = this_device->owning_port->state_handlers->start_io_handler(
257 this_device->owning_port,
262 if (status == SCI_SUCCESS)
265 scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
267 if (status == SCI_SUCCESS)
269 status = io_request->state_handlers->parent.start_handler(request);
272 if (status == SCI_SUCCESS)
274 if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA)
276 sci_base_state_machine_change_state(
277 &this_device->ready_substate_machine,
278 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
283 this_device->working_request = io_request;
285 sci_base_state_machine_change_state(
286 &this_device->ready_substate_machine,
287 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
292 scic_sds_remote_device_start_request(this_device, io_request, status);
300 * This method will handle the event for a sata device that is in
301 * the idle state. We pick up suspension events to handle specifically
302 * to this state. We resume the RNC right away.
304 * @param [in] device The device received event.
305 * @param [in] event_code The event code.
310 SCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_event_handler(
311 SCIC_SDS_REMOTE_DEVICE_T * this_device,
317 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
319 if (status == SCI_SUCCESS)
321 if ((scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
322 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
323 && (this_device->rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY))
325 status = scic_sds_remote_node_context_resume(
326 this_device->rnc, NULL, NULL);
334 //*****************************************************************************
335 //* STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
336 //*****************************************************************************
342 SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
343 SCI_BASE_REMOTE_DEVICE_T * device,
344 SCI_BASE_REQUEST_T * request
348 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
349 SCIC_SDS_REQUEST_T * io_request = (SCIC_SDS_REQUEST_T *)request;
351 if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA)
353 status = this_device->owning_port->state_handlers->start_io_handler(
354 this_device->owning_port,
359 if (status == SCI_SUCCESS)
361 status = scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
363 if (status == SCI_SUCCESS)
365 status = io_request->state_handlers->parent.start_handler(request);
368 scic_sds_remote_device_start_request(this_device, io_request, status);
373 status = SCI_FAILURE_INVALID_STATE;
380 * This method will handle events received while the STP device is in the
381 * ready command substate.
383 * @param [in] this_device This is the device object that is receiving the
385 * @param [in] event_code The event code to process.
390 SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_event_handler(
391 SCIC_SDS_REMOTE_DEVICE_T * this_device,
397 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
399 switch (scu_get_event_code(event_code))
401 case SCU_EVENT_TL_RNC_SUSPEND_TX:
402 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
403 /// @todo We need to decode and understand why the hardware suspended the device.
404 /// The suspension reason was probably due to an SDB error FIS received.
407 case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DATA_LEN_ERR:
408 case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_OFFSET_ERR:
409 case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DMASETUP_DIERR:
410 case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_XFERCNT_ERR:
411 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX_DONE_PLD_LEN_ERR:
412 this_device->not_ready_reason =
413 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
415 sci_base_state_machine_change_state(
416 &this_device->ready_substate_machine,
417 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
420 // We have a notification that the driver requested a suspend operation
421 // this should not happen.
423 sci_base_object_get_logger(this_device),
424 SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
425 "SCIC Remote device 0x%x received driver suspend event %x while in ncq ready substate %d\n",
426 this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
429 // Since we didn't expect to get here start the device again.
430 status = scic_sds_remote_device_resume(this_device);
433 case SCU_EVENT_POST_RCN_RELEASE:
434 /// @todo Do we need to store the suspend state on the device?
436 sci_base_object_get_logger(this_device),
437 SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
438 "SCIC Remote device 0x%x received driver release event %x while in the ready substate %d\n",
439 this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
444 // Some other event just log it and continue
446 sci_base_object_get_logger(this_device),
447 SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
448 "SCIC Remote device 0x%x received driver unexpected event %x while in the ready substate %d\n",
449 this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
452 status = SCI_FAILURE_INVALID_STATE;
462 * @param[in] this_device
463 * @param[in] frame_index
468 SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
469 SCIC_SDS_REMOTE_DEVICE_T * this_device,
474 SATA_FIS_HEADER_T * frame_header;
476 status = scic_sds_unsolicited_frame_control_get_header(
477 &(scic_sds_remote_device_get_controller(this_device)->uf_control),
479 (void **)&frame_header
482 if (status == SCI_SUCCESS)
485 (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS)
486 && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
489 this_device->not_ready_reason =
490 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
492 /** @todo Check sactive and complete associated IO if any. */
494 sci_base_state_machine_change_state(
495 &this_device->ready_substate_machine,
496 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
500 (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
501 && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
504 // Some devices return D2H FIS when an NCQ error is detected.
505 // Treat this like an SDB error FIS ready reason.
506 this_device->not_ready_reason =
507 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
509 sci_base_state_machine_change_state(
510 &this_device->ready_substate_machine,
511 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
516 status = SCI_FAILURE;
519 scic_sds_controller_release_frame(
520 scic_sds_remote_device_get_controller(this_device), frame_index
527 //*****************************************************************************
528 //* STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
529 //*****************************************************************************
532 * This device is already handling a command it can not accept new commands
533 * until this one is complete.
541 SCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
542 SCI_BASE_REMOTE_DEVICE_T * device,
543 SCI_BASE_REQUEST_T * request
546 return SCI_FAILURE_INVALID_STATE;
550 SCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
551 SCIC_SDS_REMOTE_DEVICE_T * this_device,
557 status = scic_sds_remote_node_context_suspend(
558 this_device->rnc, suspend_type, NULL, NULL
567 * @param[in] this_device
568 * @param[in] frame_index
573 SCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
574 SCIC_SDS_REMOTE_DEVICE_T * this_device,
580 /// The device doe not process any UF received from the hardware while
581 /// in this state. All unsolicited frames are forwarded to the io request
583 status = scic_sds_io_request_frame_handler(
584 this_device->working_request,
592 //*****************************************************************************
593 //* STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
594 //*****************************************************************************
597 //*****************************************************************************
598 //* STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
599 //*****************************************************************************
601 SCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
602 SCI_BASE_REMOTE_DEVICE_T * device,
603 SCI_BASE_REQUEST_T * request
606 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
612 * This method will perform the STP request (both io or task) completion
613 * processing for await reset state.
615 * @param[in] device This parameter specifies the device for which the
616 * request is being completed.
617 * @param[in] request This parameter specifies the request being completed.
619 * @return This method returns an indication as to whether the request
620 * processing completed successfully.
623 SCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
624 SCI_BASE_REMOTE_DEVICE_T * device,
625 SCI_BASE_REQUEST_T * request
628 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
629 SCIC_SDS_REQUEST_T * the_request = (SCIC_SDS_REQUEST_T *)request;
632 status = scic_sds_io_request_complete(the_request);
634 if (status == SCI_SUCCESS)
636 status = scic_sds_port_complete_io(
637 this_device->owning_port, this_device, the_request
640 if (status == SCI_SUCCESS)
641 scic_sds_remote_device_decrement_request_count(this_device);
644 if (status != SCI_SUCCESS)
647 sci_base_object_get_logger(this_device),
648 SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
649 "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
650 this_device->owning_port, this_device, the_request, status
657 #if !defined(DISABLE_ATAPI)
658 //*****************************************************************************
659 //* STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
660 //*****************************************************************************
663 * This method will handle the event for a ATAPI device that is in
664 * the ATAPI ERROR state. We pick up suspension events to handle specifically
665 * to this state. We resume the RNC right away. We then complete the outstanding
668 * @param [in] device The device received event.
669 * @param [in] event_code The event code.
674 SCI_STATUS scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
675 SCIC_SDS_REMOTE_DEVICE_T * this_device,
681 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
683 if (status == SCI_SUCCESS)
685 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
686 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
688 status = scic_sds_remote_node_context_resume(
690 (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
691 this_device->working_request->state_handlers->parent.complete_handler,
692 (void *)this_device->working_request
699 #endif // !defined(DISABLE_ATAPI)
701 // ---------------------------------------------------------------------------
703 SCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T
704 scic_sds_stp_remote_device_ready_substate_handler_table[
705 SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
707 // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
710 scic_sds_remote_device_default_start_handler,
711 scic_sds_remote_device_ready_state_stop_handler,
712 scic_sds_remote_device_default_fail_handler,
713 scic_sds_remote_device_default_destruct_handler,
714 scic_sds_remote_device_ready_state_reset_handler,
715 scic_sds_remote_device_default_reset_complete_handler,
716 scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
717 scic_sds_remote_device_default_complete_request_handler,
718 scic_sds_remote_device_default_continue_request_handler,
719 scic_sds_stp_remote_device_ready_substate_start_request_handler,
720 scic_sds_remote_device_default_complete_request_handler
722 scic_sds_remote_device_default_suspend_handler,
723 scic_sds_remote_device_default_resume_handler,
724 scic_sds_stp_remote_device_ready_idle_substate_event_handler,
725 scic_sds_remote_device_default_frame_handler
727 // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
730 scic_sds_remote_device_default_start_handler,
731 scic_sds_remote_device_ready_state_stop_handler,
732 scic_sds_remote_device_default_fail_handler,
733 scic_sds_remote_device_default_destruct_handler,
734 scic_sds_remote_device_ready_state_reset_handler,
735 scic_sds_remote_device_default_reset_complete_handler,
736 scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
737 scic_sds_stp_remote_device_complete_request,
738 scic_sds_remote_device_default_continue_request_handler,
739 scic_sds_stp_remote_device_ready_substate_start_request_handler,
740 scic_sds_stp_remote_device_complete_request,
742 scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
743 scic_sds_remote_device_default_resume_handler,
744 scic_sds_remote_device_general_event_handler,
745 scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
747 // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
750 scic_sds_remote_device_default_start_handler,
751 scic_sds_remote_device_ready_state_stop_handler,
752 scic_sds_remote_device_default_fail_handler,
753 scic_sds_remote_device_default_destruct_handler,
754 scic_sds_remote_device_ready_state_reset_handler,
755 scic_sds_remote_device_default_reset_complete_handler,
756 scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
757 scic_sds_stp_remote_device_complete_request,
758 scic_sds_remote_device_default_continue_request_handler,
759 scic_sds_stp_remote_device_ready_substate_start_request_handler,
760 scic_sds_stp_remote_device_complete_request
762 scic_sds_remote_device_default_suspend_handler,
763 scic_sds_remote_device_default_resume_handler,
764 scic_sds_stp_remote_device_ready_ncq_substate_event_handler,
765 scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
767 // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
770 scic_sds_remote_device_default_start_handler,
771 scic_sds_remote_device_ready_state_stop_handler,
772 scic_sds_remote_device_default_fail_handler,
773 scic_sds_remote_device_default_destruct_handler,
774 scic_sds_remote_device_ready_state_reset_handler,
775 scic_sds_remote_device_default_reset_complete_handler,
776 scic_sds_remote_device_default_start_request_handler,
777 scic_sds_stp_remote_device_complete_request,
778 scic_sds_remote_device_default_continue_request_handler,
779 scic_sds_stp_remote_device_ready_substate_start_request_handler,
780 scic_sds_stp_remote_device_complete_request
782 scic_sds_remote_device_default_suspend_handler,
783 scic_sds_remote_device_default_resume_handler,
784 scic_sds_remote_device_general_event_handler,
785 scic_sds_remote_device_general_frame_handler
787 #if !defined(DISABLE_ATAPI)
788 // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
791 scic_sds_remote_device_default_start_handler,
792 scic_sds_remote_device_ready_state_stop_handler,
793 scic_sds_remote_device_default_fail_handler,
794 scic_sds_remote_device_default_destruct_handler,
795 scic_sds_remote_device_ready_state_reset_handler,
796 scic_sds_remote_device_default_reset_complete_handler,
797 scic_sds_remote_device_default_start_request_handler,
798 scic_sds_stp_remote_device_complete_request,
799 scic_sds_remote_device_default_continue_request_handler,
800 scic_sds_stp_remote_device_ready_substate_start_request_handler,
801 scic_sds_stp_remote_device_complete_request
803 scic_sds_remote_device_default_suspend_handler,
804 scic_sds_remote_device_default_resume_handler,
805 scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler,
806 scic_sds_remote_device_general_frame_handler
809 // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
812 scic_sds_remote_device_default_start_handler,
813 scic_sds_remote_device_ready_state_stop_handler,
814 scic_sds_remote_device_default_fail_handler,
815 scic_sds_remote_device_default_destruct_handler,
816 scic_sds_remote_device_ready_state_reset_handler,
817 scic_sds_remote_device_default_reset_complete_handler,
818 scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
819 scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
820 scic_sds_remote_device_default_continue_request_handler,
821 scic_sds_stp_remote_device_ready_substate_start_request_handler,
822 scic_sds_stp_remote_device_complete_request
824 scic_sds_remote_device_default_suspend_handler,
825 scic_sds_remote_device_default_resume_handler,
826 scic_sds_remote_device_general_event_handler,
827 scic_sds_remote_device_general_frame_handler
831 //*****************************************************************************
832 //* STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
833 //*****************************************************************************
836 void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
840 SCIC_SDS_REMOTE_DEVICE_T * this_device;
841 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_cookie;
843 // For NCQ operation we do not issue a
844 // scic_cb_remote_device_not_ready(). As a result, avoid sending
845 // the ready notification.
846 if (this_device->ready_substate_machine.previous_state_id
847 != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
849 scic_cb_remote_device_ready(
850 scic_sds_remote_device_get_controller(this_device), this_device
855 //*****************************************************************************
856 //* STP REMOTE DEVICE READY IDLE SUBSTATE
857 //*****************************************************************************
861 * @param[in] device This is the SCI base object which is cast into a
862 * SCIC_SDS_REMOTE_DEVICE object.
867 void scic_sds_stp_remote_device_ready_idle_substate_enter(
868 SCI_BASE_OBJECT_T * device
871 SCIC_SDS_REMOTE_DEVICE_T * this_device;
873 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
877 scic_sds_stp_remote_device_ready_substate_handler_table,
878 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
881 this_device->working_request = NULL;
883 if (scic_sds_remote_node_context_is_ready(this_device->rnc))
885 // Since the RNC is ready, it's alright to finish completion
886 // processing (e.g. signal the remote device is ready).
887 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
893 scic_sds_remote_node_context_resume(
895 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
901 //*****************************************************************************
902 //* STP REMOTE DEVICE READY CMD SUBSTATE
903 //*****************************************************************************
908 * @param[in] device This is the SCI base object which is cast into a
909 * SCIC_SDS_REMOTE_DEVICE object.
914 void scic_sds_stp_remote_device_ready_cmd_substate_enter(
915 SCI_BASE_OBJECT_T * device
918 SCIC_SDS_REMOTE_DEVICE_T * this_device;
920 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
922 ASSERT(this_device->working_request != NULL);
926 scic_sds_stp_remote_device_ready_substate_handler_table,
927 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
930 scic_cb_remote_device_not_ready(
931 scic_sds_remote_device_get_controller(this_device),
933 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
937 //*****************************************************************************
938 //* STP REMOTE DEVICE READY NCQ SUBSTATE
939 //*****************************************************************************
944 * @param[in] device This is the SCI base object which is cast into a
945 * SCIC_SDS_REMOTE_DEVICE object.
950 void scic_sds_stp_remote_device_ready_ncq_substate_enter(
951 SCI_BASE_OBJECT_T * device
954 SCIC_SDS_REMOTE_DEVICE_T * this_device;
956 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
960 scic_sds_stp_remote_device_ready_substate_handler_table,
961 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
965 //*****************************************************************************
966 //* STP REMOTE DEVICE READY NCQ ERROR SUBSTATE
967 //*****************************************************************************
972 * @param[in] device This is the SCI base object which is cast into a
973 * SCIC_SDS_REMOTE_DEVICE object.
978 void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
979 SCI_BASE_OBJECT_T * device
982 SCIC_SDS_REMOTE_DEVICE_T * this_device;
984 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
988 scic_sds_stp_remote_device_ready_substate_handler_table,
989 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
992 if(this_device->not_ready_reason ==
993 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
995 scic_cb_remote_device_not_ready(
996 scic_sds_remote_device_get_controller(this_device),
998 this_device->not_ready_reason
1003 //*****************************************************************************
1004 //* STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
1005 //*****************************************************************************
1008 * @brief The enter routine to READY AWAIT RESET substate.
1010 * @param[in] device This is the SCI base object which is cast into a
1011 * SCIC_SDS_REMOTE_DEVICE object.
1016 void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
1017 SCI_BASE_OBJECT_T * device
1020 SCIC_SDS_REMOTE_DEVICE_T * this_device;
1022 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
1026 scic_sds_stp_remote_device_ready_substate_handler_table,
1027 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
1031 #if !defined(DISABLE_ATAPI)
1032 //*****************************************************************************
1033 //* STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
1034 //*****************************************************************************
1037 * @brief The enter routine to READY ATAPI ERROR substate.
1039 * @param[in] device This is the SCI base object which is cast into a
1040 * SCIC_SDS_REMOTE_DEVICE object.
1045 void scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
1046 SCI_BASE_OBJECT_T * device
1049 SCIC_SDS_REMOTE_DEVICE_T * this_device;
1051 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
1055 scic_sds_stp_remote_device_ready_substate_handler_table,
1056 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
1059 #endif // !defined(DISABLE_ATAPI)
1061 // ---------------------------------------------------------------------------
1064 scic_sds_stp_remote_device_ready_substate_table[
1065 SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
1068 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE,
1069 scic_sds_stp_remote_device_ready_idle_substate_enter,
1073 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD,
1074 scic_sds_stp_remote_device_ready_cmd_substate_enter,
1078 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ,
1079 scic_sds_stp_remote_device_ready_ncq_substate_enter,
1083 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
1084 scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
1087 #if !defined(DISABLE_ATAPI)
1089 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR,
1090 scic_sds_stp_remote_device_ready_atapi_error_substate_enter,
1095 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET,
1096 scic_sds_stp_remote_device_ready_await_reset_substate_enter,