/** * @brief This routine is to free the memory for a released smp phy. * * @param[in] fw_controller The framework controller, a smp phy is released * to its memory. * @param[in] fw_smp_phy The smp phy to be freed. * * @return none */ void scif_sas_controller_free_smp_phy( SCIF_SAS_CONTROLLER_T * fw_controller, SCIF_SAS_SMP_PHY_T * smp_phy ) { SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_controller), SCIF_LOG_OBJECT_CONTROLLER, "scif_controller_free_smp_phy(0x%x, 0x%x) enter\n", fw_controller, smp_phy )); //return the memory to the list. sci_fast_list_insert_tail( &fw_controller->smp_phy_memory_list, &smp_phy->list_element ); }
/** * @brief This routine constructs a smp phy object for an expander phy and insert * to owning expander device's smp_phy_list. * @param[in] this_smp_phy The memory space to store a phy * @param[in] owning_device The smp remote device that owns this smp phy. * @param[in] expander_phy_id The expander phy id for this_smp_phy. * @return None */ void scif_sas_smp_phy_construct( SCIF_SAS_SMP_PHY_T * this_smp_phy, SCIF_SAS_REMOTE_DEVICE_T * owning_device, U8 expander_phy_id ) { memset(this_smp_phy, 0, sizeof(SCIF_SAS_SMP_PHY_T)); this_smp_phy->phy_identifier = expander_phy_id; this_smp_phy->owning_device = owning_device; sci_fast_list_element_init((this_smp_phy), (&this_smp_phy->list_element)); //insert to owning device's smp phy list. sci_fast_list_insert_tail( (&owning_device->protocol_device.smp_device.smp_phy_list), (&this_smp_phy->list_element) ); }
void isci_remote_device_reset(struct ISCI_REMOTE_DEVICE *remote_device, union ccb *ccb) { struct ISCI_CONTROLLER *controller = remote_device->domain->controller; struct ISCI_REQUEST *request; struct ISCI_TASK_REQUEST *task_request; SCI_STATUS status; if (remote_device->is_resetting == TRUE) { /* device is already being reset, so return immediately */ return; } if (sci_pool_empty(controller->request_pool)) { /* No requests are available in our request pool. If this reset is tied * to a CCB, ask CAM to requeue it. Otherwise, we need to put it on our * pending device reset list, so that the reset will occur when a request * frees up. */ if (ccb == NULL) sci_fast_list_insert_tail( &controller->pending_device_reset_list, &remote_device->pending_device_reset_element); else { ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_REQUEUE_REQ; xpt_done(ccb); } return; } isci_log_message(0, "ISCI", "Sending reset to device on controller %d domain %d CAM index %d\n", controller->index, remote_device->domain->index, remote_device->index ); sci_pool_get(controller->request_pool, request); task_request = (struct ISCI_TASK_REQUEST *)request; task_request->parent.remote_device_handle = remote_device->sci_object; task_request->ccb = ccb; remote_device->is_resetting = TRUE; status = (SCI_STATUS) scif_task_request_construct( controller->scif_controller_handle, remote_device->sci_object, SCI_CONTROLLER_INVALID_IO_TAG, (void *)task_request, (void *)((char*)task_request + sizeof(struct ISCI_TASK_REQUEST)), &task_request->sci_object); if (status != SCI_SUCCESS) { isci_task_request_complete(controller->scif_controller_handle, remote_device->sci_object, task_request->sci_object, (SCI_TASK_STATUS)status); return; } status = (SCI_STATUS)scif_controller_start_task( controller->scif_controller_handle, remote_device->sci_object, task_request->sci_object, SCI_CONTROLLER_INVALID_IO_TAG); if (status != SCI_SUCCESS) { isci_task_request_complete( controller->scif_controller_handle, remote_device->sci_object, task_request->sci_object, (SCI_TASK_STATUS)status); return; } }
/** * @brief This method implements the actions taken when entering the * RESET state. * * @param[in] object This parameter specifies the base object for which * the state transition is occurring. This is cast into a * SCIF_SAS_CONTROLLER object in the method implementation. * * @return none */ static void scif_sas_controller_reset_state_enter( SCI_BASE_OBJECT_T * object ) { SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; U8 index; U16 smp_phy_index; SET_STATE_HANDLER( fw_controller, scif_sas_controller_state_handler_table, SCI_BASE_CONTROLLER_STATE_RESET ); scif_sas_high_priority_request_queue_construct( &fw_controller->hprq, sci_base_object_get_logger(fw_controller) ); // Construct the abstract element pool. This pool will store the // references to the framework's remote devices objects. sci_abstract_element_pool_construct( &fw_controller->free_remote_device_pool, fw_controller->remote_device_pool_elements, SCI_MAX_REMOTE_DEVICES ); // Construct the domain objects. for (index = 0; index < SCI_MAX_DOMAINS; index++) { scif_sas_domain_construct( &fw_controller->domains[index], index, fw_controller ); } //Initialize SMP PHY MEMORY LIST. sci_fast_list_init(&fw_controller->smp_phy_memory_list); for (smp_phy_index = 0; smp_phy_index < SCIF_SAS_SMP_PHY_COUNT; smp_phy_index++) { sci_fast_list_element_init( &fw_controller->smp_phy_array[smp_phy_index], &(fw_controller->smp_phy_array[smp_phy_index].list_element) ); //insert to owning device's smp phy list. sci_fast_list_insert_tail( (&(fw_controller->smp_phy_memory_list)), (&(fw_controller->smp_phy_array[smp_phy_index].list_element)) ); } scif_sas_controller_set_default_config_parameters(fw_controller); fw_controller->internal_request_entries = SCIF_SAS_MAX_INTERNAL_REQUEST_COUNT; //@Todo: may need to verify all timers are released. Including domain's //operation timer and all the Internal IO's timer. //take care of the lock. scif_cb_lock_disassociate(fw_controller, &fw_controller->hprq.lock); }