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 structures, constants, and prototypes 60230557Sjimharris* associated with the remote node context in the silicon. It 61230557Sjimharris* exists to model and manage the remote node context in the silicon. 62230557Sjimharris*/ 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/sci_util.h> 65230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 66230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 67230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 68230557Sjimharris#include <dev/isci/scil/scic_sds_remote_node_context.h> 69230557Sjimharris#include <dev/isci/scil/sci_base_state_machine.h> 70230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 71230557Sjimharris#include <dev/isci/scil/scic_sds_port.h> 72230557Sjimharris#include <dev/isci/scil/scu_event_codes.h> 73230557Sjimharris#include <dev/isci/scil/scu_task_context.h> 74230557Sjimharris 75230557Sjimharris/** 76230557Sjimharris* @brief 77230557Sjimharris*/ 78230557Sjimharris void scic_sds_remote_node_context_construct( 79230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * device, 80230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc, 81230557Sjimharris U16 remote_node_index 82230557Sjimharris ) 83230557Sjimharris{ 84230557Sjimharris memset (rnc, 0, sizeof(SCIC_SDS_REMOTE_NODE_CONTEXT_T) ); 85230557Sjimharris 86230557Sjimharris rnc->remote_node_index = remote_node_index; 87230557Sjimharris rnc->device = device; 88230557Sjimharris rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; 89230557Sjimharris 90230557Sjimharris rnc->parent.logger = device->parent.parent.logger; 91230557Sjimharris 92230557Sjimharris sci_base_state_machine_construct( 93230557Sjimharris &rnc->state_machine, 94230557Sjimharris &rnc->parent, 95230557Sjimharris scic_sds_remote_node_context_state_table, 96230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE 97230557Sjimharris ); 98230557Sjimharris 99230557Sjimharris sci_base_state_machine_start(&rnc->state_machine); 100230557Sjimharris 101230557Sjimharris // State logging initialization takes place late for the remote node context 102230557Sjimharris // see the resume state handler for the initial state. 103230557Sjimharris} 104230557Sjimharris 105230557Sjimharris/** 106230557Sjimharris* This method will return TRUE if the RNC is not in the initial state. In 107230557Sjimharris* all other states the RNC is considered active and this will return TRUE. 108230557Sjimharris* 109230557Sjimharris* @note The destroy request of the state machine drives the RNC back to the 110230557Sjimharris* initial state. If the state machine changes then this routine will 111230557Sjimharris* also have to be changed. 112230557Sjimharris* 113230557Sjimharris* @param[in] this_rnc The RNC for which the is posted request is being made. 114230557Sjimharris* 115230557Sjimharris* @return BOOL 116230557Sjimharris* @retval TRUE if the state machine is not in the initial state 117230557Sjimharris* @retval FALSE if the state machine is in the initial state 118230557Sjimharris*/ 119230557Sjimharris BOOL scic_sds_remote_node_context_is_initialized( 120230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 121230557Sjimharris ) 122230557Sjimharris{ 123230557Sjimharris U32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine); 124230557Sjimharris 125230557Sjimharris if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE) 126230557Sjimharris { 127230557Sjimharris return FALSE; 128230557Sjimharris } 129230557Sjimharris 130230557Sjimharris return TRUE; 131230557Sjimharris} 132230557Sjimharris 133230557Sjimharris/** 134230557Sjimharris* This method will return TRUE if the remote node context is in a READY state 135230557Sjimharris* otherwise it will return FALSE 136230557Sjimharris* 137230557Sjimharris* @param[in] this_rnc The state of the remote node context object to check. 138230557Sjimharris* 139230557Sjimharris* @return BOOL 140230557Sjimharris* @retval TRUE if the remote node context is in the ready state. 141230557Sjimharris* @retval FALSE if the remote node context is not in the ready state. 142230557Sjimharris*/ 143230557Sjimharris BOOL scic_sds_remote_node_context_is_ready( 144230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 145230557Sjimharris ) 146230557Sjimharris{ 147230557Sjimharris U32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine); 148230557Sjimharris 149230557Sjimharris if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE) 150230557Sjimharris { 151230557Sjimharris return TRUE; 152230557Sjimharris } 153230557Sjimharris 154230557Sjimharris return FALSE; 155230557Sjimharris} 156230557Sjimharris 157230557Sjimharris/** 158230557Sjimharris* This method will construct the RNC buffer for this remote device object. 159230557Sjimharris* 160230557Sjimharris* @param[in] this_device The remote device to use to construct the RNC 161230557Sjimharris* buffer. 162230557Sjimharris* @param[in] rnc The buffer into which the remote device data will be copied. 163230557Sjimharris* 164230557Sjimharris* @return none 165230557Sjimharris*/ 166230557Sjimharris void scic_sds_remote_node_context_construct_buffer( 167230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 168230557Sjimharris ) 169230557Sjimharris{ 170230557Sjimharris SCU_REMOTE_NODE_CONTEXT_T * rnc; 171230557Sjimharris SCIC_SDS_CONTROLLER_T * the_controller; 172230557Sjimharris 173230557Sjimharris the_controller = scic_sds_remote_device_get_controller(this_rnc->device); 174230557Sjimharris 175230557Sjimharris rnc = scic_sds_controller_get_remote_node_context_buffer( 176230557Sjimharris the_controller, this_rnc->remote_node_index); 177230557Sjimharris 178230557Sjimharris memset( 179230557Sjimharris rnc, 180230557Sjimharris 0x00, 181230557Sjimharris sizeof(SCU_REMOTE_NODE_CONTEXT_T) 182230557Sjimharris * scic_sds_remote_device_node_count(this_rnc->device) 183230557Sjimharris ); 184230557Sjimharris 185230557Sjimharris rnc->ssp.remote_node_index = this_rnc->remote_node_index; 186230557Sjimharris rnc->ssp.remote_node_port_width = this_rnc->device->device_port_width; 187230557Sjimharris rnc->ssp.logical_port_index = 188230557Sjimharris scic_sds_remote_device_get_port_index(this_rnc->device); 189230557Sjimharris 190230557Sjimharris rnc->ssp.remote_sas_address_hi = SCIC_SWAP_DWORD(this_rnc->device->device_address.high); 191230557Sjimharris rnc->ssp.remote_sas_address_lo = SCIC_SWAP_DWORD(this_rnc->device->device_address.low); 192230557Sjimharris 193230557Sjimharris rnc->ssp.nexus_loss_timer_enable = TRUE; 194230557Sjimharris rnc->ssp.check_bit = FALSE; 195230557Sjimharris rnc->ssp.is_valid = FALSE; 196230557Sjimharris rnc->ssp.is_remote_node_context = TRUE; 197230557Sjimharris rnc->ssp.function_number = 0; 198230557Sjimharris 199230557Sjimharris rnc->ssp.arbitration_wait_time = 0; 200230557Sjimharris 201230557Sjimharris 202230557Sjimharris if ( 203230557Sjimharris this_rnc->device->target_protocols.u.bits.attached_sata_device 204230557Sjimharris || this_rnc->device->target_protocols.u.bits.attached_stp_target 205230557Sjimharris ) 206230557Sjimharris { 207230557Sjimharris rnc->ssp.connection_occupancy_timeout = 208230557Sjimharris the_controller->user_parameters.sds1.stp_max_occupancy_timeout; 209230557Sjimharris rnc->ssp.connection_inactivity_timeout = 210230557Sjimharris the_controller->user_parameters.sds1.stp_inactivity_timeout; 211230557Sjimharris } 212230557Sjimharris else 213230557Sjimharris { 214230557Sjimharris rnc->ssp.connection_occupancy_timeout = 215230557Sjimharris the_controller->user_parameters.sds1.ssp_max_occupancy_timeout; 216230557Sjimharris rnc->ssp.connection_inactivity_timeout = 217230557Sjimharris the_controller->user_parameters.sds1.ssp_inactivity_timeout; 218230557Sjimharris } 219230557Sjimharris 220230557Sjimharris rnc->ssp.initial_arbitration_wait_time = 0; 221230557Sjimharris 222230557Sjimharris // Open Address Frame Parameters 223230557Sjimharris rnc->ssp.oaf_connection_rate = this_rnc->device->connection_rate; 224230557Sjimharris rnc->ssp.oaf_features = 0; 225230557Sjimharris rnc->ssp.oaf_source_zone_group = 0; 226230557Sjimharris rnc->ssp.oaf_more_compatibility_features = 0; 227230557Sjimharris} 228230557Sjimharris 229230557Sjimharris// --------------------------------------------------------------------------- 230230557Sjimharris 231230557Sjimharris#ifdef SCI_LOGGING 232230557Sjimharris/** 233230557Sjimharris* This method will enable and turn on state transition logging for the remote 234230557Sjimharris* node context object. 235230557Sjimharris* 236230557Sjimharris* @param[in] this_rnc The remote node context for which state transition 237230557Sjimharris* logging is to be enabled. 238230557Sjimharris* 239230557Sjimharris* @return none 240230557Sjimharris*/ 241230557Sjimharris void scic_sds_remote_node_context_initialize_state_logging( 242230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 243230557Sjimharris ) 244230557Sjimharris{ 245230557Sjimharris sci_base_state_machine_logger_initialize( 246230557Sjimharris &this_rnc->state_machine_logger, 247230557Sjimharris &this_rnc->state_machine, 248230557Sjimharris &this_rnc->parent, 249230557Sjimharris scic_cb_logger_log_states, 250230557Sjimharris "SCIC_SDS_REMOTE_NODE_CONTEXT_T", "state machine", 251230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 252230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 253230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET 254230557Sjimharris ); 255230557Sjimharris} 256230557Sjimharris 257230557Sjimharris/** 258230557Sjimharris* This method will stop the state machine logging for this object and should 259230557Sjimharris* be called before the object is destroyed. 260230557Sjimharris* 261230557Sjimharris* @param[in] this_rnc The remote node context on which to stop logging state 262230557Sjimharris* transitions. 263230557Sjimharris* 264230557Sjimharris* @return none 265230557Sjimharris*/ 266230557Sjimharris void scic_sds_remote_node_context_deinitialize_state_logging( 267230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 268230557Sjimharris ) 269230557Sjimharris{ 270230557Sjimharris sci_base_state_machine_logger_deinitialize( 271230557Sjimharris &this_rnc->state_machine_logger, 272230557Sjimharris &this_rnc->state_machine 273230557Sjimharris ); 274230557Sjimharris} 275230557Sjimharris#endif 276230557Sjimharris 277230557Sjimharris/** 278230557Sjimharris* This method will setup the remote node context object so it will transition 279230557Sjimharris* to its ready state. If the remote node context is already setup to 280230557Sjimharris* transition to its final state then this function does nothing. 281230557Sjimharris* 282230557Sjimharris* @param[in] this_rnc 283230557Sjimharris* @param[in] the_callback 284230557Sjimharris* @param[in] callback_parameter 285230557Sjimharris* 286230557Sjimharris* @return none 287230557Sjimharris*/ 288230557Sjimharrisstatic 289230557Sjimharrisvoid scic_sds_remote_node_context_setup_to_resume( 290230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 291230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 292230557Sjimharris void * callback_parameter 293230557Sjimharris) 294230557Sjimharris{ 295230557Sjimharris if (this_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) 296230557Sjimharris { 297230557Sjimharris this_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY; 298230557Sjimharris this_rnc->user_callback = the_callback; 299230557Sjimharris this_rnc->user_cookie = callback_parameter; 300230557Sjimharris } 301230557Sjimharris} 302230557Sjimharris 303230557Sjimharris/** 304230557Sjimharris* This method will setup the remote node context object so it will 305230557Sjimharris* transistion to its final state. 306230557Sjimharris* 307230557Sjimharris* @param[in] this_rnc 308230557Sjimharris* @param[in] the_callback 309230557Sjimharris* @param[in] callback_parameter 310230557Sjimharris* 311230557Sjimharris* @return none 312230557Sjimharris*/ 313230557Sjimharrisstatic 314230557Sjimharrisvoid scic_sds_remote_node_context_setup_to_destory( 315230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 316230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 317230557Sjimharris void * callback_parameter 318230557Sjimharris) 319230557Sjimharris{ 320230557Sjimharris this_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL; 321230557Sjimharris this_rnc->user_callback = the_callback; 322230557Sjimharris this_rnc->user_cookie = callback_parameter; 323230557Sjimharris} 324230557Sjimharris 325230557Sjimharris/** 326230557Sjimharris* This method will continue to resume a remote node context. This is used 327230557Sjimharris* in the states where a resume is requested while a resume is in progress. 328230557Sjimharris* 329230557Sjimharris* @param[in] this_rnc 330230557Sjimharris* @param[in] the_callback 331230557Sjimharris* @param[in] callback_parameter 332230557Sjimharris*/ 333230557Sjimharrisstatic 334230557SjimharrisSCI_STATUS scic_sds_remote_node_context_continue_to_resume_handler( 335230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 336230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 337230557Sjimharris void * callback_parameter 338230557Sjimharris) 339230557Sjimharris{ 340230557Sjimharris if (this_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) 341230557Sjimharris { 342230557Sjimharris this_rnc->user_callback = the_callback; 343230557Sjimharris this_rnc->user_cookie = callback_parameter; 344230557Sjimharris 345230557Sjimharris return SCI_SUCCESS; 346230557Sjimharris } 347230557Sjimharris 348230557Sjimharris return SCI_FAILURE_INVALID_STATE; 349230557Sjimharris} 350230557Sjimharris 351230557Sjimharris//****************************************************************************** 352230557Sjimharris//* REMOTE NODE CONTEXT STATE MACHINE 353230557Sjimharris//****************************************************************************** 354230557Sjimharris 355230557Sjimharrisstatic 356230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_destruct_handler( 357230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 358230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 359230557Sjimharris void * callback_parameter 360230557Sjimharris) 361230557Sjimharris{ 362230557Sjimharris SCIC_LOG_WARNING(( 363230557Sjimharris sci_base_object_get_logger(this_rnc->device), 364230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 365230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 366230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 367230557Sjimharris "SCIC Remote Node Context 0x%x requested to stop while in unexpected state %d\n", 368230557Sjimharris this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine) 369230557Sjimharris )); 370230557Sjimharris 371230557Sjimharris // We have decided that the destruct request on the remote node context can not fail 372230557Sjimharris // since it is either in the initial/destroyed state or is can be destroyed. 373230557Sjimharris return SCI_SUCCESS; 374230557Sjimharris} 375230557Sjimharris 376230557Sjimharrisstatic 377230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_suspend_handler( 378230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 379230557Sjimharris U32 suspend_type, 380230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 381230557Sjimharris void * callback_parameter 382230557Sjimharris) 383230557Sjimharris{ 384230557Sjimharris SCIC_LOG_WARNING(( 385230557Sjimharris sci_base_object_get_logger(this_rnc->device), 386230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 387230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 388230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 389230557Sjimharris "SCIC Remote Node Context 0x%x requested to suspend while in wrong state %d\n", 390230557Sjimharris this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine) 391230557Sjimharris )); 392230557Sjimharris 393230557Sjimharris return SCI_FAILURE_INVALID_STATE; 394230557Sjimharris} 395230557Sjimharris 396230557Sjimharrisstatic 397230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_resume_handler( 398230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 399230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 400230557Sjimharris void * callback_parameter 401230557Sjimharris) 402230557Sjimharris{ 403230557Sjimharris SCIC_LOG_WARNING(( 404230557Sjimharris sci_base_object_get_logger(this_rnc->device), 405230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 406230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 407230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 408230557Sjimharris "SCIC Remote Node Context 0x%x requested to resume while in wrong state %d\n", 409230557Sjimharris this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine) 410230557Sjimharris )); 411230557Sjimharris 412230557Sjimharris return SCI_FAILURE_INVALID_STATE; 413230557Sjimharris} 414230557Sjimharris 415230557Sjimharrisstatic 416230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_start_io_handler( 417230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 418230557Sjimharris struct SCIC_SDS_REQUEST * the_request 419230557Sjimharris) 420230557Sjimharris{ 421230557Sjimharris SCIC_LOG_WARNING(( 422230557Sjimharris sci_base_object_get_logger(this_rnc->device), 423230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 424230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 425230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 426230557Sjimharris "SCIC Remote Node Context 0x%x requested to start io 0x%x while in wrong state %d\n", 427230557Sjimharris this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine) 428230557Sjimharris )); 429230557Sjimharris 430230557Sjimharris return SCI_FAILURE_INVALID_STATE; 431230557Sjimharris} 432230557Sjimharris 433230557Sjimharrisstatic 434230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_start_task_handler( 435230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 436230557Sjimharris struct SCIC_SDS_REQUEST * the_request 437230557Sjimharris) 438230557Sjimharris{ 439230557Sjimharris SCIC_LOG_WARNING(( 440230557Sjimharris sci_base_object_get_logger(this_rnc->device), 441230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 442230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 443230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 444230557Sjimharris "SCIC Remote Node Context 0x%x requested to start task 0x%x while in wrong state %d\n", 445230557Sjimharris this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine) 446230557Sjimharris )); 447230557Sjimharris 448230557Sjimharris return SCI_FAILURE; 449230557Sjimharris} 450230557Sjimharris 451230557Sjimharrisstatic 452230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_event_handler( 453230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 454230557Sjimharris U32 event_code 455230557Sjimharris) 456230557Sjimharris{ 457230557Sjimharris SCIC_LOG_WARNING(( 458230557Sjimharris sci_base_object_get_logger(this_rnc->device), 459230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 460230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 461230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 462230557Sjimharris "SCIC Remote Node Context 0x%x requested to process event 0x%x while in wrong state %d\n", 463230557Sjimharris this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) 464230557Sjimharris )); 465230557Sjimharris 466230557Sjimharris return SCI_FAILURE_INVALID_STATE; 467230557Sjimharris} 468230557Sjimharris 469230557Sjimharris/** 470230557Sjimharris* This method determines if the task request can be started by the SCU 471230557Sjimharris* hardware. When the RNC is in the ready state any task can be started. 472230557Sjimharris* 473230557Sjimharris* @param[in] this_rnc The rnc for which the task request is targeted. 474230557Sjimharris* @param[in] the_request The request which is going to be started. 475230557Sjimharris* 476230557Sjimharris* @return SCI_STATUS 477230557Sjimharris* @retval SCI_SUCCESS 478230557Sjimharris*/ 479230557Sjimharrisstatic 480230557SjimharrisSCI_STATUS scic_sds_remote_node_context_success_start_task_handler( 481230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 482230557Sjimharris struct SCIC_SDS_REQUEST * the_request 483230557Sjimharris) 484230557Sjimharris{ 485230557Sjimharris return SCI_SUCCESS; 486230557Sjimharris} 487230557Sjimharris 488230557Sjimharris/** 489230557Sjimharris* This method handles destruct calls from the various state handlers. The 490230557Sjimharris* remote node context can be requested to destroy from any state. If there 491230557Sjimharris* was a user callback it is always replaced with the request to destroy user 492230557Sjimharris* callback. 493230557Sjimharris* 494230557Sjimharris* @param[in] this_rnc 495230557Sjimharris* @param[in] the_callback 496230557Sjimharris* @param[in] callback_parameter 497230557Sjimharris* 498230557Sjimharris* @return SCI_STATUS 499230557Sjimharris*/ 500230557Sjimharrisstatic 501230557SjimharrisSCI_STATUS scic_sds_remote_node_context_general_destruct_handler( 502230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 503230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 504230557Sjimharris void * callback_parameter 505230557Sjimharris) 506230557Sjimharris{ 507230557Sjimharris scic_sds_remote_node_context_setup_to_destory( 508230557Sjimharris this_rnc, the_callback, callback_parameter 509230557Sjimharris ); 510230557Sjimharris 511230557Sjimharris sci_base_state_machine_change_state( 512230557Sjimharris &this_rnc->state_machine, 513230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE 514230557Sjimharris ); 515230557Sjimharris 516230557Sjimharris return SCI_SUCCESS; 517230557Sjimharris} 518230557Sjimharris// --------------------------------------------------------------------------- 519230557Sjimharrisstatic 520230557SjimharrisSCI_STATUS scic_sds_remote_node_context_reset_required_start_io_handler( 521230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 522230557Sjimharris struct SCIC_SDS_REQUEST * the_request 523230557Sjimharris) 524230557Sjimharris{ 525230557Sjimharris SCIC_LOG_WARNING(( 526230557Sjimharris sci_base_object_get_logger(this_rnc->device), 527230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 528230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 529230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 530230557Sjimharris "SCIC Remote Node Context 0x%x requested to start io 0x%x while in wrong state %d\n", 531230557Sjimharris this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine) 532230557Sjimharris )); 533230557Sjimharris 534230557Sjimharris return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; 535230557Sjimharris} 536230557Sjimharris 537230557Sjimharris// --------------------------------------------------------------------------- 538230557Sjimharris 539230557Sjimharrisstatic 540230557SjimharrisSCI_STATUS scic_sds_remote_node_context_initial_state_resume_handler( 541230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 542230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 543230557Sjimharris void * callback_parameter 544230557Sjimharris) 545230557Sjimharris{ 546230557Sjimharris if (this_rnc->remote_node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) 547230557Sjimharris { 548230557Sjimharris scic_sds_remote_node_context_setup_to_resume( 549230557Sjimharris this_rnc, the_callback, callback_parameter 550230557Sjimharris ); 551230557Sjimharris 552230557Sjimharris scic_sds_remote_node_context_construct_buffer(this_rnc); 553230557Sjimharris 554230557Sjimharris#if defined (SCI_LOGGING) 555230557Sjimharris // If a remote node context has a logger already, don't work on its state 556230557Sjimharris // logging. 557230557Sjimharris if (this_rnc->state_machine.previous_state_id 558230557Sjimharris != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE) 559230557Sjimharris scic_sds_remote_node_context_initialize_state_logging(this_rnc); 560230557Sjimharris#endif 561230557Sjimharris 562230557Sjimharris sci_base_state_machine_change_state( 563230557Sjimharris &this_rnc->state_machine, 564230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE 565230557Sjimharris ); 566230557Sjimharris 567230557Sjimharris return SCI_SUCCESS; 568230557Sjimharris } 569230557Sjimharris 570230557Sjimharris return SCI_FAILURE_INVALID_STATE; 571230557Sjimharris} 572230557Sjimharris 573230557Sjimharris// --------------------------------------------------------------------------- 574230557Sjimharris 575230557Sjimharrisstatic 576230557SjimharrisSCI_STATUS scic_sds_remote_node_context_posting_state_event_handler( 577230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 578230557Sjimharris U32 event_code 579230557Sjimharris) 580230557Sjimharris{ 581230557Sjimharris SCI_STATUS status; 582230557Sjimharris 583230557Sjimharris switch (scu_get_event_code(event_code)) 584230557Sjimharris { 585230557Sjimharris case SCU_EVENT_POST_RNC_COMPLETE: 586230557Sjimharris status = SCI_SUCCESS; 587230557Sjimharris 588230557Sjimharris sci_base_state_machine_change_state( 589230557Sjimharris &this_rnc->state_machine, 590230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE 591230557Sjimharris ); 592230557Sjimharris break; 593230557Sjimharris 594230557Sjimharris default: 595230557Sjimharris status = SCI_FAILURE; 596230557Sjimharris SCIC_LOG_WARNING(( 597230557Sjimharris sci_base_object_get_logger(this_rnc->device), 598230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 599230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 600230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 601230557Sjimharris "SCIC Remote Node Context 0x%x requested to process unexpected event 0x%x while in posting state\n", 602230557Sjimharris this_rnc, event_code 603230557Sjimharris )); 604230557Sjimharris break; 605230557Sjimharris } 606230557Sjimharris 607230557Sjimharris return status; 608230557Sjimharris} 609230557Sjimharris 610230557Sjimharris// --------------------------------------------------------------------------- 611230557Sjimharris 612230557Sjimharrisstatic 613230557SjimharrisSCI_STATUS scic_sds_remote_node_context_invalidating_state_destruct_handler( 614230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 615230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 616230557Sjimharris void * callback_parameter 617230557Sjimharris) 618230557Sjimharris{ 619230557Sjimharris scic_sds_remote_node_context_setup_to_destory( 620230557Sjimharris this_rnc, the_callback, callback_parameter 621230557Sjimharris ); 622230557Sjimharris 623230557Sjimharris return SCI_SUCCESS; 624230557Sjimharris} 625230557Sjimharris 626230557Sjimharrisstatic 627230557SjimharrisSCI_STATUS scic_sds_remote_node_context_invalidating_state_event_handler( 628230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 629230557Sjimharris U32 event_code 630230557Sjimharris) 631230557Sjimharris{ 632230557Sjimharris SCI_STATUS status; 633230557Sjimharris 634230557Sjimharris if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) 635230557Sjimharris { 636230557Sjimharris status = SCI_SUCCESS; 637230557Sjimharris 638230557Sjimharris if (this_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) 639230557Sjimharris { 640230557Sjimharris sci_base_state_machine_change_state( 641230557Sjimharris &this_rnc->state_machine, 642230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE 643230557Sjimharris ); 644230557Sjimharris } 645230557Sjimharris else 646230557Sjimharris { 647230557Sjimharris sci_base_state_machine_change_state( 648230557Sjimharris &this_rnc->state_machine, 649230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE 650230557Sjimharris ); 651230557Sjimharris } 652230557Sjimharris } 653230557Sjimharris else 654230557Sjimharris { 655230557Sjimharris switch (scu_get_event_type(event_code)) 656230557Sjimharris { 657230557Sjimharris case SCU_EVENT_TYPE_RNC_SUSPEND_TX: 658230557Sjimharris case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: 659230557Sjimharris // We really dont care if the hardware is going to suspend 660230557Sjimharris // the device since it's being invalidated anyway 661230557Sjimharris SCIC_LOG_INFO(( 662230557Sjimharris sci_base_object_get_logger(this_rnc->device), 663230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 664230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 665230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 666230557Sjimharris "SCIC Remote Node Context 0x%x was suspeneded by hardware while being invalidated.\n", 667230557Sjimharris this_rnc 668230557Sjimharris )); 669230557Sjimharris status = SCI_SUCCESS; 670230557Sjimharris break; 671230557Sjimharris 672230557Sjimharris default: 673230557Sjimharris SCIC_LOG_WARNING(( 674230557Sjimharris sci_base_object_get_logger(this_rnc->device), 675230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 676230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 677230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 678230557Sjimharris "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n", 679230557Sjimharris this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) 680230557Sjimharris )); 681230557Sjimharris status = SCI_FAILURE; 682230557Sjimharris break; 683230557Sjimharris } 684230557Sjimharris } 685230557Sjimharris 686230557Sjimharris return status; 687230557Sjimharris} 688230557Sjimharris 689230557Sjimharris// --------------------------------------------------------------------------- 690230557Sjimharris 691230557Sjimharrisstatic 692230557SjimharrisSCI_STATUS scic_sds_remote_node_context_resuming_state_event_handler( 693230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 694230557Sjimharris U32 event_code 695230557Sjimharris) 696230557Sjimharris{ 697230557Sjimharris SCI_STATUS status; 698230557Sjimharris 699230557Sjimharris if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) 700230557Sjimharris { 701230557Sjimharris status = SCI_SUCCESS; 702230557Sjimharris 703230557Sjimharris sci_base_state_machine_change_state( 704230557Sjimharris &this_rnc->state_machine, 705230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE 706230557Sjimharris ); 707230557Sjimharris } 708230557Sjimharris else 709230557Sjimharris { 710230557Sjimharris switch (scu_get_event_type(event_code)) 711230557Sjimharris { 712230557Sjimharris case SCU_EVENT_TYPE_RNC_SUSPEND_TX: 713230557Sjimharris case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: 714230557Sjimharris // We really dont care if the hardware is going to suspend 715230557Sjimharris // the device since it's being resumed anyway 716230557Sjimharris SCIC_LOG_INFO(( 717230557Sjimharris sci_base_object_get_logger(this_rnc->device), 718230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 719230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 720230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 721230557Sjimharris "SCIC Remote Node Context 0x%x was suspeneded by hardware while being resumed.\n", 722230557Sjimharris this_rnc 723230557Sjimharris )); 724230557Sjimharris status = SCI_SUCCESS; 725230557Sjimharris break; 726230557Sjimharris 727230557Sjimharris default: 728230557Sjimharris SCIC_LOG_WARNING(( 729230557Sjimharris sci_base_object_get_logger(this_rnc->device), 730230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 731230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 732230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 733230557Sjimharris "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n", 734230557Sjimharris this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) 735230557Sjimharris )); 736230557Sjimharris status = SCI_FAILURE; 737230557Sjimharris break; 738230557Sjimharris } 739230557Sjimharris } 740230557Sjimharris 741230557Sjimharris return status; 742230557Sjimharris} 743230557Sjimharris 744230557Sjimharris// --------------------------------------------------------------------------- 745230557Sjimharris 746230557Sjimharris/** 747230557Sjimharris* This method will handle the suspend requests from the ready state. 748230557Sjimharris* 749230557Sjimharris* @param[in] this_rnc The remote node context object being suspended. 750230557Sjimharris* @param[in] the_callback The callback when the suspension is complete. 751230557Sjimharris* @param[in] callback_parameter The parameter that is to be passed into the 752230557Sjimharris* callback. 753230557Sjimharris* 754230557Sjimharris* @return SCI_SUCCESS 755230557Sjimharris*/ 756230557Sjimharrisstatic 757230557SjimharrisSCI_STATUS scic_sds_remote_node_context_ready_state_suspend_handler( 758230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 759230557Sjimharris U32 suspend_type, 760230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 761230557Sjimharris void * callback_parameter 762230557Sjimharris) 763230557Sjimharris{ 764230557Sjimharris this_rnc->user_callback = the_callback; 765230557Sjimharris this_rnc->user_cookie = callback_parameter; 766230557Sjimharris this_rnc->suspension_code = suspend_type; 767230557Sjimharris 768230557Sjimharris if (suspend_type == SCI_SOFTWARE_SUSPENSION) 769230557Sjimharris { 770230557Sjimharris scic_sds_remote_device_post_request( 771230557Sjimharris this_rnc->device, 772230557Sjimharris SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX 773230557Sjimharris ); 774230557Sjimharris } 775230557Sjimharris 776230557Sjimharris sci_base_state_machine_change_state( 777230557Sjimharris &this_rnc->state_machine, 778230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE 779230557Sjimharris ); 780230557Sjimharris 781230557Sjimharris return SCI_SUCCESS; 782230557Sjimharris} 783230557Sjimharris 784230557Sjimharris/** 785230557Sjimharris* This method determines if the io request can be started by the SCU 786230557Sjimharris* hardware. When the RNC is in the ready state any io request can be started. 787230557Sjimharris* 788230557Sjimharris* @param[in] this_rnc The rnc for which the io request is targeted. 789230557Sjimharris* @param[in] the_request The request which is going to be started. 790230557Sjimharris* 791230557Sjimharris* @return SCI_STATUS 792230557Sjimharris* @retval SCI_SUCCESS 793230557Sjimharris*/ 794230557Sjimharrisstatic 795230557SjimharrisSCI_STATUS scic_sds_remote_node_context_ready_state_start_io_handler( 796230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 797230557Sjimharris struct SCIC_SDS_REQUEST * the_request 798230557Sjimharris) 799230557Sjimharris{ 800230557Sjimharris return SCI_SUCCESS; 801230557Sjimharris} 802230557Sjimharris 803230557Sjimharris 804230557Sjimharrisstatic 805230557SjimharrisSCI_STATUS scic_sds_remote_node_context_ready_state_event_handler( 806230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 807230557Sjimharris U32 event_code 808230557Sjimharris) 809230557Sjimharris{ 810230557Sjimharris SCI_STATUS status; 811230557Sjimharris 812230557Sjimharris switch (scu_get_event_type(event_code)) 813230557Sjimharris { 814230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX: 815230557Sjimharris sci_base_state_machine_change_state( 816230557Sjimharris &this_rnc->state_machine, 817230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE 818230557Sjimharris ); 819230557Sjimharris 820230557Sjimharris this_rnc->suspension_code = scu_get_event_specifier(event_code); 821230557Sjimharris status = SCI_SUCCESS; 822230557Sjimharris break; 823230557Sjimharris 824230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: 825230557Sjimharris sci_base_state_machine_change_state( 826230557Sjimharris &this_rnc->state_machine, 827230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE 828230557Sjimharris ); 829230557Sjimharris 830230557Sjimharris this_rnc->suspension_code = scu_get_event_specifier(event_code); 831230557Sjimharris status = SCI_SUCCESS; 832230557Sjimharris break; 833230557Sjimharris 834230557Sjimharris default: 835230557Sjimharris SCIC_LOG_WARNING(( 836230557Sjimharris sci_base_object_get_logger(this_rnc->device), 837230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 838230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 839230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 840230557Sjimharris "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n", 841230557Sjimharris this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) 842230557Sjimharris )); 843230557Sjimharris 844230557Sjimharris status = SCI_FAILURE; 845230557Sjimharris break; 846230557Sjimharris } 847230557Sjimharris 848230557Sjimharris return status; 849230557Sjimharris} 850230557Sjimharris 851230557Sjimharris// --------------------------------------------------------------------------- 852230557Sjimharris 853230557Sjimharrisstatic 854230557SjimharrisSCI_STATUS scic_sds_remote_node_context_tx_suspended_state_resume_handler( 855230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 856230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 857230557Sjimharris void * callback_parameter 858230557Sjimharris) 859230557Sjimharris{ 860230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T protocols; 861230557Sjimharris 862230557Sjimharris scic_sds_remote_node_context_setup_to_resume( 863230557Sjimharris this_rnc, the_callback, callback_parameter 864230557Sjimharris ); 865230557Sjimharris 866230557Sjimharris // If this is an expander attached SATA device we must invalidate 867230557Sjimharris // and repost the RNC since this is the only way to clear the 868230557Sjimharris // TCi to NCQ tag mapping table for the RNi 869230557Sjimharris // All other device types we can just resume. 870230557Sjimharris scic_remote_device_get_protocols(this_rnc->device, &protocols); 871230557Sjimharris 872230557Sjimharris if ( 873230557Sjimharris (protocols.u.bits.attached_stp_target == 1) 874230557Sjimharris && !(this_rnc->device->is_direct_attached) 875230557Sjimharris ) 876230557Sjimharris { 877230557Sjimharris sci_base_state_machine_change_state( 878230557Sjimharris &this_rnc->state_machine, 879230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE 880230557Sjimharris ); 881230557Sjimharris } 882230557Sjimharris else 883230557Sjimharris { 884230557Sjimharris sci_base_state_machine_change_state( 885230557Sjimharris &this_rnc->state_machine, 886230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE 887230557Sjimharris ); 888230557Sjimharris } 889230557Sjimharris 890230557Sjimharris return SCI_SUCCESS; 891230557Sjimharris} 892230557Sjimharris 893230557Sjimharris/** 894230557Sjimharris* This method will report a success or failure attempt to start a new task 895230557Sjimharris* request to the hardware. Since all task requests are sent on the high 896230557Sjimharris* priority queue they can be sent when the RCN is in a TX suspend state. 897230557Sjimharris* 898230557Sjimharris* @param[in] this_rnc The remote node context which is to receive the task 899230557Sjimharris* request. 900230557Sjimharris* @param[in] the_request The task request to be transmitted to to the remote 901230557Sjimharris* target device. 902230557Sjimharris* 903230557Sjimharris* @return SCI_STATUS 904230557Sjimharris* @retval SCI_SUCCESS 905230557Sjimharris*/ 906230557Sjimharrisstatic 907230557SjimharrisSCI_STATUS scic_sds_remote_node_context_suspended_start_task_handler( 908230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 909230557Sjimharris struct SCIC_SDS_REQUEST * the_request 910230557Sjimharris) 911230557Sjimharris{ 912230557Sjimharris scic_sds_remote_node_context_resume(this_rnc, NULL, NULL); 913230557Sjimharris 914230557Sjimharris return SCI_SUCCESS; 915230557Sjimharris} 916230557Sjimharris 917230557Sjimharris// --------------------------------------------------------------------------- 918230557Sjimharris 919230557Sjimharrisstatic 920230557SjimharrisSCI_STATUS scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler( 921230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 922230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 923230557Sjimharris void * callback_parameter 924230557Sjimharris) 925230557Sjimharris{ 926230557Sjimharris scic_sds_remote_node_context_setup_to_resume( 927230557Sjimharris this_rnc, the_callback, callback_parameter 928230557Sjimharris ); 929230557Sjimharris 930230557Sjimharris sci_base_state_machine_change_state( 931230557Sjimharris &this_rnc->state_machine, 932230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE 933230557Sjimharris ); 934230557Sjimharris 935230557Sjimharris return SCI_FAILURE_INVALID_STATE; 936230557Sjimharris} 937230557Sjimharris 938230557Sjimharris// --------------------------------------------------------------------------- 939230557Sjimharris 940230557Sjimharris/** 941230557Sjimharris* 942230557Sjimharris*/ 943230557Sjimharrisstatic 944230557SjimharrisSCI_STATUS scic_sds_remote_node_context_await_suspension_state_resume_handler( 945230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, 946230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 947230557Sjimharris void * callback_parameter 948230557Sjimharris) 949230557Sjimharris{ 950230557Sjimharris scic_sds_remote_node_context_setup_to_resume( 951230557Sjimharris this_rnc, the_callback, callback_parameter 952230557Sjimharris ); 953230557Sjimharris 954230557Sjimharris return SCI_SUCCESS; 955230557Sjimharris} 956230557Sjimharris 957230557Sjimharris/** 958230557Sjimharris* This method will report a success or failure attempt to start a new task 959230557Sjimharris* request to the hardware. Since all task requests are sent on the high 960230557Sjimharris* priority queue they can be sent when the RCN is in a TX suspend state. 961230557Sjimharris* 962230557Sjimharris* @param[in] this_rnc The remote node context which is to receive the task 963230557Sjimharris* request. 964230557Sjimharris* @param[in] the_request The task request to be transmitted to to the remote 965230557Sjimharris* target device. 966230557Sjimharris* 967230557Sjimharris* @return SCI_STATUS 968230557Sjimharris* @retval SCI_SUCCESS 969230557Sjimharris*/ 970230557Sjimharrisstatic 971230557SjimharrisSCI_STATUS scic_sds_remote_node_context_await_suspension_state_start_task_handler( 972230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 973230557Sjimharris struct SCIC_SDS_REQUEST * the_request 974230557Sjimharris) 975230557Sjimharris{ 976230557Sjimharris return SCI_SUCCESS; 977230557Sjimharris} 978230557Sjimharris 979230557Sjimharrisstatic 980230557SjimharrisSCI_STATUS scic_sds_remote_node_context_await_suspension_state_event_handler( 981230557Sjimharris struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 982230557Sjimharris U32 event_code 983230557Sjimharris) 984230557Sjimharris{ 985230557Sjimharris SCI_STATUS status; 986230557Sjimharris 987230557Sjimharris switch (scu_get_event_type(event_code)) 988230557Sjimharris { 989230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX: 990230557Sjimharris sci_base_state_machine_change_state( 991230557Sjimharris &this_rnc->state_machine, 992230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE 993230557Sjimharris ); 994230557Sjimharris 995230557Sjimharris this_rnc->suspension_code = scu_get_event_specifier(event_code); 996230557Sjimharris status = SCI_SUCCESS; 997230557Sjimharris break; 998230557Sjimharris 999230557Sjimharris case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: 1000230557Sjimharris sci_base_state_machine_change_state( 1001230557Sjimharris &this_rnc->state_machine, 1002230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE 1003230557Sjimharris ); 1004230557Sjimharris 1005230557Sjimharris this_rnc->suspension_code = scu_get_event_specifier(event_code); 1006230557Sjimharris status = SCI_SUCCESS; 1007230557Sjimharris break; 1008230557Sjimharris 1009230557Sjimharris default: 1010230557Sjimharris SCIC_LOG_WARNING(( 1011230557Sjimharris sci_base_object_get_logger(this_rnc->device), 1012230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1013230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1014230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1015230557Sjimharris "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n", 1016230557Sjimharris this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) 1017230557Sjimharris )); 1018230557Sjimharris 1019230557Sjimharris status = SCI_FAILURE; 1020230557Sjimharris break; 1021230557Sjimharris } 1022230557Sjimharris 1023230557Sjimharris return status; 1024230557Sjimharris} 1025230557Sjimharris 1026230557Sjimharris// --------------------------------------------------------------------------- 1027230557Sjimharris 1028230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS 1029230557Sjimharris scic_sds_remote_node_context_state_handler_table[ 1030230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES] = 1031230557Sjimharris{ 1032230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE 1033230557Sjimharris { 1034230557Sjimharris scic_sds_remote_node_context_default_destruct_handler, 1035230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1036230557Sjimharris scic_sds_remote_node_context_initial_state_resume_handler, 1037230557Sjimharris scic_sds_remote_node_context_default_start_io_handler, 1038230557Sjimharris scic_sds_remote_node_context_default_start_task_handler, 1039230557Sjimharris scic_sds_remote_node_context_default_event_handler 1040230557Sjimharris }, 1041230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE 1042230557Sjimharris { 1043230557Sjimharris scic_sds_remote_node_context_general_destruct_handler, 1044230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1045230557Sjimharris scic_sds_remote_node_context_continue_to_resume_handler, 1046230557Sjimharris scic_sds_remote_node_context_default_start_io_handler, 1047230557Sjimharris scic_sds_remote_node_context_default_start_task_handler, 1048230557Sjimharris scic_sds_remote_node_context_posting_state_event_handler 1049230557Sjimharris }, 1050230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE 1051230557Sjimharris { 1052230557Sjimharris scic_sds_remote_node_context_invalidating_state_destruct_handler, 1053230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1054230557Sjimharris scic_sds_remote_node_context_continue_to_resume_handler, 1055230557Sjimharris scic_sds_remote_node_context_default_start_io_handler, 1056230557Sjimharris scic_sds_remote_node_context_default_start_task_handler, 1057230557Sjimharris scic_sds_remote_node_context_invalidating_state_event_handler 1058230557Sjimharris }, 1059230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE 1060230557Sjimharris { 1061230557Sjimharris scic_sds_remote_node_context_general_destruct_handler, 1062230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1063230557Sjimharris scic_sds_remote_node_context_continue_to_resume_handler, 1064230557Sjimharris scic_sds_remote_node_context_default_start_io_handler, 1065230557Sjimharris scic_sds_remote_node_context_success_start_task_handler, 1066230557Sjimharris scic_sds_remote_node_context_resuming_state_event_handler 1067230557Sjimharris }, 1068230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE 1069230557Sjimharris { 1070230557Sjimharris scic_sds_remote_node_context_general_destruct_handler, 1071230557Sjimharris scic_sds_remote_node_context_ready_state_suspend_handler, 1072230557Sjimharris scic_sds_remote_node_context_default_resume_handler, 1073230557Sjimharris scic_sds_remote_node_context_ready_state_start_io_handler, 1074230557Sjimharris scic_sds_remote_node_context_success_start_task_handler, 1075230557Sjimharris scic_sds_remote_node_context_ready_state_event_handler 1076230557Sjimharris }, 1077230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE 1078230557Sjimharris { 1079230557Sjimharris scic_sds_remote_node_context_general_destruct_handler, 1080230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1081230557Sjimharris scic_sds_remote_node_context_tx_suspended_state_resume_handler, 1082230557Sjimharris scic_sds_remote_node_context_reset_required_start_io_handler, 1083230557Sjimharris scic_sds_remote_node_context_suspended_start_task_handler, 1084230557Sjimharris scic_sds_remote_node_context_default_event_handler 1085230557Sjimharris }, 1086230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE 1087230557Sjimharris { 1088230557Sjimharris scic_sds_remote_node_context_general_destruct_handler, 1089230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1090230557Sjimharris scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler, 1091230557Sjimharris scic_sds_remote_node_context_reset_required_start_io_handler, 1092230557Sjimharris scic_sds_remote_node_context_suspended_start_task_handler, 1093230557Sjimharris scic_sds_remote_node_context_default_event_handler 1094230557Sjimharris }, 1095230557Sjimharris // SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE 1096230557Sjimharris { 1097230557Sjimharris scic_sds_remote_node_context_general_destruct_handler, 1098230557Sjimharris scic_sds_remote_node_context_default_suspend_handler, 1099230557Sjimharris scic_sds_remote_node_context_await_suspension_state_resume_handler, 1100230557Sjimharris scic_sds_remote_node_context_reset_required_start_io_handler, 1101230557Sjimharris scic_sds_remote_node_context_await_suspension_state_start_task_handler, 1102230557Sjimharris scic_sds_remote_node_context_await_suspension_state_event_handler 1103230557Sjimharris } 1104230557Sjimharris}; 1105230557Sjimharris 1106230557Sjimharris//***************************************************************************** 1107230557Sjimharris//* REMOTE NODE CONTEXT PRIVATE METHODS 1108230557Sjimharris//***************************************************************************** 1109230557Sjimharris 1110230557Sjimharris/** 1111230557Sjimharris* This method just calls the user callback function and then resets the 1112230557Sjimharris* callback. 1113230557Sjimharris* 1114230557Sjimharris* @param[in out] rnc 1115230557Sjimharris*/ 1116230557Sjimharrisstatic 1117230557Sjimharrisvoid scic_sds_remote_node_context_notify_user( 1118230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T *rnc 1119230557Sjimharris) 1120230557Sjimharris{ 1121230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK local_user_callback = rnc->user_callback; 1122230557Sjimharris void * local_user_cookie = rnc->user_cookie; 1123230557Sjimharris 1124230557Sjimharris //we need to set the user_callback to NULL before it is called, because 1125230557Sjimharris //the user callback's stack may eventually also set up a new set of 1126230557Sjimharris //user callback. If we nullify the user_callback after it is called, 1127230557Sjimharris //we are in the risk to lose the freshly set user callback. 1128230557Sjimharris rnc->user_callback = NULL; 1129230557Sjimharris rnc->user_cookie = NULL; 1130230557Sjimharris 1131230557Sjimharris if (local_user_callback != NULL) 1132230557Sjimharris { 1133230557Sjimharris (*local_user_callback)(local_user_cookie); 1134230557Sjimharris } 1135230557Sjimharris} 1136230557Sjimharris 1137230557Sjimharris/** 1138230557Sjimharris* This method will continue the remote node context state machine by 1139230557Sjimharris* requesting to resume the remote node context state machine from its current 1140230557Sjimharris* state. 1141230557Sjimharris* 1142230557Sjimharris* @param[in] rnc 1143230557Sjimharris*/ 1144230557Sjimharrisstatic 1145230557Sjimharrisvoid scic_sds_remote_node_context_continue_state_transitions( 1146230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc 1147230557Sjimharris) 1148230557Sjimharris{ 1149230557Sjimharris if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) 1150230557Sjimharris { 1151230557Sjimharris rnc->state_handlers->resume_handler( 1152230557Sjimharris rnc, rnc->user_callback, rnc->user_cookie 1153230557Sjimharris ); 1154230557Sjimharris } 1155230557Sjimharris} 1156230557Sjimharris 1157230557Sjimharris/** 1158230557Sjimharris* This method will mark the rnc buffer as being valid and post the request to 1159230557Sjimharris* the hardware. 1160230557Sjimharris* 1161230557Sjimharris* @param[in] this_rnc The remote node context object that is to be 1162230557Sjimharris* validated. 1163230557Sjimharris* 1164230557Sjimharris* @return none 1165230557Sjimharris*/ 1166230557Sjimharrisstatic 1167230557Sjimharrisvoid scic_sds_remote_node_context_validate_context_buffer( 1168230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 1169230557Sjimharris) 1170230557Sjimharris{ 1171230557Sjimharris SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer; 1172230557Sjimharris 1173230557Sjimharris rnc_buffer = scic_sds_controller_get_remote_node_context_buffer( 1174230557Sjimharris scic_sds_remote_device_get_controller(this_rnc->device), 1175230557Sjimharris this_rnc->remote_node_index 1176230557Sjimharris ); 1177230557Sjimharris 1178230557Sjimharris rnc_buffer->ssp.is_valid = TRUE; 1179230557Sjimharris 1180230557Sjimharris if ( 1181230557Sjimharris !this_rnc->device->is_direct_attached 1182230557Sjimharris && this_rnc->device->target_protocols.u.bits.attached_stp_target 1183230557Sjimharris ) 1184230557Sjimharris { 1185230557Sjimharris scic_sds_remote_device_post_request( 1186230557Sjimharris this_rnc->device, 1187230557Sjimharris SCU_CONTEXT_COMMAND_POST_RNC_96 1188230557Sjimharris ); 1189230557Sjimharris } 1190230557Sjimharris else 1191230557Sjimharris { 1192230557Sjimharris scic_sds_remote_device_post_request( 1193230557Sjimharris this_rnc->device, 1194230557Sjimharris SCU_CONTEXT_COMMAND_POST_RNC_32 1195230557Sjimharris ); 1196230557Sjimharris 1197230557Sjimharris if (this_rnc->device->is_direct_attached) 1198230557Sjimharris { 1199230557Sjimharris scic_sds_port_setup_transports( 1200230557Sjimharris this_rnc->device->owning_port, 1201230557Sjimharris this_rnc->remote_node_index 1202230557Sjimharris ); 1203230557Sjimharris } 1204230557Sjimharris } 1205230557Sjimharris} 1206230557Sjimharris 1207230557Sjimharris/** 1208230557Sjimharris* This method will update the RNC buffer and post the invalidate request. 1209230557Sjimharris* 1210230557Sjimharris* @param[in] this_rnc The remote node context object that is to be 1211230557Sjimharris* invalidated. 1212230557Sjimharris* 1213230557Sjimharris* @return none 1214230557Sjimharris*/ 1215230557Sjimharrisstatic 1216230557Sjimharrisvoid scic_sds_remote_node_context_invalidate_context_buffer( 1217230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 1218230557Sjimharris) 1219230557Sjimharris{ 1220230557Sjimharris SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer; 1221230557Sjimharris 1222230557Sjimharris rnc_buffer = scic_sds_controller_get_remote_node_context_buffer( 1223230557Sjimharris scic_sds_remote_device_get_controller(this_rnc->device), 1224230557Sjimharris this_rnc->remote_node_index 1225230557Sjimharris ); 1226230557Sjimharris 1227230557Sjimharris rnc_buffer->ssp.is_valid = FALSE; 1228230557Sjimharris 1229230557Sjimharris scic_sds_remote_device_post_request( 1230230557Sjimharris this_rnc->device, 1231230557Sjimharris SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE 1232230557Sjimharris ); 1233230557Sjimharris} 1234230557Sjimharris 1235230557Sjimharris//***************************************************************************** 1236230557Sjimharris//* REMOTE NODE CONTEXT STATE ENTER AND EXIT METHODS 1237230557Sjimharris//***************************************************************************** 1238230557Sjimharris 1239230557Sjimharris/** 1240230557Sjimharris* 1241230557Sjimharris* 1242230557Sjimharris* @param[in] object 1243230557Sjimharris*/ 1244230557Sjimharrisstatic 1245230557Sjimharrisvoid scic_sds_remote_node_context_initial_state_enter( 1246230557Sjimharris SCI_BASE_OBJECT_T * object 1247230557Sjimharris) 1248230557Sjimharris{ 1249230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1250230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1251230557Sjimharris 1252230557Sjimharris SET_STATE_HANDLER( 1253230557Sjimharris rnc, 1254230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1255230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE 1256230557Sjimharris ); 1257230557Sjimharris 1258230557Sjimharris // Check to see if we have gotten back to the initial state because someone 1259230557Sjimharris // requested to destroy the remote node context object. 1260230557Sjimharris if ( 1261230557Sjimharris rnc->state_machine.previous_state_id 1262230557Sjimharris == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE 1263230557Sjimharris ) 1264230557Sjimharris { 1265230557Sjimharris rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; 1266230557Sjimharris 1267230557Sjimharris scic_sds_remote_node_context_notify_user(rnc); 1268230557Sjimharris 1269230557Sjimharris // Since we are destroying the remote node context deinitialize the state logging 1270230557Sjimharris // should we resume the remote node context the state logging will be reinitialized 1271230557Sjimharris // on the resume handler. 1272230557Sjimharris scic_sds_remote_node_context_deinitialize_state_logging(rnc); 1273230557Sjimharris } 1274230557Sjimharris} 1275230557Sjimharris 1276230557Sjimharris/** 1277230557Sjimharris* 1278230557Sjimharris* 1279230557Sjimharris* @param[in] object 1280230557Sjimharris*/ 1281230557Sjimharrisstatic 1282230557Sjimharrisvoid scic_sds_remote_node_context_posting_state_enter( 1283230557Sjimharris SCI_BASE_OBJECT_T * object 1284230557Sjimharris) 1285230557Sjimharris{ 1286230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc; 1287230557Sjimharris this_rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1288230557Sjimharris 1289230557Sjimharris SET_STATE_HANDLER( 1290230557Sjimharris this_rnc, 1291230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1292230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE 1293230557Sjimharris ); 1294230557Sjimharris 1295230557Sjimharris scic_sds_remote_node_context_validate_context_buffer(this_rnc); 1296230557Sjimharris} 1297230557Sjimharris 1298230557Sjimharris/** 1299230557Sjimharris* 1300230557Sjimharris* 1301230557Sjimharris* @param[in] object 1302230557Sjimharris*/ 1303230557Sjimharrisstatic 1304230557Sjimharrisvoid scic_sds_remote_node_context_invalidating_state_enter( 1305230557Sjimharris SCI_BASE_OBJECT_T * object 1306230557Sjimharris) 1307230557Sjimharris{ 1308230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1309230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1310230557Sjimharris 1311230557Sjimharris SET_STATE_HANDLER( 1312230557Sjimharris rnc, 1313230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1314230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE 1315230557Sjimharris ); 1316230557Sjimharris 1317230557Sjimharris scic_sds_remote_node_context_invalidate_context_buffer(rnc); 1318230557Sjimharris} 1319230557Sjimharris 1320230557Sjimharris/** 1321230557Sjimharris* 1322230557Sjimharris* 1323230557Sjimharris* @param[in] object 1324230557Sjimharris*/ 1325230557Sjimharrisstatic 1326230557Sjimharrisvoid scic_sds_remote_node_context_resuming_state_enter( 1327230557Sjimharris SCI_BASE_OBJECT_T * object 1328230557Sjimharris) 1329230557Sjimharris{ 1330230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1331230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T protocols; 1332230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1333230557Sjimharris 1334230557Sjimharris SET_STATE_HANDLER( 1335230557Sjimharris rnc, 1336230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1337230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE 1338230557Sjimharris ); 1339230557Sjimharris 1340230557Sjimharris // For direct attached SATA devices we need to clear the TLCR 1341230557Sjimharris // NCQ to TCi tag mapping on the phy and in cases where we 1342230557Sjimharris // resume because of a target reset we also need to update 1343230557Sjimharris // the STPTLDARNI register with the RNi of the device 1344230557Sjimharris scic_remote_device_get_protocols(rnc->device, &protocols); 1345230557Sjimharris 1346230557Sjimharris if ( 1347230557Sjimharris (protocols.u.bits.attached_stp_target == 1) 1348230557Sjimharris && (rnc->device->is_direct_attached) 1349230557Sjimharris ) 1350230557Sjimharris { 1351230557Sjimharris scic_sds_port_setup_transports( 1352230557Sjimharris rnc->device->owning_port, rnc->remote_node_index 1353230557Sjimharris ); 1354230557Sjimharris } 1355230557Sjimharris 1356230557Sjimharris scic_sds_remote_device_post_request( 1357230557Sjimharris rnc->device, 1358230557Sjimharris SCU_CONTEXT_COMMAND_POST_RNC_RESUME 1359230557Sjimharris ); 1360230557Sjimharris} 1361230557Sjimharris 1362230557Sjimharris/** 1363230557Sjimharris* 1364230557Sjimharris* 1365230557Sjimharris* @param[in] object 1366230557Sjimharris*/ 1367230557Sjimharrisstatic 1368230557Sjimharrisvoid scic_sds_remote_node_context_ready_state_enter( 1369230557Sjimharris SCI_BASE_OBJECT_T * object 1370230557Sjimharris) 1371230557Sjimharris{ 1372230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1373230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1374230557Sjimharris 1375230557Sjimharris SET_STATE_HANDLER( 1376230557Sjimharris rnc, 1377230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1378230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE 1379230557Sjimharris ); 1380230557Sjimharris 1381230557Sjimharris rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; 1382230557Sjimharris 1383230557Sjimharris if (rnc->user_callback != NULL) 1384230557Sjimharris { 1385230557Sjimharris scic_sds_remote_node_context_notify_user(rnc); 1386230557Sjimharris } 1387230557Sjimharris} 1388230557Sjimharris 1389230557Sjimharris/** 1390230557Sjimharris* 1391230557Sjimharris* 1392230557Sjimharris* @param[in] object 1393230557Sjimharris*/ 1394230557Sjimharrisstatic 1395230557Sjimharrisvoid scic_sds_remote_node_context_tx_suspended_state_enter( 1396230557Sjimharris SCI_BASE_OBJECT_T * object 1397230557Sjimharris) 1398230557Sjimharris{ 1399230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1400230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1401230557Sjimharris 1402230557Sjimharris SET_STATE_HANDLER( 1403230557Sjimharris rnc, 1404230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1405230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE 1406230557Sjimharris ); 1407230557Sjimharris 1408230557Sjimharris scic_sds_remote_node_context_continue_state_transitions(rnc); 1409230557Sjimharris} 1410230557Sjimharris 1411230557Sjimharris/** 1412230557Sjimharris* 1413230557Sjimharris* 1414230557Sjimharris* @param[in] object 1415230557Sjimharris*/ 1416230557Sjimharrisstatic 1417230557Sjimharrisvoid scic_sds_remote_node_context_tx_rx_suspended_state_enter( 1418230557Sjimharris SCI_BASE_OBJECT_T * object 1419230557Sjimharris) 1420230557Sjimharris{ 1421230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1422230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1423230557Sjimharris 1424230557Sjimharris SET_STATE_HANDLER( 1425230557Sjimharris rnc, 1426230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1427230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE 1428230557Sjimharris ); 1429230557Sjimharris 1430230557Sjimharris scic_sds_remote_node_context_continue_state_transitions(rnc); 1431230557Sjimharris} 1432230557Sjimharris 1433230557Sjimharris/** 1434230557Sjimharris* 1435230557Sjimharris* 1436230557Sjimharris* @param[in] object 1437230557Sjimharris*/ 1438230557Sjimharrisstatic 1439230557Sjimharrisvoid scic_sds_remote_node_context_await_suspension_state_enter( 1440230557Sjimharris SCI_BASE_OBJECT_T * object 1441230557Sjimharris) 1442230557Sjimharris{ 1443230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc; 1444230557Sjimharris rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *)object; 1445230557Sjimharris 1446230557Sjimharris SET_STATE_HANDLER( 1447230557Sjimharris rnc, 1448230557Sjimharris scic_sds_remote_node_context_state_handler_table, 1449230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE 1450230557Sjimharris ); 1451230557Sjimharris} 1452230557Sjimharris 1453230557Sjimharris// --------------------------------------------------------------------------- 1454230557Sjimharris 1455230557Sjimharris SCI_BASE_STATE_T 1456230557Sjimharris scic_sds_remote_node_context_state_table[ 1457230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES] = 1458230557Sjimharris{ 1459230557Sjimharris { 1460230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE, 1461230557Sjimharris scic_sds_remote_node_context_initial_state_enter, 1462230557Sjimharris NULL 1463230557Sjimharris }, 1464230557Sjimharris { 1465230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE, 1466230557Sjimharris scic_sds_remote_node_context_posting_state_enter, 1467230557Sjimharris NULL 1468230557Sjimharris }, 1469230557Sjimharris { 1470230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE, 1471230557Sjimharris scic_sds_remote_node_context_invalidating_state_enter, 1472230557Sjimharris NULL 1473230557Sjimharris }, 1474230557Sjimharris { 1475230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE, 1476230557Sjimharris scic_sds_remote_node_context_resuming_state_enter, 1477230557Sjimharris NULL 1478230557Sjimharris }, 1479230557Sjimharris { 1480230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE, 1481230557Sjimharris scic_sds_remote_node_context_ready_state_enter, 1482230557Sjimharris NULL 1483230557Sjimharris }, 1484230557Sjimharris { 1485230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE, 1486230557Sjimharris scic_sds_remote_node_context_tx_suspended_state_enter, 1487230557Sjimharris NULL 1488230557Sjimharris }, 1489230557Sjimharris { 1490230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE, 1491230557Sjimharris scic_sds_remote_node_context_tx_rx_suspended_state_enter, 1492230557Sjimharris NULL 1493230557Sjimharris }, 1494230557Sjimharris { 1495230557Sjimharris SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE, 1496230557Sjimharris scic_sds_remote_node_context_await_suspension_state_enter, 1497230557Sjimharris NULL 1498230557Sjimharris } 1499230557Sjimharris}; 1500230557Sjimharris 1501