/** * @brief This routine is to allocate the memory for creating a smp phy object. * * @param[in] scif_controller handle to frame controller * * @return SCIF_SAS_SMP_PHY_T * An allocated space for smp phy. If failed to allocate, * return NULL. */ SCIF_SAS_SMP_PHY_T * scif_sas_controller_allocate_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_allocate_smp_phy(0x%x) enter\n", fw_controller )); if( !sci_fast_list_is_empty(&fw_controller->smp_phy_memory_list) ) { smp_phy = (SCIF_SAS_SMP_PHY_T *) sci_fast_list_remove_head(&fw_controller->smp_phy_memory_list); //clean the memory. memset((char*)smp_phy, 0, sizeof(SCIF_SAS_SMP_PHY_T) ); return smp_phy; } else return NULL; }
void isci_task_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, SCI_REMOTE_DEVICE_HANDLE_T remote_device, SCI_TASK_REQUEST_HANDLE_T task_request, SCI_TASK_STATUS completion_status) { struct ISCI_TASK_REQUEST *isci_task_request = (struct ISCI_TASK_REQUEST *)sci_object_get_association(task_request); struct ISCI_CONTROLLER *isci_controller = (struct ISCI_CONTROLLER *)sci_object_get_association(scif_controller); struct ISCI_REMOTE_DEVICE *isci_remote_device = (struct ISCI_REMOTE_DEVICE *)sci_object_get_association(remote_device); struct ISCI_REMOTE_DEVICE *pending_remote_device; BOOL retry_task = FALSE; union ccb *ccb = isci_task_request->ccb; isci_remote_device->is_resetting = FALSE; switch ((int)completion_status) { case SCI_TASK_SUCCESS: case SCI_TASK_FAILURE_RESPONSE_VALID: break; case SCI_TASK_FAILURE_INVALID_STATE: retry_task = TRUE; isci_log_message(0, "ISCI", "task failure (invalid state) - retrying\n"); break; case SCI_TASK_FAILURE_INSUFFICIENT_RESOURCES: retry_task = TRUE; isci_log_message(0, "ISCI", "task failure (insufficient resources) - retrying\n"); break; case SCI_FAILURE_TIMEOUT: if (isci_controller->fail_on_task_timeout) { retry_task = FALSE; isci_log_message(0, "ISCI", "task timeout - not retrying\n"); scif_cb_domain_device_removed(isci_controller, isci_remote_device->domain, isci_remote_device); } else { retry_task = TRUE; isci_log_message(0, "ISCI", "task timeout - retrying\n"); } break; case SCI_TASK_FAILURE: case SCI_TASK_FAILURE_UNSUPPORTED_PROTOCOL: case SCI_TASK_FAILURE_INVALID_TAG: case SCI_TASK_FAILURE_CONTROLLER_SPECIFIC_ERR: case SCI_TASK_FAILURE_TERMINATED: case SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE: isci_log_message(0, "ISCI", "unhandled task completion code 0x%x\n", completion_status); break; default: isci_log_message(0, "ISCI", "unhandled task completion code 0x%x\n", completion_status); break; } if (isci_controller->is_frozen == TRUE) { isci_controller->is_frozen = FALSE; xpt_release_simq(isci_controller->sim, TRUE); } sci_pool_put(isci_controller->request_pool, (struct ISCI_REQUEST *)isci_task_request); /* Make sure we release the device queue, since it may have been frozen * if someone tried to start an I/O while the task was in progress. */ isci_remote_device_release_device_queue(isci_remote_device); if (retry_task == TRUE) isci_remote_device_reset(isci_remote_device, ccb); else { pending_remote_device = sci_fast_list_remove_head( &isci_controller->pending_device_reset_list); if (pending_remote_device != NULL) { /* Any resets that were triggered from an XPT_RESET_DEV * CCB are never put in the pending list if the request * pool is empty - they are given back to CAM to be * requeued. So we will alawys pass NULL here, * denoting that there is no CCB associated with the * device reset. */ isci_remote_device_reset(pending_remote_device, NULL); } else if (ccb != NULL) { /* There was a CCB associated with this reset, so mark * it complete and return it to CAM. */ ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_REQ_CMP; xpt_done(ccb); } } }