/** * * * @param[in] this_device * @param[in] frame_index * * @return SCI_STATUS */ static SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_frame_handler( SCIC_SDS_REMOTE_DEVICE_T * this_device, U32 frame_index ) { SCI_STATUS status; SATA_FIS_HEADER_T * frame_header; status = scic_sds_unsolicited_frame_control_get_header( &(scic_sds_remote_device_get_controller(this_device)->uf_control), frame_index, (void **)&frame_header ); if (status == SCI_SUCCESS) { if ( (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS) && (frame_header->status & ATA_STATUS_REG_ERROR_BIT) ) { this_device->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; /** @todo Check sactive and complete associated IO if any. */ sci_base_state_machine_change_state( &this_device->ready_substate_machine, SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR ); } else if ( (frame_header->fis_type == SATA_FIS_TYPE_REGD2H) && (frame_header->status & ATA_STATUS_REG_ERROR_BIT) ) { // Some devices return D2H FIS when an NCQ error is detected. // Treat this like an SDB error FIS ready reason. 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 ); } else { status = SCI_FAILURE; } scic_sds_controller_release_frame( scic_sds_remote_device_get_controller(this_device), frame_index ); } return status; }
/** * * * @param[in] device This is the SCI base object which is cast into a * SCIC_SDS_REMOTE_DEVICE object. * * @return none */ static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter( SCI_BASE_OBJECT_T * device ) { SCIC_SDS_REMOTE_DEVICE_T * this_device; this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; SET_STATE_HANDLER( this_device, scic_sds_stp_remote_device_ready_substate_handler_table, SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR ); if(this_device->not_ready_reason == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) { scic_cb_remote_device_not_ready( scic_sds_remote_device_get_controller(this_device), this_device, this_device->not_ready_reason ); } }
/** * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method. This * method sets the ready cmd substate handlers and reports the device as ready. * * @param[in] object This is the SCI_BASE_OBJECT which is cast into a * SCIC_SDS_REMOTE_DEVICE. * * @return none */ static void scic_sds_smp_remote_device_ready_idle_substate_enter( SCI_BASE_OBJECT_T *object ) { SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; SET_STATE_HANDLER( this_device, scic_sds_smp_remote_device_ready_substate_handler_table, SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE ); scic_cb_remote_device_ready( scic_sds_remote_device_get_controller(this_device), this_device); }
/** * This method will update the RNC buffer and post the invalidate request. * * @param[in] this_rnc The remote node context object that is to be * invalidated. * * @return none */ static void scic_sds_remote_node_context_invalidate_context_buffer( SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc ) { SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer; rnc_buffer = scic_sds_controller_get_remote_node_context_buffer( scic_sds_remote_device_get_controller(this_rnc->device), this_rnc->remote_node_index ); rnc_buffer->ssp.is_valid = FALSE; scic_sds_remote_device_post_request( this_rnc->device, SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE ); }
static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler( void * user_cookie ) { SCIC_SDS_REMOTE_DEVICE_T * this_device; this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_cookie; // For NCQ operation we do not issue a // scic_cb_remote_device_not_ready(). As a result, avoid sending // the ready notification. if (this_device->ready_substate_machine.previous_state_id != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) { scic_cb_remote_device_ready( scic_sds_remote_device_get_controller(this_device), this_device ); } }
/** * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This * method sets the remote device objects ready cmd substate handlers, and notify * core user that the device is not ready. * * @param[in] object This is the SCI_BASE_OBJECT which is cast into a * SCIC_SDS_REMOTE_DEVICE. * * @return none */ static void scic_sds_smp_remote_device_ready_cmd_substate_enter( SCI_BASE_OBJECT_T *object ) { SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; ASSERT(this_device->working_request != NULL); SET_STATE_HANDLER( this_device, scic_sds_smp_remote_device_ready_substate_handler_table, SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD ); scic_cb_remote_device_not_ready( scic_sds_remote_device_get_controller(this_device), this_device, SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED ); }
/** * This method will mark the rnc buffer as being valid and post the request to * the hardware. * * @param[in] this_rnc The remote node context object that is to be * validated. * * @return none */ static void scic_sds_remote_node_context_validate_context_buffer( SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc ) { SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer; rnc_buffer = scic_sds_controller_get_remote_node_context_buffer( scic_sds_remote_device_get_controller(this_rnc->device), this_rnc->remote_node_index ); rnc_buffer->ssp.is_valid = TRUE; if ( !this_rnc->device->is_direct_attached && this_rnc->device->target_protocols.u.bits.attached_stp_target ) { scic_sds_remote_device_post_request( this_rnc->device, SCU_CONTEXT_COMMAND_POST_RNC_96 ); } else { scic_sds_remote_device_post_request( this_rnc->device, SCU_CONTEXT_COMMAND_POST_RNC_32 ); if (this_rnc->device->is_direct_attached) { scic_sds_port_setup_transports( this_rnc->device->owning_port, this_rnc->remote_node_index ); } } }
/** * This method will construct the RNC buffer for this remote device object. * * @param[in] this_device The remote device to use to construct the RNC * buffer. * @param[in] rnc The buffer into which the remote device data will be copied. * * @return none */ void scic_sds_remote_node_context_construct_buffer( SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc ) { SCU_REMOTE_NODE_CONTEXT_T * rnc; SCIC_SDS_CONTROLLER_T * the_controller; the_controller = scic_sds_remote_device_get_controller(this_rnc->device); rnc = scic_sds_controller_get_remote_node_context_buffer( the_controller, this_rnc->remote_node_index); memset( rnc, 0x00, sizeof(SCU_REMOTE_NODE_CONTEXT_T) * scic_sds_remote_device_node_count(this_rnc->device) ); rnc->ssp.remote_node_index = this_rnc->remote_node_index; rnc->ssp.remote_node_port_width = this_rnc->device->device_port_width; rnc->ssp.logical_port_index = scic_sds_remote_device_get_port_index(this_rnc->device); rnc->ssp.remote_sas_address_hi = SCIC_SWAP_DWORD(this_rnc->device->device_address.high); rnc->ssp.remote_sas_address_lo = SCIC_SWAP_DWORD(this_rnc->device->device_address.low); rnc->ssp.nexus_loss_timer_enable = TRUE; rnc->ssp.check_bit = FALSE; rnc->ssp.is_valid = FALSE; rnc->ssp.is_remote_node_context = TRUE; rnc->ssp.function_number = 0; rnc->ssp.arbitration_wait_time = 0; if ( this_rnc->device->target_protocols.u.bits.attached_sata_device || this_rnc->device->target_protocols.u.bits.attached_stp_target ) { rnc->ssp.connection_occupancy_timeout = the_controller->user_parameters.sds1.stp_max_occupancy_timeout; rnc->ssp.connection_inactivity_timeout = the_controller->user_parameters.sds1.stp_inactivity_timeout; } else { rnc->ssp.connection_occupancy_timeout = the_controller->user_parameters.sds1.ssp_max_occupancy_timeout; rnc->ssp.connection_inactivity_timeout = the_controller->user_parameters.sds1.ssp_inactivity_timeout; } rnc->ssp.initial_arbitration_wait_time = 0; // Open Address Frame Parameters rnc->ssp.oaf_connection_rate = this_rnc->device->connection_rate; rnc->ssp.oaf_features = 0; rnc->ssp.oaf_source_zone_group = 0; rnc->ssp.oaf_more_compatibility_features = 0; }