static void isci_io_request_construct(void *arg, bus_dma_segment_t *seg, int nseg, int error) { union ccb *ccb; struct ISCI_IO_REQUEST *io_request = (struct ISCI_IO_REQUEST *)arg; SCI_REMOTE_DEVICE_HANDLE_T *device = io_request->parent.remote_device_handle; SCI_STATUS status; io_request->num_segments = nseg; io_request->sge = seg; ccb = io_request->ccb; /* XXX More cleanup is needed here */ if ((nseg == 0) || (error != 0)) { ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; } status = scif_io_request_construct( io_request->parent.controller_handle, io_request->parent.remote_device_handle, SCI_CONTROLLER_INVALID_IO_TAG, (void *)io_request, (void *)((char*)io_request + sizeof(struct ISCI_IO_REQUEST)), &io_request->sci_object); if (status != SCI_SUCCESS) { isci_io_request_complete(io_request->parent.controller_handle, device, io_request, (SCI_IO_STATUS)status); return; } sci_object_set_association(io_request->sci_object, io_request); bus_dmamap_sync(io_request->parent.dma_tag, io_request->parent.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); status = (SCI_STATUS)scif_controller_start_io( io_request->parent.controller_handle, device, io_request->sci_object, SCI_CONTROLLER_INVALID_IO_TAG); if (status != SCI_SUCCESS) { isci_io_request_complete(io_request->parent.controller_handle, device, io_request, (SCI_IO_STATUS)status); return; } if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) callout_reset(&io_request->parent.timer, ccb->ccb_h.timeout, isci_io_request_timeout, io_request); }
/** * @brief This method continues a scif sas request. * * @param[in] fw_controller The framework controller * @param[in] fw_device The device that the IO request targets to. * @param[in] fw_request The IO request to be continued. * * @return Indicate if the internal io was successfully constructed. * @retval SCI_SUCCESS This value is returned if the internal io was * successfully continued. * @retval SCI_FAILURE This value is returned if the io was failed to * be continued. */ SCI_STATUS scif_sas_io_request_continue( SCIF_SAS_CONTROLLER_T * fw_controller, SCIF_SAS_REMOTE_DEVICE_T * fw_device, SCIF_SAS_REQUEST_T * fw_request ) { SCI_IO_REQUEST_HANDLE_T dummy_handle; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_request), SCIF_LOG_OBJECT_IO_REQUEST, "scif_sas_io_request_continue(0x%x, 0x%x, 0x%x) enter\n", fw_controller, fw_device, fw_request )); //complete this io request in framework and core. scif_controller_complete_io(fw_controller, fw_device, fw_request); //construct next command in the sequence using the same memory. We pass //a dummy pointer to let the framework user keep the pointer to this IO //request untouched. scif_sas_io_request_construct( fw_device, (SCIF_SAS_IO_REQUEST_T*)fw_request, SCI_CONTROLLER_INVALID_IO_TAG, (void *)sci_object_get_association(fw_request), &dummy_handle, FALSE ); //start the new constructed IO. return (SCI_STATUS)scif_controller_start_io( (SCI_CONTROLLER_HANDLE_T) fw_controller, (SCI_REMOTE_DEVICE_HANDLE_T) fw_device, (SCI_IO_REQUEST_HANDLE_T) fw_request, SCI_CONTROLLER_INVALID_IO_TAG ); }
void isci_io_request_execute_smp_io(union ccb *ccb, struct ISCI_CONTROLLER *controller) { SCI_STATUS status; target_id_t target_id = ccb->ccb_h.target_id; struct ISCI_REQUEST *request; struct ISCI_IO_REQUEST *io_request; SCI_REMOTE_DEVICE_HANDLE_T smp_device_handle; struct ISCI_REMOTE_DEVICE *end_device = controller->remote_device[target_id]; /* SMP commands are sent to an end device, because SMP devices are not * exposed to the kernel. It is our responsibility to use this method * to get the SMP device that contains the specified end device. If * the device is direct-attached, the handle will come back NULL, and * we'll just fail the SMP_IO with DEV_NOT_THERE. */ scif_remote_device_get_containing_device(end_device->sci_object, &smp_device_handle); if (smp_device_handle == NULL) { ccb->ccb_h.status &= ~CAM_SIM_QUEUED; ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_DEV_NOT_THERE; xpt_done(ccb); return; } if (sci_pool_empty(controller->request_pool)) { ccb->ccb_h.status &= ~CAM_SIM_QUEUED; ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_REQUEUE_REQ; xpt_freeze_simq(controller->sim, 1); controller->is_frozen = TRUE; xpt_done(ccb); return; } ASSERT(device->is_resetting == FALSE); sci_pool_get(controller->request_pool, request); io_request = (struct ISCI_IO_REQUEST *)request; io_request->ccb = ccb; io_request->parent.remote_device_handle = smp_device_handle; status = isci_smp_request_construct(io_request); if (status != SCI_SUCCESS) { isci_io_request_complete(controller->scif_controller_handle, smp_device_handle, io_request, (SCI_IO_STATUS)status); return; } sci_object_set_association(io_request->sci_object, io_request); status = (SCI_STATUS) scif_controller_start_io( controller->scif_controller_handle, smp_device_handle, io_request->sci_object, SCI_CONTROLLER_INVALID_IO_TAG); if (status != SCI_SUCCESS) { isci_io_request_complete(controller->scif_controller_handle, smp_device_handle, io_request, (SCI_IO_STATUS)status); return; } if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) callout_reset(&io_request->parent.timer, ccb->ccb_h.timeout, isci_io_request_timeout, request); }