1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * 59230557Sjimharris * @brief This file contains the methods and state machines for SATA/STP 60230557Sjimharris * remote devices. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/intel_sat.h> 64230557Sjimharris#include <dev/isci/scil/intel_ata.h> 65230557Sjimharris#include <dev/isci/scil/intel_sata.h> 66230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 67230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 68230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 69230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 70230557Sjimharris#include <dev/isci/scil/scic_sds_port.h> 71230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 72230557Sjimharris#include <dev/isci/scil/scic_sds_request.h> 73230557Sjimharris#include <dev/isci/scil/scu_event_codes.h> 74230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h> 75230557Sjimharris#include <dev/isci/scil/sci_base_state.h> 76230557Sjimharris 77230557Sjimharris/** 78230557Sjimharris * This method will perform the STP request completion processing common 79230557Sjimharris * to IO requests and task requests of all types 80230557Sjimharris * 81230557Sjimharris * @param[in] device This parameter specifies the device for which the 82230557Sjimharris * request is being completed. 83230557Sjimharris * @param[in] request This parameter specifies the request being completed. 84230557Sjimharris * 85230557Sjimharris * @return This method returns an indication as to whether the request 86230557Sjimharris * processing completed successfully. 87230557Sjimharris */ 88230557Sjimharrisstatic 89230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_complete_request( 90230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 91230557Sjimharris SCI_BASE_REQUEST_T * request 92230557Sjimharris) 93230557Sjimharris{ 94230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 95230557Sjimharris SCIC_SDS_REQUEST_T * the_request = (SCIC_SDS_REQUEST_T *)request; 96230557Sjimharris SCI_STATUS status; 97230557Sjimharris 98230557Sjimharris status = scic_sds_io_request_complete(the_request); 99230557Sjimharris 100230557Sjimharris if (status == SCI_SUCCESS) 101230557Sjimharris { 102230557Sjimharris status = scic_sds_port_complete_io( 103230557Sjimharris this_device->owning_port, this_device, the_request 104230557Sjimharris ); 105230557Sjimharris 106230557Sjimharris if (status == SCI_SUCCESS) 107230557Sjimharris { 108230557Sjimharris scic_sds_remote_device_decrement_request_count(this_device); 109230557Sjimharris if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) 110230557Sjimharris { 111230557Sjimharris //This request causes hardware error, device needs to be Lun Reset. 112230557Sjimharris //So here we force the state machine to IDLE state so the rest IOs 113230557Sjimharris //can reach RNC state handler, these IOs will be completed by RNC with 114230557Sjimharris //status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". 115230557Sjimharris sci_base_state_machine_change_state( 116230557Sjimharris &this_device->ready_substate_machine, 117230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET 118230557Sjimharris ); 119230557Sjimharris } 120230557Sjimharris else if (scic_sds_remote_device_get_request_count(this_device) == 0) 121230557Sjimharris { 122230557Sjimharris sci_base_state_machine_change_state( 123230557Sjimharris &this_device->ready_substate_machine, 124230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 125230557Sjimharris ); 126230557Sjimharris } 127230557Sjimharris } 128230557Sjimharris } 129230557Sjimharris 130230557Sjimharris if (status != SCI_SUCCESS) 131230557Sjimharris { 132230557Sjimharris SCIC_LOG_ERROR(( 133230557Sjimharris sci_base_object_get_logger(this_device), 134230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 135230557Sjimharris "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n", 136230557Sjimharris this_device->owning_port, this_device, the_request, status 137230557Sjimharris )); 138230557Sjimharris } 139230557Sjimharris 140230557Sjimharris return status; 141230557Sjimharris} 142230557Sjimharris 143230557Sjimharris//***************************************************************************** 144230557Sjimharris//* STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS 145230557Sjimharris//***************************************************************************** 146230557Sjimharris 147230557Sjimharris/** 148230557Sjimharris * This is the READY NCQ substate handler to start task management request. In this 149230557Sjimharris * routine, we suspend and resume the RNC. 150230557Sjimharris * 151230557Sjimharris * @param[in] device The target device a task management request towards to. 152230557Sjimharris * @param[in] request The task request. 153230557Sjimharris * 154230557Sjimharris * @return SCI_STATUS Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status 155230557Sjimharris * to let controller_start_task_handler know that the controller can't post TC for 156230557Sjimharris * task request yet, instead, when RNC gets resumed, a controller_continue_task 157230557Sjimharris * callback will be called. 158230557Sjimharris */ 159230557Sjimharrisstatic 160230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_substate_start_request_handler( 161230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 162230557Sjimharris SCI_BASE_REQUEST_T * request 163230557Sjimharris) 164230557Sjimharris{ 165230557Sjimharris SCI_STATUS status; 166230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 167230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)request; 168230557Sjimharris 169230557Sjimharris // Will the port allow the io request to start? 170230557Sjimharris status = this_device->owning_port->state_handlers->start_io_handler( 171230557Sjimharris this_device->owning_port, 172230557Sjimharris this_device, 173230557Sjimharris this_request 174230557Sjimharris ); 175230557Sjimharris 176230557Sjimharris if (SCI_SUCCESS == status) 177230557Sjimharris { 178230557Sjimharris status = 179230557Sjimharris scic_sds_remote_node_context_start_task(this_device->rnc, this_request); 180230557Sjimharris 181230557Sjimharris if (SCI_SUCCESS == status) 182230557Sjimharris { 183230557Sjimharris status = this_request->state_handlers->parent.start_handler(request); 184230557Sjimharris } 185230557Sjimharris 186230557Sjimharris if (status == SCI_SUCCESS) 187230557Sjimharris { 188230557Sjimharris /// @note If the remote device state is not IDLE this will replace 189230557Sjimharris /// the request that probably resulted in the task management 190230557Sjimharris /// request. 191230557Sjimharris this_device->working_request = this_request; 192230557Sjimharris 193230557Sjimharris sci_base_state_machine_change_state( 194230557Sjimharris &this_device->ready_substate_machine, 195230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD 196230557Sjimharris ); 197230557Sjimharris 198230557Sjimharris //The remote node context must cleanup the TCi to NCQ mapping table. 199230557Sjimharris //The only way to do this correctly is to either write to the TLCR 200230557Sjimharris //register or to invalidate and repost the RNC. In either case the 201230557Sjimharris //remote node context state machine will take the correct action when 202230557Sjimharris //the remote node context is suspended and later resumed. 203230557Sjimharris scic_sds_remote_node_context_suspend( 204230557Sjimharris this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL); 205230557Sjimharris 206230557Sjimharris scic_sds_remote_node_context_resume( 207230557Sjimharris this_device->rnc, 208230557Sjimharris (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK) 209230557Sjimharris scic_sds_remote_device_continue_request, 210230557Sjimharris this_device); 211230557Sjimharris } 212230557Sjimharris 213230557Sjimharris scic_sds_remote_device_start_request(this_device,this_request,status); 214230557Sjimharris 215230557Sjimharris //We need to let the controller start request handler know that it can't 216230557Sjimharris //post TC yet. We will provide a callback function to post TC when RNC gets 217230557Sjimharris //resumed. 218230557Sjimharris return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS; 219230557Sjimharris } 220230557Sjimharris 221230557Sjimharris return status; 222230557Sjimharris} 223230557Sjimharris 224230557Sjimharris//***************************************************************************** 225230557Sjimharris//* STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS 226230557Sjimharris//***************************************************************************** 227230557Sjimharris 228230557Sjimharris/** 229230557Sjimharris * This method will handle the start io operation for a sata device that is in 230230557Sjimharris * the command idle state. 231230557Sjimharris * - Evalute the type of IO request to be started 232230557Sjimharris * - If its an NCQ request change to NCQ substate 233230557Sjimharris * - If its any other command change to the CMD substate 234230557Sjimharris * 235230557Sjimharris * @note If this is a softreset we may want to have a different substate. 236230557Sjimharris * 237230557Sjimharris * @param [in] device 238230557Sjimharris * @param [in] request 239230557Sjimharris * 240230557Sjimharris * @return SCI_STATUS 241230557Sjimharris */ 242230557Sjimharrisstatic 243230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_start_io_handler( 244230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 245230557Sjimharris SCI_BASE_REQUEST_T * request 246230557Sjimharris) 247230557Sjimharris{ 248230557Sjimharris SCI_STATUS status; 249230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 250230557Sjimharris SCIC_SDS_REQUEST_T * io_request = (SCIC_SDS_REQUEST_T *)request; 251230557Sjimharris 252230557Sjimharris 253230557Sjimharris // Will the port allow the io request to start? 254230557Sjimharris status = this_device->owning_port->state_handlers->start_io_handler( 255230557Sjimharris this_device->owning_port, 256230557Sjimharris this_device, 257230557Sjimharris io_request 258230557Sjimharris ); 259230557Sjimharris 260230557Sjimharris if (status == SCI_SUCCESS) 261230557Sjimharris { 262230557Sjimharris status = 263230557Sjimharris scic_sds_remote_node_context_start_io(this_device->rnc, io_request); 264230557Sjimharris 265230557Sjimharris if (status == SCI_SUCCESS) 266230557Sjimharris { 267230557Sjimharris status = io_request->state_handlers->parent.start_handler(request); 268230557Sjimharris } 269230557Sjimharris 270230557Sjimharris if (status == SCI_SUCCESS) 271230557Sjimharris { 272230557Sjimharris if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA) 273230557Sjimharris { 274230557Sjimharris sci_base_state_machine_change_state( 275230557Sjimharris &this_device->ready_substate_machine, 276230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ 277230557Sjimharris ); 278230557Sjimharris } 279230557Sjimharris else 280230557Sjimharris { 281230557Sjimharris this_device->working_request = io_request; 282230557Sjimharris 283230557Sjimharris sci_base_state_machine_change_state( 284230557Sjimharris &this_device->ready_substate_machine, 285230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD 286230557Sjimharris ); 287230557Sjimharris } 288230557Sjimharris } 289230557Sjimharris 290230557Sjimharris scic_sds_remote_device_start_request(this_device, io_request, status); 291230557Sjimharris } 292230557Sjimharris 293230557Sjimharris return status; 294230557Sjimharris} 295230557Sjimharris 296230557Sjimharris 297230557Sjimharris/** 298230557Sjimharris * This method will handle the event for a sata device that is in 299230557Sjimharris * the idle state. We pick up suspension events to handle specifically 300230557Sjimharris * to this state. We resume the RNC right away. 301230557Sjimharris * 302230557Sjimharris * @param [in] device The device received event. 303230557Sjimharris * @param [in] event_code The event code. 304230557Sjimharris * 305230557Sjimharris * @return SCI_STATUS 306230557Sjimharris */ 307230557Sjimharrisstatic 308230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_event_handler( 309230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 310230557Sjimharris U32 event_code 311230557Sjimharris) 312230557Sjimharris{ 313230557Sjimharris SCI_STATUS status; 314230557Sjimharris 315230557Sjimharris status = scic_sds_remote_device_general_event_handler(this_device, event_code); 316230557Sjimharris 317230557Sjimharris if (status == SCI_SUCCESS) 318230557Sjimharris { 319230557Sjimharris if ((scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX 320230557Sjimharris || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) 321230557Sjimharris && (this_device->rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)) 322230557Sjimharris { 323230557Sjimharris status = scic_sds_remote_node_context_resume( 324230557Sjimharris this_device->rnc, NULL, NULL); 325230557Sjimharris } 326230557Sjimharris } 327230557Sjimharris 328230557Sjimharris return status; 329230557Sjimharris} 330230557Sjimharris 331230557Sjimharris 332230557Sjimharris//***************************************************************************** 333230557Sjimharris//* STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS 334230557Sjimharris//***************************************************************************** 335230557Sjimharris 336230557Sjimharris/** 337230557Sjimharris * 338230557Sjimharris */ 339230557Sjimharrisstatic 340230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler( 341230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 342230557Sjimharris SCI_BASE_REQUEST_T * request 343230557Sjimharris) 344230557Sjimharris{ 345230557Sjimharris SCI_STATUS status; 346230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 347230557Sjimharris SCIC_SDS_REQUEST_T * io_request = (SCIC_SDS_REQUEST_T *)request; 348230557Sjimharris 349230557Sjimharris if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA) 350230557Sjimharris { 351230557Sjimharris status = this_device->owning_port->state_handlers->start_io_handler( 352230557Sjimharris this_device->owning_port, 353230557Sjimharris this_device, 354230557Sjimharris io_request 355230557Sjimharris ); 356230557Sjimharris 357230557Sjimharris if (status == SCI_SUCCESS) 358230557Sjimharris { 359230557Sjimharris status = scic_sds_remote_node_context_start_io(this_device->rnc, io_request); 360230557Sjimharris 361230557Sjimharris if (status == SCI_SUCCESS) 362230557Sjimharris { 363230557Sjimharris status = io_request->state_handlers->parent.start_handler(request); 364230557Sjimharris } 365230557Sjimharris 366230557Sjimharris scic_sds_remote_device_start_request(this_device, io_request, status); 367230557Sjimharris } 368230557Sjimharris } 369230557Sjimharris else 370230557Sjimharris { 371230557Sjimharris status = SCI_FAILURE_INVALID_STATE; 372230557Sjimharris } 373230557Sjimharris 374230557Sjimharris return status; 375230557Sjimharris} 376230557Sjimharris 377230557Sjimharris/** 378230557Sjimharris * This method will handle events received while the STP device is in the 379230557Sjimharris * ready command substate. 380230557Sjimharris * 381230557Sjimharris * @param [in] this_device This is the device object that is receiving the 382230557Sjimharris * event. 383230557Sjimharris * @param [in] event_code The event code to process. 384230557Sjimharris * 385230557Sjimharris * @return SCI_STATUS 386230557Sjimharris */ 387230557Sjimharrisstatic 388230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_event_handler( 389230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 390230557Sjimharris U32 event_code 391230557Sjimharris) 392230557Sjimharris{ 393230557Sjimharris SCI_STATUS status; 394230557Sjimharris 395230557Sjimharris status = scic_sds_remote_device_general_event_handler(this_device, event_code); 396230557Sjimharris 397230557Sjimharris switch (scu_get_event_code(event_code)) 398230557Sjimharris { 399230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX: 400230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: 401230557Sjimharris /// @todo We need to decode and understand why the hardware suspended the device. 402230557Sjimharris /// The suspension reason was probably due to an SDB error FIS received. 403230557Sjimharris break; 404230557Sjimharris 405230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DATA_LEN_ERR: 406230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_OFFSET_ERR: 407230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DMASETUP_DIERR: 408230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_XFERCNT_ERR: 409230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_RX_DONE_PLD_LEN_ERR: 410230557Sjimharris this_device->not_ready_reason = 411230557Sjimharris SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; 412230557Sjimharris 413230557Sjimharris sci_base_state_machine_change_state( 414230557Sjimharris &this_device->ready_substate_machine, 415230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 416230557Sjimharris ); 417230557Sjimharris 418230557Sjimharris // We have a notification that the driver requested a suspend operation 419230557Sjimharris // this should not happen. 420230557Sjimharris SCIC_LOG_WARNING(( 421230557Sjimharris sci_base_object_get_logger(this_device), 422230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 423230557Sjimharris "SCIC Remote device 0x%x received driver suspend event %x while in ncq ready substate %d\n", 424230557Sjimharris this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine) 425230557Sjimharris )); 426230557Sjimharris 427230557Sjimharris // Since we didnt expect to get here start the device again. 428230557Sjimharris status = scic_sds_remote_device_resume(this_device); 429230557Sjimharris break; 430230557Sjimharris 431230557Sjimharris case SCU_EVENT_POST_RCN_RELEASE: 432230557Sjimharris /// @todo Do we need to store the suspend state on the device? 433230557Sjimharris SCIC_LOG_INFO(( 434230557Sjimharris sci_base_object_get_logger(this_device), 435230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 436230557Sjimharris "SCIC Remote device 0x%x received driver release event %x while in the ready substate %d\n", 437230557Sjimharris this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine) 438230557Sjimharris )); 439230557Sjimharris break; 440230557Sjimharris 441230557Sjimharris default: 442230557Sjimharris // Some other event just log it and continue 443230557Sjimharris SCIC_LOG_WARNING(( 444230557Sjimharris sci_base_object_get_logger(this_device), 445230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 446230557Sjimharris "SCIC Remote device 0x%x received driver unexpected event %x while in the ready substate %d\n", 447230557Sjimharris this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine) 448230557Sjimharris )); 449230557Sjimharris 450230557Sjimharris status = SCI_FAILURE_INVALID_STATE; 451230557Sjimharris break; 452230557Sjimharris } 453230557Sjimharris 454230557Sjimharris return status; 455230557Sjimharris} 456230557Sjimharris 457230557Sjimharris/** 458230557Sjimharris * 459230557Sjimharris * 460230557Sjimharris * @param[in] this_device 461230557Sjimharris * @param[in] frame_index 462230557Sjimharris * 463230557Sjimharris * @return SCI_STATUS 464230557Sjimharris */ 465230557Sjimharrisstatic 466230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_frame_handler( 467230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 468230557Sjimharris U32 frame_index 469230557Sjimharris) 470230557Sjimharris{ 471230557Sjimharris SCI_STATUS status; 472230557Sjimharris SATA_FIS_HEADER_T * frame_header; 473230557Sjimharris 474230557Sjimharris status = scic_sds_unsolicited_frame_control_get_header( 475230557Sjimharris &(scic_sds_remote_device_get_controller(this_device)->uf_control), 476230557Sjimharris frame_index, 477230557Sjimharris (void **)&frame_header 478230557Sjimharris ); 479230557Sjimharris 480230557Sjimharris if (status == SCI_SUCCESS) 481230557Sjimharris { 482230557Sjimharris if ( 483230557Sjimharris (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS) 484230557Sjimharris && (frame_header->status & ATA_STATUS_REG_ERROR_BIT) 485230557Sjimharris ) 486230557Sjimharris { 487230557Sjimharris this_device->not_ready_reason = 488230557Sjimharris SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; 489230557Sjimharris 490230557Sjimharris /** @todo Check sactive and complete associated IO if any. */ 491230557Sjimharris 492230557Sjimharris sci_base_state_machine_change_state( 493230557Sjimharris &this_device->ready_substate_machine, 494230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 495230557Sjimharris ); 496230557Sjimharris } 497230557Sjimharris else if ( 498230557Sjimharris (frame_header->fis_type == SATA_FIS_TYPE_REGD2H) 499230557Sjimharris && (frame_header->status & ATA_STATUS_REG_ERROR_BIT) 500230557Sjimharris ) 501230557Sjimharris { 502230557Sjimharris // Some devices return D2H FIS when an NCQ error is detected. 503230557Sjimharris // Treat this like an SDB error FIS ready reason. 504230557Sjimharris this_device->not_ready_reason = 505230557Sjimharris SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; 506230557Sjimharris 507230557Sjimharris sci_base_state_machine_change_state( 508230557Sjimharris &this_device->ready_substate_machine, 509230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 510230557Sjimharris ); 511230557Sjimharris } 512230557Sjimharris else 513230557Sjimharris { 514230557Sjimharris status = SCI_FAILURE; 515230557Sjimharris } 516230557Sjimharris 517230557Sjimharris scic_sds_controller_release_frame( 518230557Sjimharris scic_sds_remote_device_get_controller(this_device), frame_index 519230557Sjimharris ); 520230557Sjimharris } 521230557Sjimharris 522230557Sjimharris return status; 523230557Sjimharris} 524230557Sjimharris 525230557Sjimharris//***************************************************************************** 526230557Sjimharris//* STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS 527230557Sjimharris//***************************************************************************** 528230557Sjimharris 529230557Sjimharris/** 530230557Sjimharris * This device is already handling a command it can not accept new commands 531230557Sjimharris * until this one is complete. 532230557Sjimharris * 533230557Sjimharris * @param[in] device 534230557Sjimharris * @param[in] request 535230557Sjimharris * 536230557Sjimharris * @return SCI_STATUS 537230557Sjimharris */ 538230557Sjimharrisstatic 539230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler( 540230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 541230557Sjimharris SCI_BASE_REQUEST_T * request 542230557Sjimharris) 543230557Sjimharris{ 544230557Sjimharris return SCI_FAILURE_INVALID_STATE; 545230557Sjimharris} 546230557Sjimharris 547230557Sjimharrisstatic 548230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler( 549230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 550230557Sjimharris U32 suspend_type 551230557Sjimharris) 552230557Sjimharris{ 553230557Sjimharris SCI_STATUS status; 554230557Sjimharris 555230557Sjimharris status = scic_sds_remote_node_context_suspend( 556230557Sjimharris this_device->rnc, suspend_type, NULL, NULL 557230557Sjimharris ); 558230557Sjimharris 559230557Sjimharris return status; 560230557Sjimharris} 561230557Sjimharris 562230557Sjimharris/** 563230557Sjimharris * 564230557Sjimharris * 565230557Sjimharris * @param[in] this_device 566230557Sjimharris * @param[in] frame_index 567230557Sjimharris * 568230557Sjimharris * @return SCI_STATUS 569230557Sjimharris */ 570230557Sjimharrisstatic 571230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_frame_handler( 572230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 573230557Sjimharris U32 frame_index 574230557Sjimharris) 575230557Sjimharris{ 576230557Sjimharris SCI_STATUS status; 577230557Sjimharris 578230557Sjimharris /// The device doe not process any UF received from the hardware while 579230557Sjimharris /// in this state. All unsolicited frames are forwarded to the io request 580230557Sjimharris /// object. 581230557Sjimharris status = scic_sds_io_request_frame_handler( 582230557Sjimharris this_device->working_request, 583230557Sjimharris frame_index 584230557Sjimharris ); 585230557Sjimharris 586230557Sjimharris return status; 587230557Sjimharris} 588230557Sjimharris 589230557Sjimharris 590230557Sjimharris//***************************************************************************** 591230557Sjimharris//* STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS 592230557Sjimharris//***************************************************************************** 593230557Sjimharris 594230557Sjimharris 595230557Sjimharris//***************************************************************************** 596230557Sjimharris//* STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS 597230557Sjimharris//***************************************************************************** 598230557Sjimharrisstatic 599230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler( 600230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 601230557Sjimharris SCI_BASE_REQUEST_T * request 602230557Sjimharris) 603230557Sjimharris{ 604230557Sjimharris return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; 605230557Sjimharris} 606230557Sjimharris 607230557Sjimharris 608230557Sjimharris 609230557Sjimharris/** 610230557Sjimharris * This method will perform the STP request (both io or task) completion 611230557Sjimharris * processing for await reset state. 612230557Sjimharris * 613230557Sjimharris * @param[in] device This parameter specifies the device for which the 614230557Sjimharris * request is being completed. 615230557Sjimharris * @param[in] request This parameter specifies the request being completed. 616230557Sjimharris * 617230557Sjimharris * @return This method returns an indication as to whether the request 618230557Sjimharris * processing completed successfully. 619230557Sjimharris */ 620230557Sjimharrisstatic 621230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler( 622230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 623230557Sjimharris SCI_BASE_REQUEST_T * request 624230557Sjimharris) 625230557Sjimharris{ 626230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 627230557Sjimharris SCIC_SDS_REQUEST_T * the_request = (SCIC_SDS_REQUEST_T *)request; 628230557Sjimharris SCI_STATUS status; 629230557Sjimharris 630230557Sjimharris status = scic_sds_io_request_complete(the_request); 631230557Sjimharris 632230557Sjimharris if (status == SCI_SUCCESS) 633230557Sjimharris { 634230557Sjimharris status = scic_sds_port_complete_io( 635230557Sjimharris this_device->owning_port, this_device, the_request 636230557Sjimharris ); 637230557Sjimharris 638230557Sjimharris if (status == SCI_SUCCESS) 639230557Sjimharris scic_sds_remote_device_decrement_request_count(this_device); 640230557Sjimharris } 641230557Sjimharris 642230557Sjimharris if (status != SCI_SUCCESS) 643230557Sjimharris { 644230557Sjimharris SCIC_LOG_ERROR(( 645230557Sjimharris sci_base_object_get_logger(this_device), 646230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 647230557Sjimharris "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n", 648230557Sjimharris this_device->owning_port, this_device, the_request, status 649230557Sjimharris )); 650230557Sjimharris } 651230557Sjimharris 652230557Sjimharris return status; 653230557Sjimharris} 654230557Sjimharris 655230557Sjimharris#if !defined(DISABLE_ATAPI) 656230557Sjimharris//***************************************************************************** 657230557Sjimharris//* STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS 658230557Sjimharris//***************************************************************************** 659230557Sjimharris 660230557Sjimharris/** 661230557Sjimharris * This method will handle the event for a ATAPI device that is in 662230557Sjimharris * the ATAPI ERROR state. We pick up suspension events to handle specifically 663230557Sjimharris * to this state. We resume the RNC right away. We then complete the outstanding 664230557Sjimharris * IO to this device. 665230557Sjimharris * 666230557Sjimharris * @param [in] device The device received event. 667230557Sjimharris * @param [in] event_code The event code. 668230557Sjimharris * 669230557Sjimharris * @return SCI_STATUS 670230557Sjimharris */ 671230557Sjimharrisstatic 672230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler( 673230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 674230557Sjimharris U32 event_code 675230557Sjimharris) 676230557Sjimharris{ 677230557Sjimharris SCI_STATUS status; 678230557Sjimharris 679230557Sjimharris status = scic_sds_remote_device_general_event_handler(this_device, event_code); 680230557Sjimharris 681230557Sjimharris if (status == SCI_SUCCESS) 682230557Sjimharris { 683230557Sjimharris if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX 684230557Sjimharris || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) 685230557Sjimharris { 686230557Sjimharris status = scic_sds_remote_node_context_resume( 687230557Sjimharris this_device->rnc, 688230557Sjimharris (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK) 689230557Sjimharris this_device->working_request->state_handlers->parent.complete_handler, 690230557Sjimharris (void *)this_device->working_request 691230557Sjimharris ); 692230557Sjimharris } 693230557Sjimharris } 694230557Sjimharris 695230557Sjimharris return status; 696230557Sjimharris} 697230557Sjimharris#endif // !defined(DISABLE_ATAPI) 698230557Sjimharris 699230557Sjimharris// --------------------------------------------------------------------------- 700230557Sjimharris 701230557SjimharrisSCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T 702230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table[ 703230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] = 704230557Sjimharris{ 705230557Sjimharris // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 706230557Sjimharris { 707230557Sjimharris { 708230557Sjimharris scic_sds_remote_device_default_start_handler, 709230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 710230557Sjimharris scic_sds_remote_device_default_fail_handler, 711230557Sjimharris scic_sds_remote_device_default_destruct_handler, 712230557Sjimharris scic_sds_remote_device_ready_state_reset_handler, 713230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 714230557Sjimharris scic_sds_stp_remote_device_ready_idle_substate_start_io_handler, 715230557Sjimharris scic_sds_remote_device_default_complete_request_handler, 716230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 717230557Sjimharris scic_sds_stp_remote_device_ready_substate_start_request_handler, 718230557Sjimharris scic_sds_remote_device_default_complete_request_handler 719230557Sjimharris }, 720230557Sjimharris scic_sds_remote_device_default_suspend_handler, 721230557Sjimharris scic_sds_remote_device_default_resume_handler, 722230557Sjimharris scic_sds_stp_remote_device_ready_idle_substate_event_handler, 723230557Sjimharris scic_sds_remote_device_default_frame_handler 724230557Sjimharris }, 725230557Sjimharris // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD 726230557Sjimharris { 727230557Sjimharris { 728230557Sjimharris scic_sds_remote_device_default_start_handler, 729230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 730230557Sjimharris scic_sds_remote_device_default_fail_handler, 731230557Sjimharris scic_sds_remote_device_default_destruct_handler, 732230557Sjimharris scic_sds_remote_device_ready_state_reset_handler, 733230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 734230557Sjimharris scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler, 735230557Sjimharris scic_sds_stp_remote_device_complete_request, 736230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 737230557Sjimharris scic_sds_stp_remote_device_ready_substate_start_request_handler, 738230557Sjimharris scic_sds_stp_remote_device_complete_request, 739230557Sjimharris }, 740230557Sjimharris scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler, 741230557Sjimharris scic_sds_remote_device_default_resume_handler, 742230557Sjimharris scic_sds_remote_device_general_event_handler, 743230557Sjimharris scic_sds_stp_remote_device_ready_cmd_substate_frame_handler 744230557Sjimharris }, 745230557Sjimharris // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ 746230557Sjimharris { 747230557Sjimharris { 748230557Sjimharris scic_sds_remote_device_default_start_handler, 749230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 750230557Sjimharris scic_sds_remote_device_default_fail_handler, 751230557Sjimharris scic_sds_remote_device_default_destruct_handler, 752230557Sjimharris scic_sds_remote_device_ready_state_reset_handler, 753230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 754230557Sjimharris scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler, 755230557Sjimharris scic_sds_stp_remote_device_complete_request, 756230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 757230557Sjimharris scic_sds_stp_remote_device_ready_substate_start_request_handler, 758230557Sjimharris scic_sds_stp_remote_device_complete_request 759230557Sjimharris }, 760230557Sjimharris scic_sds_remote_device_default_suspend_handler, 761230557Sjimharris scic_sds_remote_device_default_resume_handler, 762230557Sjimharris scic_sds_stp_remote_device_ready_ncq_substate_event_handler, 763230557Sjimharris scic_sds_stp_remote_device_ready_ncq_substate_frame_handler 764230557Sjimharris }, 765230557Sjimharris // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 766230557Sjimharris { 767230557Sjimharris { 768230557Sjimharris scic_sds_remote_device_default_start_handler, 769230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 770230557Sjimharris scic_sds_remote_device_default_fail_handler, 771230557Sjimharris scic_sds_remote_device_default_destruct_handler, 772230557Sjimharris scic_sds_remote_device_ready_state_reset_handler, 773230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 774230557Sjimharris scic_sds_remote_device_default_start_request_handler, 775230557Sjimharris scic_sds_stp_remote_device_complete_request, 776230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 777230557Sjimharris scic_sds_stp_remote_device_ready_substate_start_request_handler, 778230557Sjimharris scic_sds_stp_remote_device_complete_request 779230557Sjimharris }, 780230557Sjimharris scic_sds_remote_device_default_suspend_handler, 781230557Sjimharris scic_sds_remote_device_default_resume_handler, 782230557Sjimharris scic_sds_remote_device_general_event_handler, 783230557Sjimharris scic_sds_remote_device_general_frame_handler 784230557Sjimharris }, 785230557Sjimharris#if !defined(DISABLE_ATAPI) 786230557Sjimharris // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR 787230557Sjimharris { 788230557Sjimharris { 789230557Sjimharris scic_sds_remote_device_default_start_handler, 790230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 791230557Sjimharris scic_sds_remote_device_default_fail_handler, 792230557Sjimharris scic_sds_remote_device_default_destruct_handler, 793230557Sjimharris scic_sds_remote_device_ready_state_reset_handler, 794230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 795230557Sjimharris scic_sds_remote_device_default_start_request_handler, 796230557Sjimharris scic_sds_stp_remote_device_complete_request, 797230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 798230557Sjimharris scic_sds_stp_remote_device_ready_substate_start_request_handler, 799230557Sjimharris scic_sds_stp_remote_device_complete_request 800230557Sjimharris }, 801230557Sjimharris scic_sds_remote_device_default_suspend_handler, 802230557Sjimharris scic_sds_remote_device_default_resume_handler, 803230557Sjimharris scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler, 804230557Sjimharris scic_sds_remote_device_general_frame_handler 805230557Sjimharris }, 806230557Sjimharris#endif 807230557Sjimharris // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET 808230557Sjimharris { 809230557Sjimharris { 810230557Sjimharris scic_sds_remote_device_default_start_handler, 811230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 812230557Sjimharris scic_sds_remote_device_default_fail_handler, 813230557Sjimharris scic_sds_remote_device_default_destruct_handler, 814230557Sjimharris scic_sds_remote_device_ready_state_reset_handler, 815230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 816230557Sjimharris scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler, 817230557Sjimharris scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler, 818230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 819230557Sjimharris scic_sds_stp_remote_device_ready_substate_start_request_handler, 820230557Sjimharris scic_sds_stp_remote_device_complete_request 821230557Sjimharris }, 822230557Sjimharris scic_sds_remote_device_default_suspend_handler, 823230557Sjimharris scic_sds_remote_device_default_resume_handler, 824230557Sjimharris scic_sds_remote_device_general_event_handler, 825230557Sjimharris scic_sds_remote_device_general_frame_handler 826230557Sjimharris } 827230557Sjimharris}; 828230557Sjimharris 829230557Sjimharris//***************************************************************************** 830230557Sjimharris//* STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS 831230557Sjimharris//***************************************************************************** 832230557Sjimharris 833230557Sjimharrisstatic 834230557Sjimharrisvoid scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler( 835230557Sjimharris void * user_cookie 836230557Sjimharris) 837230557Sjimharris{ 838230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 839230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_cookie; 840230557Sjimharris 841230557Sjimharris // For NCQ operation we do not issue a 842230557Sjimharris // scic_cb_remote_device_not_ready(). As a result, avoid sending 843230557Sjimharris // the ready notification. 844230557Sjimharris if (this_device->ready_substate_machine.previous_state_id 845230557Sjimharris != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) 846230557Sjimharris { 847230557Sjimharris scic_cb_remote_device_ready( 848230557Sjimharris scic_sds_remote_device_get_controller(this_device), this_device 849230557Sjimharris ); 850230557Sjimharris } 851230557Sjimharris} 852230557Sjimharris 853230557Sjimharris//***************************************************************************** 854230557Sjimharris//* STP REMOTE DEVICE READY IDLE SUBSTATE 855230557Sjimharris//***************************************************************************** 856230557Sjimharris 857230557Sjimharris/** 858230557Sjimharris * 859230557Sjimharris * @param[in] device This is the SCI base object which is cast into a 860230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 861230557Sjimharris * 862230557Sjimharris * @return none 863230557Sjimharris */ 864230557Sjimharrisstatic 865230557Sjimharrisvoid scic_sds_stp_remote_device_ready_idle_substate_enter( 866230557Sjimharris SCI_BASE_OBJECT_T * device 867230557Sjimharris) 868230557Sjimharris{ 869230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 870230557Sjimharris 871230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 872230557Sjimharris 873230557Sjimharris SET_STATE_HANDLER( 874230557Sjimharris this_device, 875230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table, 876230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 877230557Sjimharris ); 878230557Sjimharris 879230557Sjimharris this_device->working_request = NULL; 880230557Sjimharris 881230557Sjimharris if (scic_sds_remote_node_context_is_ready(this_device->rnc)) 882230557Sjimharris { 883230557Sjimharris // Since the RNC is ready, it's alright to finish completion 884230557Sjimharris // processing (e.g. signal the remote device is ready). 885230557Sjimharris scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler( 886230557Sjimharris this_device 887230557Sjimharris ); 888230557Sjimharris } 889230557Sjimharris else 890230557Sjimharris { 891230557Sjimharris scic_sds_remote_node_context_resume( 892230557Sjimharris this_device->rnc, 893230557Sjimharris scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler, 894230557Sjimharris this_device 895230557Sjimharris ); 896230557Sjimharris } 897230557Sjimharris} 898230557Sjimharris 899230557Sjimharris//***************************************************************************** 900230557Sjimharris//* STP REMOTE DEVICE READY CMD SUBSTATE 901230557Sjimharris//***************************************************************************** 902230557Sjimharris 903230557Sjimharris/** 904230557Sjimharris * 905230557Sjimharris * 906230557Sjimharris * @param[in] device This is the SCI base object which is cast into a 907230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 908230557Sjimharris * 909230557Sjimharris * @return none 910230557Sjimharris */ 911230557Sjimharrisstatic 912230557Sjimharrisvoid scic_sds_stp_remote_device_ready_cmd_substate_enter( 913230557Sjimharris SCI_BASE_OBJECT_T * device 914230557Sjimharris) 915230557Sjimharris{ 916230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 917230557Sjimharris 918230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 919230557Sjimharris 920230557Sjimharris ASSERT(this_device->working_request != NULL); 921230557Sjimharris 922230557Sjimharris SET_STATE_HANDLER( 923230557Sjimharris this_device, 924230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table, 925230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD 926230557Sjimharris ); 927230557Sjimharris 928230557Sjimharris scic_cb_remote_device_not_ready( 929230557Sjimharris scic_sds_remote_device_get_controller(this_device), 930230557Sjimharris this_device, 931230557Sjimharris SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED 932230557Sjimharris ); 933230557Sjimharris} 934230557Sjimharris 935230557Sjimharris//***************************************************************************** 936230557Sjimharris//* STP REMOTE DEVICE READY NCQ SUBSTATE 937230557Sjimharris//***************************************************************************** 938230557Sjimharris 939230557Sjimharris/** 940230557Sjimharris * 941230557Sjimharris * 942230557Sjimharris * @param[in] device This is the SCI base object which is cast into a 943230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 944230557Sjimharris * 945230557Sjimharris * @return none 946230557Sjimharris */ 947230557Sjimharrisstatic 948230557Sjimharrisvoid scic_sds_stp_remote_device_ready_ncq_substate_enter( 949230557Sjimharris SCI_BASE_OBJECT_T * device 950230557Sjimharris) 951230557Sjimharris{ 952230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 953230557Sjimharris 954230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 955230557Sjimharris 956230557Sjimharris SET_STATE_HANDLER( 957230557Sjimharris this_device, 958230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table, 959230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ 960230557Sjimharris ); 961230557Sjimharris} 962230557Sjimharris 963230557Sjimharris//***************************************************************************** 964230557Sjimharris//* STP REMOTE DEVICE READY NCQ ERROR SUBSTATE 965230557Sjimharris//***************************************************************************** 966230557Sjimharris 967230557Sjimharris/** 968230557Sjimharris * 969230557Sjimharris * 970230557Sjimharris * @param[in] device This is the SCI base object which is cast into a 971230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 972230557Sjimharris * 973230557Sjimharris * @return none 974230557Sjimharris */ 975230557Sjimharrisstatic 976230557Sjimharrisvoid scic_sds_stp_remote_device_ready_ncq_error_substate_enter( 977230557Sjimharris SCI_BASE_OBJECT_T * device 978230557Sjimharris) 979230557Sjimharris{ 980230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 981230557Sjimharris 982230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 983230557Sjimharris 984230557Sjimharris SET_STATE_HANDLER( 985230557Sjimharris this_device, 986230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table, 987230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 988230557Sjimharris ); 989230557Sjimharris 990230557Sjimharris if(this_device->not_ready_reason == 991230557Sjimharris SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) 992230557Sjimharris { 993230557Sjimharris scic_cb_remote_device_not_ready( 994230557Sjimharris scic_sds_remote_device_get_controller(this_device), 995230557Sjimharris this_device, 996230557Sjimharris this_device->not_ready_reason 997230557Sjimharris ); 998230557Sjimharris } 999230557Sjimharris} 1000230557Sjimharris 1001230557Sjimharris//***************************************************************************** 1002230557Sjimharris//* STP REMOTE DEVICE READY AWAIT RESET SUBSTATE 1003230557Sjimharris//***************************************************************************** 1004230557Sjimharris 1005230557Sjimharris/** 1006230557Sjimharris * @brief The enter routine to READY AWAIT RESET substate. 1007230557Sjimharris * 1008230557Sjimharris * @param[in] device This is the SCI base object which is cast into a 1009230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 1010230557Sjimharris * 1011230557Sjimharris * @return none 1012230557Sjimharris */ 1013230557Sjimharrisstatic 1014230557Sjimharrisvoid scic_sds_stp_remote_device_ready_await_reset_substate_enter( 1015230557Sjimharris SCI_BASE_OBJECT_T * device 1016230557Sjimharris) 1017230557Sjimharris{ 1018230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 1019230557Sjimharris 1020230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1021230557Sjimharris 1022230557Sjimharris SET_STATE_HANDLER( 1023230557Sjimharris this_device, 1024230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table, 1025230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET 1026230557Sjimharris ); 1027230557Sjimharris} 1028230557Sjimharris 1029230557Sjimharris#if !defined(DISABLE_ATAPI) 1030230557Sjimharris//***************************************************************************** 1031230557Sjimharris//* STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE 1032230557Sjimharris//***************************************************************************** 1033230557Sjimharris 1034230557Sjimharris/** 1035230557Sjimharris * @brief The enter routine to READY ATAPI ERROR substate. 1036230557Sjimharris * 1037230557Sjimharris * @param[in] device This is the SCI base object which is cast into a 1038230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 1039230557Sjimharris * 1040230557Sjimharris * @return none 1041230557Sjimharris */ 1042230557Sjimharrisstatic 1043230557Sjimharrisvoid scic_sds_stp_remote_device_ready_atapi_error_substate_enter( 1044230557Sjimharris SCI_BASE_OBJECT_T * device 1045230557Sjimharris) 1046230557Sjimharris{ 1047230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 1048230557Sjimharris 1049230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1050230557Sjimharris 1051230557Sjimharris SET_STATE_HANDLER( 1052230557Sjimharris this_device, 1053230557Sjimharris scic_sds_stp_remote_device_ready_substate_handler_table, 1054230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR 1055230557Sjimharris ); 1056230557Sjimharris} 1057230557Sjimharris#endif // !defined(DISABLE_ATAPI) 1058230557Sjimharris 1059230557Sjimharris// --------------------------------------------------------------------------- 1060230557Sjimharris 1061230557SjimharrisSCI_BASE_STATE_T 1062230557Sjimharris scic_sds_stp_remote_device_ready_substate_table[ 1063230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] = 1064230557Sjimharris{ 1065230557Sjimharris { 1066230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE, 1067230557Sjimharris scic_sds_stp_remote_device_ready_idle_substate_enter, 1068230557Sjimharris NULL 1069230557Sjimharris }, 1070230557Sjimharris { 1071230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD, 1072230557Sjimharris scic_sds_stp_remote_device_ready_cmd_substate_enter, 1073230557Sjimharris NULL 1074230557Sjimharris }, 1075230557Sjimharris { 1076230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ, 1077230557Sjimharris scic_sds_stp_remote_device_ready_ncq_substate_enter, 1078230557Sjimharris NULL 1079230557Sjimharris }, 1080230557Sjimharris { 1081230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR, 1082230557Sjimharris scic_sds_stp_remote_device_ready_ncq_error_substate_enter, 1083230557Sjimharris NULL 1084230557Sjimharris }, 1085230557Sjimharris#if !defined(DISABLE_ATAPI) 1086230557Sjimharris { 1087230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR, 1088230557Sjimharris scic_sds_stp_remote_device_ready_atapi_error_substate_enter, 1089230557Sjimharris NULL 1090230557Sjimharris }, 1091230557Sjimharris#endif 1092230557Sjimharris { 1093230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET, 1094230557Sjimharris scic_sds_stp_remote_device_ready_await_reset_substate_enter, 1095230557Sjimharris NULL 1096230557Sjimharris } 1097230557Sjimharris}; 1098230557Sjimharris 1099