/** * @brief This method implements the actions taken when entering the * STOPPED state. * * @param[in] object This parameter specifies the base object for which * the state transition is occurring. This is cast into a * SCIF_SAS_DOMAIN object in the method implementation. * * @return none */ static void scif_sas_domain_stopped_state_enter( SCI_BASE_OBJECT_T * object ) { SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)object; SET_STATE_HANDLER( fw_domain, scif_sas_domain_state_handler_table, SCI_BASE_DOMAIN_STATE_STOPPED ); SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "scif_sas_domain_stopped_state_enter(0x%x) enter\n", fw_domain )); // A hot unplug of the direct attached device has occurred. Thus, // notify the user. Note, if the controller is not in READY state, // mostly likely the controller is in STOPPING or STOPPED state, // meaning the controller is in the process of stopping, we should // not call back to user in the middle of controller stopping. if(fw_domain->controller->parent.state_machine.current_state_id == SCI_BASE_CONTROLLER_STATE_READY) scif_cb_domain_change_notification(fw_domain->controller, fw_domain); }
void scic_cb_port_bc_change_primitive_recieved( SCI_CONTROLLER_HANDLE_T controller, SCI_PORT_HANDLE_T port, SCI_PHY_HANDLE_T phy ) { SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) sci_object_get_association(port); SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *) sci_object_get_association(controller); SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "scic_cb_port_bc_change_primitive_recieved(0x%x, 0x%x, 0x%x) enter\n", controller, port, phy )); if (fw_domain->broadcast_change_count == 0) { // Enable the BCN detection only if the bcn_count is zero. If bcn_count is // not zero at this time, we won't enable BCN detection since all non-zero // BCN_count means same to us. Furthermore, we avoid BCN storm by not // always enabling the BCN_detection. scic_port_enable_broadcast_change_notification(fw_domain->core_object); } fw_domain->broadcast_change_count++; //if there is smp device on this domain that is in the middle of discover //process or smp target reset, don't notify the driver layer. if( ! scif_sas_domain_is_in_smp_activity(fw_domain) ) // Notify the user that there is, potentially, a change to the domain. scif_cb_domain_change_notification(fw_controller, fw_domain); }
/** * @brief This method implements the actions taken when entering the * READY state. If the transition into this state came from: * - the STARTING state, then alert the user via a * scif_cb_domain_change_notification() that the domain * has at least 1 device ready for discovery. * - the DISCOVERING state, then alert the user that * discovery is complete via the * scif_cb_domain_discovery_complete() notification that * discovery is finished. * * @param[in] object This parameter specifies the base object for which * the state transition is occurring. This is cast into a * SCIF_SAS_DOMAIN object in the method implementation. * * @return none */ static void scif_sas_domain_ready_state_enter( SCI_BASE_OBJECT_T * object ) { SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)object; SET_STATE_HANDLER( fw_domain, scif_sas_domain_state_handler_table, SCI_BASE_DOMAIN_STATE_READY ); SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "scif_sas_domain_ready_state_enter(0x%x) enter\n", fw_domain )); if (fw_domain->parent.state_machine.previous_state_id == SCI_BASE_DOMAIN_STATE_STARTING) { scif_cb_domain_ready(fw_domain->controller, fw_domain); // Only indicate the domain change notification if the previous // state was the STARTING state. We issue the notification here // as opposed to exit of the STARTING state so that the appropriate // state handlers are in place should the user call // scif_domain_discover() from scif_cb_domain_change_notification() scif_cb_domain_change_notification(fw_domain->controller, fw_domain); } else if (fw_domain->parent.state_machine.previous_state_id == SCI_BASE_DOMAIN_STATE_DISCOVERING) { //if domain discovery timed out, we will NOT go back to discover even //the broadcast change count is not zero. Instead we finish the discovery //back to user. User can check the operation status and decide to //retry discover all over again. if (fw_domain->operation.status == SCI_FAILURE_TIMEOUT) fw_domain->broadcast_change_count = 0; // Check the broadcast change count to determine if discovery // is indeed complete. if (fw_domain->broadcast_change_count == 0) { scif_sas_domain_transition_from_discovering_state(fw_domain); scif_cb_domain_ready(fw_domain->controller, fw_domain); } else { // The broadcast change count indicates something my have // changed in the domain, while a discovery was ongoing. // Thus, we should start discovery over again. sci_base_state_machine_change_state( &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_DISCOVERING ); } // Enable the BCN because underneath hardware may disabled any further // BCN. scic_port_enable_broadcast_change_notification(fw_domain->core_object); } }