/** * @brief This method update the direct attached device port width. * * @param[in] fw_domain The framework domain object * @param[in] port The associated port object which recently has link up/down * event happened. * * @return none */ void scif_sas_domain_update_device_port_width( SCIF_SAS_DOMAIN_T * fw_domain, SCI_PORT_HANDLE_T port ) { SCIF_SAS_REMOTE_DEVICE_T * fw_device; SCIC_PORT_PROPERTIES_T properties; U8 new_port_width = 0; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN, "scif_sas_domain_update_device_port_width(0x%x, 0x%x) enter\n", fw_domain, port )); scic_port_get_properties(port, &properties); fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) scif_domain_get_device_by_sas_address( fw_domain, &properties.remote.sas_address ); // If the device already existed in the domain, it is a wide port SSP target, // we need to update its port width. if (fw_device != SCI_INVALID_HANDLE) { SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); if (dev_protocols.u.bits.attached_ssp_target) { //Get accurate port width from port's phy mask for a DA device. SCI_GET_BITS_SET_COUNT(properties.phy_mask, new_port_width); scif_sas_remote_device_update_port_width(fw_device, new_port_width); } } }
/** * @brief This method implements the actions taken when entering the * DISCOVERING state. This includes determining from which * state we entered. If we entered from stopping that some sort * of hot-remove of the port occurred. In the hot-remove case * all devices should be in the STOPPED state already and, as * a result, are removed from the domain with a notification sent * to the framework user. * * @note This method currently only handles hot-insert/hot-remove of * direct attached SSP devices. * * @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_discovering_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_DISCOVERING ); SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "scif_sas_domain_discovering_state_enter(0x%x) enter\n", fw_domain )); fw_domain->broadcast_change_count = 0; // Did the domain just go through a port not ready action? If it did, // then we will be entering from the STOPPED state. if (fw_domain->parent.state_machine.previous_state_id != SCI_BASE_DOMAIN_STATE_STOPPED) { SCIF_SAS_REMOTE_DEVICE_T * remote_device; SCIC_PORT_PROPERTIES_T properties; scic_port_get_properties(fw_domain->core_object, &properties); // If the device has not yet been added to the domain, then // inform the user that the device is new. remote_device = (SCIF_SAS_REMOTE_DEVICE_T *) scif_domain_get_device_by_sas_address( fw_domain, &properties.remote.sas_address ); if (remote_device == SCI_INVALID_HANDLE) { // simply notify the user of the new DA device and be done // with discovery. scif_cb_domain_da_device_added( fw_domain->controller, fw_domain, &properties.remote.sas_address, &properties.remote.protocols ); } else { if(properties.remote.protocols.u.bits.smp_target) //kick off the smp discover process. scif_sas_domain_start_smp_discover(fw_domain, remote_device); } } else //entered from STOPPED state. { SCI_ABSTRACT_ELEMENT_T * current_element = sci_abstract_list_get_front(&(fw_domain->remote_device_list) ); SCIF_SAS_REMOTE_DEVICE_T * fw_device; while (current_element != NULL) { fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) sci_abstract_list_get_object(current_element); ASSERT(fw_device->parent.state_machine.current_state_id == SCI_BASE_REMOTE_DEVICE_STATE_STOPPED); current_element = sci_abstract_list_get_next(current_element); SCIF_LOG_INFO(( sci_base_object_get_logger(fw_domain), SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "Controller:0x%x Domain:0x%x Device:0x%x removed\n", fw_domain->controller, fw_domain, fw_device )); // Notify the framework user of the device removal. scif_cb_domain_device_removed( fw_domain->controller, fw_domain, fw_device ); } ASSERT(fw_domain->request_list.element_count == 0); ASSERT(sci_abstract_list_size(&fw_domain->remote_device_list) == 0); sci_base_state_machine_change_state( &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_STARTING ); } }