/** * @brief This method provides STOPPED state specific handling for * when the framework attempts to start the remote device. This * method attempts to transition the state machine into the * STARTING state. If this is unsuccessful, then there is a direct * transition into the FAILED state. * * @param[in] remote_device This parameter specifies the remote device * object for which the framework is attempting to start. * * @return This method returns an indication as to whether the start * operating began successfully. */ static SCI_STATUS scif_sas_remote_device_stopped_start_handler( SCI_BASE_REMOTE_DEVICE_T * remote_device ) { SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) remote_device; sci_base_state_machine_change_state( &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STARTING ); // Check to see if the state transition occurred without issue. if (sci_base_state_machine_get_state(&fw_device->parent.state_machine) == SCI_BASE_REMOTE_DEVICE_STATE_FAILED) { SCIF_LOG_WARNING(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "Domain:0x%x Device:0x%x Status:0x%x failed to start\n", fw_device->domain, fw_device, fw_device->operation_status )); } return fw_device->operation_status; }
/** * @brief This method provides default handling (i.e. returns an error); * for when the core issues a ready notification and such a * notification isn't supported. * * @param[in] remote_device This parameter specifies the remote device object * for which the notification has occured. * * @return none. */ void scif_sas_remote_device_default_ready_handler( SCIF_SAS_REMOTE_DEVICE_T * fw_device ) { SCIF_LOG_WARNING(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x State:0x%x invalid state to handle ready\n", fw_device, sci_base_state_machine_get_state(&fw_device->parent.state_machine) )); }
void sci_base_state_machine_observer_default_update( SCI_BASE_OBSERVER_T *this_observer, SCI_BASE_SUBJECT_T *the_subject ) { SCI_BASE_STATE_MACHINE_OBSERVER_T *state_machine_observer; state_machine_observer = (SCI_BASE_STATE_MACHINE_OBSERVER_T *)this_observer; state_machine_observer->subject_state = sci_base_state_machine_get_state((SCI_BASE_STATE_MACHINE_T *)the_subject); }
static SCI_STATUS scic_sds_remote_node_context_resuming_state_event_handler( struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, U32 event_code ) { SCI_STATUS status; if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) { status = SCI_SUCCESS; sci_base_state_machine_change_state( &this_rnc->state_machine, SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE ); } else { switch (scu_get_event_type(event_code)) { case SCU_EVENT_TYPE_RNC_SUSPEND_TX: case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: // We really dont care if the hardware is going to suspend // the device since it's being resumed anyway SCIC_LOG_INFO(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x was suspeneded by hardware while being resumed.\n", this_rnc )); status = SCI_SUCCESS; break; default: SCIC_LOG_WARNING(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n", this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) )); status = SCI_FAILURE; break; } } return status; }
/** * This method will return TRUE if the remote node context is in a READY state * otherwise it will return FALSE * * @param[in] this_rnc The state of the remote node context object to check. * * @return BOOL * @retval TRUE if the remote node context is in the ready state. * @retval FALSE if the remote node context is not in the ready state. */ BOOL scic_sds_remote_node_context_is_ready( SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc ) { U32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine); if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE) { return TRUE; } return FALSE; }
/** * @brief This method provides default handling (i.e. returns an error); * for when the core issues a stop completion notification and * such a notification isn't supported. * * @param[in] remote_device This parameter specifies the remote device object * for which the completion notification has occured. * @param[in] completion_status This parameter specifies the status * of the completion operation. * * @return none. */ void scif_sas_remote_device_default_stop_complete_handler( SCIF_SAS_REMOTE_DEVICE_T * fw_device, SCI_STATUS completion_status ) { SCIF_LOG_WARNING(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x State:0x%x invalid state to stop complete\n", fw_device, sci_base_state_machine_get_state(&fw_device->parent.state_machine) )); }
/** * @brief This method provides default handling (i.e. returns an error); * when there is an attempt to complete a reset to the remote device * from an invalid state. * * @param[in] remote_device This parameter specifies the remote device * object on which there is an attempt to fail the device. * * @return This method returns an indication that the fail transition is not * allowed. * @retval SCI_FAILURE_INVALID_STATE This value is always returned. */ SCI_STATUS scif_sas_remote_device_default_reset_complete_handler( SCI_BASE_REMOTE_DEVICE_T * remote_device ) { SCIF_LOG_WARNING(( sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x State:0x%x invalid state to complete reset.\n", remote_device, sci_base_state_machine_get_state( &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) )); return SCI_FAILURE_INVALID_STATE; }
/** * @brief This method provides DEFAULT handling for when the user * attempts to destruct the supplied IO request. * * @param[in] io_request This parameter specifies the IO request object * to be destructed. * * @return This method returns an indication that destruct operation is * not allowed. * @retval SCI_FAILURE_INVALID_STATE This value is always returned. */ SCI_STATUS scif_sas_io_request_default_destruct_handler( SCI_BASE_REQUEST_T * io_request ) { SCIF_LOG_ERROR(( sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request), SCIF_LOG_OBJECT_IO_REQUEST, "IoRequest:0x%x State:0x%x invalid state to destruct.\n", io_request, sci_base_state_machine_get_state( &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine) )); return SCI_FAILURE_INVALID_STATE; }
/** * @brief This method provides default handling (i.e. returns an error); * when a user attempts to start a task on a remote device and a * start task operation is not allowed. * * @param[in] remote_device This parameter specifies the remote device * object on which the user is attempting to perform a start * task operation. * @param[in] task_request This parameter specifies the task management * request to be started. * * @return This method returns an indication that start task operations * are not allowed. * @retval SCI_FAILURE_INVALID_STATE This value is always returned. */ SCI_STATUS scif_sas_remote_device_default_start_task_handler( SCI_BASE_REMOTE_DEVICE_T * remote_device, SCI_BASE_REQUEST_T * task_request ) { SCIF_LOG_WARNING(( sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT, "RemoteDevice:0x%x State:0x%x invalid state to start task\n", remote_device, sci_base_state_machine_get_state( &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) )); return SCI_FAILURE_INVALID_STATE; }
/** * @brief This method provides DEFAULT handling for when the user * attempts to destruct the supplied task request. * * @param[in] task_request This parameter specifies the task request object * to be destructed. * * @return This method returns an indication that destruct operation is * not allowed. * @retval SCI_FAILURE_INVALID_STATE This value is always returned. */ static SCI_STATUS scif_sas_task_request_default_destruct_handler( SCI_BASE_REQUEST_T * task_request ) { SCIF_LOG_ERROR(( sci_base_object_get_logger((SCIF_SAS_TASK_REQUEST_T *) task_request), SCIF_LOG_OBJECT_TASK_MANAGEMENT, "TaskRequest:0x%x State:0x%x invalid state to destruct.\n", task_request, sci_base_state_machine_get_state( &((SCIF_SAS_TASK_REQUEST_T *) task_request)->parent.parent.state_machine) )); return SCI_FAILURE_INVALID_STATE; }
static SCI_STATUS scic_sds_remote_node_context_default_event_handler( struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, U32 event_code ) { SCIC_LOG_WARNING(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x requested to process event 0x%x while in wrong state %d\n", this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) )); return SCI_FAILURE_INVALID_STATE; }
static SCI_STATUS scic_sds_remote_node_context_await_suspension_state_event_handler( struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, U32 event_code ) { SCI_STATUS status; switch (scu_get_event_type(event_code)) { case SCU_EVENT_TL_RNC_SUSPEND_TX: sci_base_state_machine_change_state( &this_rnc->state_machine, SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE ); this_rnc->suspension_code = scu_get_event_specifier(event_code); status = SCI_SUCCESS; break; case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: sci_base_state_machine_change_state( &this_rnc->state_machine, SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE ); this_rnc->suspension_code = scu_get_event_specifier(event_code); status = SCI_SUCCESS; break; default: SCIC_LOG_WARNING(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n", this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine) )); status = SCI_FAILURE; break; } return status; }
// --------------------------------------------------------------------------- static SCI_STATUS scic_sds_remote_node_context_reset_required_start_io_handler( struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, struct SCIC_SDS_REQUEST * the_request ) { SCIC_LOG_WARNING(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x requested to start io 0x%x while in wrong state %d\n", this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine) )); return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; }
/** * @brief This method provides default handling (i.e. returns an error); * when a user attempts to complete an IO on a remote device and a * complete IO operation is not allowed. * * @param[in] remote_device This parameter specifies the remote device * object on which the user is attempting to perform a start IO * operation. * @param[in] io_request This parameter specifies the IO request to be * started. * * @return This method returns an indication that complete IO operations * are not allowed. * @retval SCI_FAILURE_INVALID_STATE This value is always returned. */ SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler( SCI_BASE_REMOTE_DEVICE_T * remote_device, SCI_BASE_REQUEST_T * io_request, void * response_data, SCI_IO_STATUS completion_status ) { SCIF_LOG_WARNING(( sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n", remote_device, sci_base_state_machine_get_state( &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) )); return SCI_FAILURE_INVALID_STATE; }
static SCI_STATUS scic_sds_remote_node_context_default_resume_handler( SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, void * callback_parameter ) { SCIC_LOG_WARNING(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x requested to resume while in wrong state %d\n", this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine) )); return SCI_FAILURE_INVALID_STATE; }
/** * @brief This method provides handling of device start complete duing * UPDATING_PORT_WIDTH state. * * @param[in] remote_device This parameter specifies the remote device object * which is start complete. * * @return none. */ static void scif_sas_remote_device_updating_port_width_state_start_complete_handler( SCIF_SAS_REMOTE_DEVICE_T * fw_device, SCI_STATUS completion_status ) { SCIF_LOG_INFO(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x updating port width state start complete handler\n", fw_device, sci_base_state_machine_get_state(&fw_device->parent.state_machine) )); if ( fw_device->destination_state == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING ) { //if the destination state of this device change to STOPPING, no matter //whether we need to update the port width again, just make the device //go to the STOPPING state. sci_base_state_machine_change_state( &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING ); } else if ( scic_remote_device_get_port_width(fw_device->core_object) != fw_device->device_port_width && fw_device->device_port_width != 0) { scic_remote_device_stop( fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT ); } else { //Port width updating succeeds. Transfer to destination state. sci_base_state_machine_change_state( &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_READY ); } }
static SCI_STATUS scic_sds_remote_node_context_default_destruct_handler( SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc, SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, void * callback_parameter ) { SCIC_LOG_WARNING(( sci_base_object_get_logger(this_rnc->device), SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote Node Context 0x%x requested to stop while in unexpected state %d\n", this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine) )); // We have decided that the destruct request on the remote node context can not fail // since it is either in the initial/destroyed state or is can be destroyed. return SCI_SUCCESS; }
/** * @brief This method provides handling of device stop complete duing * UPDATING_PORT_WIDTH state. * * @param[in] remote_device This parameter specifies the remote device object * which is stop complete. * * @return none. */ static void scif_sas_remote_device_updating_port_width_state_stop_complete_handler( SCIF_SAS_REMOTE_DEVICE_T * fw_device, SCI_STATUS completion_status ) { SCIF_LOG_INFO(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x updating port width state stop complete handler\n", fw_device, sci_base_state_machine_get_state(&fw_device->parent.state_machine) )); if ( fw_device->destination_state == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING ) { //Device directly transits to STOPPED STATE from UPDATING_PORT_WIDTH state, fw_device->domain->device_start_count--; //if the destination state of this device change to STOPPING, no matter //whether we need to update the port width again, just make the device //go to the STOPPED state. sci_base_state_machine_change_state( &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPED ); } else { scic_remote_device_set_port_width( fw_device->core_object, fw_device->device_port_width ); //Device stop complete, means the RNC has been destructed. Now we need to //start core device so the RNC with updated port width will be posted. scic_remote_device_start( fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT); } }
/** * @brief This method will attempt to handle an operation timeout (i.e. * discovery or reset). * * @param[in] cookie This parameter specifies the domain in which the * timeout occurred. * * @return none */ static void scif_sas_domain_operation_timeout_handler( void * cookie ) { SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) cookie; U32 state; state = sci_base_state_machine_get_state(&fw_domain->parent.state_machine); // Based upon the state of the domain, we know whether we were in the // process of performing discovery or a reset. if (state == SCI_BASE_DOMAIN_STATE_DISCOVERING) { SCIF_LOG_WARNING(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN, "Domain:0x%x State:0x%x DISCOVER timeout!\n", fw_domain, state )); fw_domain->operation.status = SCI_FAILURE_TIMEOUT; //search all the smp devices in the domain and cancel their activities //if there is any outstanding activity remained. The smp devices will terminate //all the started internal IOs. scif_sas_domain_cancel_smp_activities(fw_domain); scif_sas_domain_continue_discover(fw_domain); } else { SCIF_LOG_ERROR(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN, "Domain:0x%x State:0x%x operation timeout in invalid state\n", fw_domain, state )); } }
/** * @brief This methods finds the first device that is in STOPPED state and its * connection_rate is still in SPINUP_HOLD(value 3). * * @param[in] fw_domain The framework domain object * * @return SCIF_SAS_REMOTE_DEVICE_T The device that is in SPINUP_HOLD or NULL. */ SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_device_in_spinup_hold( SCIF_SAS_DOMAIN_T * fw_domain ) { SCI_ABSTRACT_ELEMENT_T * current_element; SCIF_SAS_REMOTE_DEVICE_T * current_device; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN, "scif_sas_domain_find_device_in_spinup_hold(0x%x) enter\n", fw_domain )); //search throught domain's device list to find the first sata device on spinup_hold current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list); while (current_element != NULL ) { current_device = (SCIF_SAS_REMOTE_DEVICE_T *) sci_abstract_list_get_object(current_element); //We must get the next element before we remove the current //device. Or else, we will get wrong next_element, since the erased //element has been put into free pool. current_element = sci_abstract_list_get_next(current_element); if ( sci_base_state_machine_get_state(¤t_device->parent.state_machine) == SCI_BASE_REMOTE_DEVICE_STATE_STOPPED && scic_remote_device_get_connection_rate(current_device->core_object) == SCI_SATA_SPINUP_HOLD ) { return current_device; } } return NULL; }
/** * This is the function that is called when the state machine wants to notify * this observer that there has been a state change. * * @param[in] observer The state machine logger that is observing the state * machine. * @param[in] subject The state machine that is being observed. */ static void sci_base_state_machine_logger_update( SCI_BASE_OBSERVER_T *observer, SCI_BASE_SUBJECT_T *subject ) { SCI_BASE_STATE_MACHINE_LOGGER_T *this_observer; this_observer = (SCI_BASE_STATE_MACHINE_LOGGER_T *)observer; this_observer->log_function( sci_base_object_get_logger(this_observer->log_object), this_observer->log_mask, "%s 0x%08x %s has transitioned from %d to %d\n", this_observer->log_object_name, this_observer->log_object, this_observer->log_state_machine_name, this_observer->parent.subject_state, sci_base_state_machine_get_state((SCI_BASE_STATE_MACHINE_T *)subject) ); sci_base_state_machine_observer_default_update( &this_observer->parent.parent, subject ); }
/** * @brief This method provides handling (i.e. returns an error); * when a user attempts to stop a remote device during the updating * port width state, it will record the destination state for this * device to be STOPPING, instead of usually READY state. * * @param[in] remote_device This parameter specifies the remote device object * on which the user is attempting to perform a stop operation. * * @return This method always return SCI_SUCCESS. */ static SCI_STATUS scif_sas_remote_device_updating_port_width_state_stop_handler( SCI_BASE_REMOTE_DEVICE_T * remote_device ) { SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)remote_device; SCIF_LOG_INFO(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_REMOTE_DEVICE, "RemoteDevice:0x%x updating port width state stop handler\n", fw_device, sci_base_state_machine_get_state(&fw_device->parent.state_machine) )); //Can't stop the device right now. Remember the pending stopping request. //When exit the UPDATING_PORT_WIDTH state, we will check this variable //to decide which state to go. fw_device->destination_state = SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING; return SCI_SUCCESS; }
/** * This method will handle events received while the STP device is in the * ready command substate. * * @param [in] this_device This is the device object that is receiving the * event. * @param [in] event_code The event code to process. * * @return SCI_STATUS */ static SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_event_handler( SCIC_SDS_REMOTE_DEVICE_T * this_device, U32 event_code ) { SCI_STATUS status; status = scic_sds_remote_device_general_event_handler(this_device, event_code); switch (scu_get_event_code(event_code)) { case SCU_EVENT_TL_RNC_SUSPEND_TX: case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: /// @todo We need to decode and understand why the hardware suspended the device. /// The suspension reason was probably due to an SDB error FIS received. break; case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DATA_LEN_ERR: case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_OFFSET_ERR: case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DMASETUP_DIERR: case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_XFERCNT_ERR: case SCU_EVENT_TL_RNC_SUSPEND_TX_RX_DONE_PLD_LEN_ERR: this_device->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; sci_base_state_machine_change_state( &this_device->ready_substate_machine, SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR ); // We have a notification that the driver requested a suspend operation // this should not happen. SCIC_LOG_WARNING(( sci_base_object_get_logger(this_device), SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote device 0x%x received driver suspend event %x while in ncq ready substate %d\n", this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine) )); // Since we didn't expect to get here start the device again. status = scic_sds_remote_device_resume(this_device); break; case SCU_EVENT_POST_RCN_RELEASE: /// @todo Do we need to store the suspend state on the device? SCIC_LOG_INFO(( sci_base_object_get_logger(this_device), SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote device 0x%x received driver release event %x while in the ready substate %d\n", this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine) )); break; default: // Some other event just log it and continue SCIC_LOG_WARNING(( sci_base_object_get_logger(this_device), SCIC_LOG_OBJECT_STP_REMOTE_TARGET, "SCIC Remote device 0x%x received driver unexpected event %x while in the ready substate %d\n", this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine) )); status = SCI_FAILURE_INVALID_STATE; break; } return status; }