/** * @brief This routine destructs a smp phy object for an expander phy and free the smp * phy to controller's smp phy memory. * @param[in] this_smp_phy The smp phy to be destructed. * * @return None */ void scif_sas_smp_phy_destruct( SCIF_SAS_SMP_PHY_T * this_smp_phy ) { SCIF_SAS_REMOTE_DEVICE_T * owning_device = this_smp_phy->owning_device; SCIF_SAS_CONTROLLER_T * fw_controller = owning_device->domain->controller; if ( ( this_smp_phy->attached_device_type == SMP_EDGE_EXPANDER_DEVICE || this_smp_phy->attached_device_type == SMP_FANOUT_EXPANDER_DEVICE) && this_smp_phy->u.attached_phy != NULL ) { //update the counterpart phy from the other smp phy list. this_smp_phy->u.attached_phy->attached_device_type = SMP_NO_DEVICE_ATTACHED; this_smp_phy->u.attached_phy->u.attached_phy = NULL; } //remove curr_smp_phy sci_fast_list_remove_element(&this_smp_phy->list_element); scif_sas_controller_free_smp_phy(fw_controller, this_smp_phy); }
/** * @brief This method retry the external smp request. * * @param[in] fw_device This parameter specifies the remote device for * which the internal IO request is destined. * @param[in] old_internal_io This parameter specifies the old smp request to be * retried. * * @return none. */ SCI_STATUS scif_sas_smp_external_request_retry( SCIF_SAS_IO_REQUEST_T * old_io ) { SCIF_SAS_REMOTE_DEVICE_T * fw_device = old_io->parent.device; SCIF_SAS_CONTROLLER_T * fw_controller; SCIF_SAS_IO_REQUEST_T * new_io; void * new_request_memory = NULL; U8 retry_count = old_io->retry_count; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, "scif_sas_smp_external_request_retry(0x%x) time %d!\n", old_io )); fw_controller = fw_device->domain->controller; // Before we construct new io using the same memory, we need to // remove the IO from the list of outstanding requests on the domain // so that we don't damage the domain's fast list of request. sci_fast_list_remove_element(&old_io->parent.list_element); switch (fw_device->protocol_device.smp_device.current_smp_request) { case SMP_FUNCTION_DISCOVER: //we are retrying an external io, we are going to reuse the //old io's memory. new_request_memory is same as old_io. new_request_memory = scif_sas_smp_request_construct_discover( fw_controller, fw_device, fw_device->protocol_device.smp_device.current_activity_phy_index, (void *)sci_object_get_association(old_io), (void *)old_io ); break; case SMP_FUNCTION_PHY_CONTROL: //Phy Control command always uses external io memory. new_request_memory = scif_sas_smp_request_construct_phy_control( fw_controller, fw_device, PHY_OPERATION_HARD_RESET, fw_device->protocol_device.smp_device.current_activity_phy_index, (void *)sci_object_get_association(old_io), (void *)old_io ); break; default: //unsupported case, TBD return SCI_FAILURE; } //end of switch //set the retry count to new built smp request. new_io = (SCIF_SAS_IO_REQUEST_T *) new_request_memory; new_io->retry_count = ++retry_count; //put into the high priority queue. sci_pool_put(fw_controller->hprq.pool, (POINTER_UINT) new_request_memory); //schedule the DPC to start new io. scif_cb_start_internal_io_task_schedule( fw_controller, scif_sas_controller_start_high_priority_io, fw_controller ); return SCI_SUCCESS; }