SCI_STATUS scif_controller_construct( SCI_LIBRARY_HANDLE_T library, SCI_CONTROLLER_HANDLE_T controller, void * user_object ) { SCI_STATUS status = SCI_SUCCESS; SCIF_SAS_LIBRARY_T * fw_library = (SCIF_SAS_LIBRARY_T*) library; SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; // Validate the user supplied parameters. if ((library == SCI_INVALID_HANDLE) || (controller == SCI_INVALID_HANDLE)) return SCI_FAILURE_INVALID_PARAMETER_VALUE; SCIF_LOG_TRACE(( sci_base_object_get_logger(library), SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, "scif_controller_construct(0x%x, 0x%x) enter\n", library, controller )); // Construct the base controller. As part of constructing the base // controller we ask it to also manage the MDL iteration for the Core. sci_base_controller_construct( &fw_controller->parent, sci_base_object_get_logger(fw_library), scif_sas_controller_state_table, fw_controller->mdes, SCIF_SAS_MAX_MEMORY_DESCRIPTORS, sci_controller_get_memory_descriptor_list_handle(fw_controller->core_object) ); scif_sas_controller_initialize_state_logging(fw_controller); sci_object_set_association(fw_controller, user_object); status = scic_controller_construct( fw_library->core_object, fw_controller->core_object, fw_controller ); // If the core controller was successfully constructed, then // finish construction of the framework controller. if (status == SCI_SUCCESS) { // Set the association in the core controller to this framework // controller. sci_object_set_association( (SCI_OBJECT_HANDLE_T) fw_controller->core_object, fw_controller ); sci_base_state_machine_change_state( &fw_controller->parent.state_machine, SCI_BASE_CONTROLLER_STATE_RESET ); } return status; }
SCI_STATUS scif_io_request_construct_with_core ( SCI_CONTROLLER_HANDLE_T scif_controller, SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, void * scic_io_request, void * user_io_request_object, void * io_request_memory, SCI_IO_REQUEST_HANDLE_T * scif_io_request ) { SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) io_request_memory; SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) scif_remote_device; SCI_STATUS status = SCI_SUCCESS; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_IO_REQUEST, "scif_io_request_construct_pass_through(0x%x, 0x%x, 0x%x, 0x%x) enter\n", scif_remote_device, user_io_request_object, io_request_memory, scif_io_request )); // Initialize the users handle to the framework IO request. *scif_io_request = fw_io; // Construct the parent object first in order to ensure logging can // function. scif_sas_request_construct( &fw_io->parent, fw_device, sci_base_object_get_logger(fw_device), scif_sas_io_request_state_table ); fw_io->parent.core_object = scic_io_request; //set association sci_object_set_association(fw_io, user_io_request_object); sci_object_set_association(fw_io->parent.core_object, fw_io); sci_base_state_machine_logger_initialize( &fw_io->parent.parent.state_machine_logger, &fw_io->parent.parent.state_machine, &fw_io->parent.parent.parent, scif_cb_logger_log_states, "SCIF_IO_REQUEST_T", "base_state_machine", SCIF_LOG_OBJECT_IO_REQUEST ); return status; }
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); }
void isci_controller_construct(struct ISCI_CONTROLLER *controller, struct isci_softc *isci) { SCI_CONTROLLER_HANDLE_T scif_controller_handle; scif_library_allocate_controller(isci->sci_library_handle, &scif_controller_handle); scif_controller_construct(isci->sci_library_handle, scif_controller_handle, NULL); controller->isci = isci; controller->scif_controller_handle = scif_controller_handle; /* This allows us to later use * sci_object_get_association(scif_controller_handle) * inside of a callback routine to get our struct ISCI_CONTROLLER object */ sci_object_set_association(scif_controller_handle, (void *)controller); controller->is_started = FALSE; controller->is_frozen = FALSE; controller->release_queued_ccbs = FALSE; controller->sim = NULL; controller->initial_discovery_mask = 0; sci_fast_list_init(&controller->pending_device_reset_list); mtx_init(&controller->lock, "isci", NULL, MTX_DEF); uint32_t domain_index; for(domain_index = 0; domain_index < SCI_MAX_DOMAINS; domain_index++) { isci_domain_construct( &controller->domain[domain_index], domain_index, controller); } controller->timer_memory = malloc( sizeof(struct ISCI_TIMER) * SCI_MAX_TIMERS, M_ISCI, M_NOWAIT | M_ZERO); sci_pool_initialize(controller->timer_pool); struct ISCI_TIMER *timer = (struct ISCI_TIMER *) controller->timer_memory; for ( int i = 0; i < SCI_MAX_TIMERS; i++ ) { sci_pool_put(controller->timer_pool, timer++); } sci_pool_initialize(controller->unmap_buffer_pool); }
/** * @brief This method constructs the framework's SAS domain object. During * the construction process a linkage to the corresponding core port * object. * * @param[in] domain This parameter specifies the domain object to be * constructed. * @param[in] domain_id This parameter specifies the ID for the domain * object. * @param[in] fw_controller This parameter specifies the controller managing * the domain being constructed. * * @return none */ void scif_sas_domain_construct( SCIF_SAS_DOMAIN_T * fw_domain, U8 domain_id, SCIF_SAS_CONTROLLER_T * fw_controller ) { SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_controller), SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_INITIALIZATION, "scif_sas_domain_construct(0x%x, 0x%x, 0x%x) enter\n", fw_domain, domain_id, fw_controller )); sci_base_domain_construct( &fw_domain->parent, sci_base_object_get_logger(fw_controller), scif_sas_domain_state_table ); scif_sas_domain_initialize_state_logging(fw_domain); sci_abstract_list_construct( &fw_domain->remote_device_list, &fw_controller->free_remote_device_pool ); // Retrieve the core's port object that directly corresponds to this // domain. scic_controller_get_port_handle( fw_controller->core_object, domain_id, &fw_domain->core_object ); // Set the association in the core port to this framework domain object. sci_object_set_association( (SCI_OBJECT_HANDLE_T) fw_domain->core_object, fw_domain ); sci_fast_list_init(&fw_domain->request_list); fw_domain->operation.timer = NULL; fw_domain->is_port_ready = FALSE; fw_domain->device_start_count = 0; fw_domain->controller = fw_controller; fw_domain->operation.status = SCI_SUCCESS; fw_domain->is_config_route_table_needed = FALSE; }
SCI_LIBRARY_HANDLE_T scif_library_construct( void * library_memory, U8 max_controller_count ) { SCI_STATUS status; SCIF_SAS_LIBRARY_T * fw_library = (SCIF_SAS_LIBRARY_T *) library_memory; // Just clear out the memory of the structure to be safe. memset(fw_library, 0, scif_library_get_object_size(max_controller_count)); // Invoke the parent object constructor. SCI_BASE_LIBRARY_CONSTRUCT(fw_library, &fw_library->parent, max_controller_count, struct SCIF_SAS_CONTROLLER, status); // The memory for the framework controller objects start immediately // after the library object. fw_library->controllers = (SCIF_SAS_CONTROLLER_T*) ((U8*)library_memory + sizeof(SCIF_SAS_LIBRARY_T)); // Construct the core library. fw_library->core_object = scic_library_construct( (U8 *)library_memory + SCIF_LIBRARY_SIZE(max_controller_count), max_controller_count ); // Ensure construction completed successfully for the core. if (fw_library->core_object != SCI_INVALID_HANDLE) { // Set the association in the core library to this framework library. sci_object_set_association( (SCI_OBJECT_HANDLE_T) fw_library->core_object, (void *) fw_library ); return fw_library; } return SCI_INVALID_HANDLE; }
int isci_initialize(struct isci_softc *isci) { int error; uint32_t status = 0; uint32_t library_object_size; uint32_t verbosity_mask; uint32_t scic_log_object_mask; uint32_t scif_log_object_mask; uint8_t *header_buffer; library_object_size = scif_library_get_object_size(SCI_MAX_CONTROLLERS); isci->sci_library_memory = malloc(library_object_size, M_ISCI, M_NOWAIT | M_ZERO ); isci->sci_library_handle = scif_library_construct( isci->sci_library_memory, SCI_MAX_CONTROLLERS); sci_object_set_association( isci->sci_library_handle, (void *)isci); verbosity_mask = (1<<SCI_LOG_VERBOSITY_ERROR) | (1<<SCI_LOG_VERBOSITY_WARNING) | (1<<SCI_LOG_VERBOSITY_INFO) | (1<<SCI_LOG_VERBOSITY_TRACE); scic_log_object_mask = 0xFFFFFFFF; scic_log_object_mask &= ~SCIC_LOG_OBJECT_COMPLETION_QUEUE; scic_log_object_mask &= ~SCIC_LOG_OBJECT_SSP_IO_REQUEST; scic_log_object_mask &= ~SCIC_LOG_OBJECT_STP_IO_REQUEST; scic_log_object_mask &= ~SCIC_LOG_OBJECT_SMP_IO_REQUEST; scic_log_object_mask &= ~SCIC_LOG_OBJECT_CONTROLLER; scif_log_object_mask = 0xFFFFFFFF; scif_log_object_mask &= ~SCIF_LOG_OBJECT_CONTROLLER; scif_log_object_mask &= ~SCIF_LOG_OBJECT_IO_REQUEST; TUNABLE_INT_FETCH("hw.isci.debug_level", &g_isci_debug_level); sci_logger_enable(sci_object_get_logger(isci->sci_library_handle), scif_log_object_mask, verbosity_mask); sci_logger_enable(sci_object_get_logger( scif_library_get_scic_handle(isci->sci_library_handle)), scic_log_object_mask, verbosity_mask); header_buffer = (uint8_t *)&isci->pci_common_header; for (uint8_t i = 0; i < sizeof(isci->pci_common_header); i++) header_buffer[i] = pci_read_config(isci->device, i, 1); scic_library_set_pci_info( scif_library_get_scic_handle(isci->sci_library_handle), &isci->pci_common_header); isci->oem_parameters_found = FALSE; isci_get_oem_parameters(isci); /* trigger interrupt if 32 completions occur before timeout expires */ isci->coalesce_number = 32; /* trigger interrupt if 2 microseconds elapse after a completion occurs, * regardless if "coalesce_number" completions have occurred */ isci->coalesce_timeout = 2; isci->controller_count = scic_library_get_pci_device_controller_count( scif_library_get_scic_handle(isci->sci_library_handle)); for (int index = 0; index < isci->controller_count; index++) { struct ISCI_CONTROLLER *controller = &isci->controllers[index]; SCI_CONTROLLER_HANDLE_T scif_controller_handle; controller->index = index; isci_controller_construct(controller, isci); scif_controller_handle = controller->scif_controller_handle; status = isci_controller_initialize(controller); if(status != SCI_SUCCESS) { isci_log_message(0, "ISCI", "isci_controller_initialize FAILED: %x\n", status); return (status); } error = isci_controller_allocate_memory(controller); if (error != 0) return (error); scif_controller_set_interrupt_coalescence( scif_controller_handle, isci->coalesce_number, isci->coalesce_timeout); } /* FreeBSD provides us a hook to ensure we get a chance to start * our controllers and complete initial domain discovery before * it searches for the boot device. Once we're done, we'll * disestablish the hook, signaling the kernel that is can proceed * with the boot process. */ isci->config_hook.ich_func = &isci_controller_start; isci->config_hook.ich_arg = &isci->controllers[0]; if (config_intrhook_establish(&isci->config_hook) != 0) isci_log_message(0, "ISCI", "config_intrhook_establish failed!\n"); return (status); }
static SCI_STATUS scif_sas_task_request_generic_construct( SCI_CONTROLLER_HANDLE_T scif_controller, SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, U16 io_tag, void * user_task_request_object, void * task_request_memory, SCI_TASK_REQUEST_HANDLE_T * scif_task_request, U8 task_function ) { SCI_STATUS status; SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) scif_controller; SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*) task_request_memory; SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) scif_remote_device; U8 * core_request_memory; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_controller), SCIF_LOG_OBJECT_TASK_MANAGEMENT, "scif_task_request_construct(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", scif_controller, scif_remote_device, io_tag, user_task_request_object, task_request_memory, scif_task_request )); // Initialize the user's handle to the framework task request. *scif_task_request = fw_task; // initialize affected request count fw_task->affected_request_count = 0; fw_task->io_tag_to_manage = SCI_CONTROLLER_INVALID_IO_TAG; fw_task->function = task_function; if (task_function == SCI_SAS_HARD_RESET ) { if (fw_device->containing_device != NULL ) {// Target Reset is for an expander attached device, // go down to construct smp Phy Control request. scif_sas_smp_request_construct_phy_control( fw_controller, fw_device->containing_device, PHY_OPERATION_HARD_RESET, fw_device->expander_phy_identifier, user_task_request_object, task_request_memory ); } else { scif_sas_request_construct( &fw_task->parent, fw_device, sci_base_object_get_logger(fw_controller), scif_sas_task_request_state_table ); // If target reset is for a DA device, don't build task at all. // Just set object association. sci_object_set_association(fw_task, user_task_request_object); } return SCI_SUCCESS; } // Construct the parent object first in order to ensure logging can // function. scif_sas_request_construct( &fw_task->parent, fw_device, sci_base_object_get_logger(fw_controller), scif_sas_task_request_state_table ); core_request_memory = (U8 *)task_request_memory + sizeof(SCIF_SAS_TASK_REQUEST_T); status = scic_task_request_construct( fw_controller->core_object, fw_device->core_object, io_tag, fw_task, core_request_memory, &fw_task->parent.core_object ); if (status == SCI_SUCCESS) { SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; // These associations must be set early for the core io request // object construction to complete correctly as there will be // callbacks into the user driver framework during core construction sci_object_set_association(fw_task, user_task_request_object); sci_object_set_association(fw_task->parent.core_object, fw_task); // Perform protocol specific core IO request construction. scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); if (dev_protocols.u.bits.attached_ssp_target) status = scic_task_request_construct_ssp(fw_task->parent.core_object); else if (dev_protocols.u.bits.attached_stp_target) status = scif_sas_stp_task_request_construct(fw_task); else status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; if (status == SCI_SUCCESS) { sci_base_state_machine_logger_initialize( &fw_task->parent.parent.state_machine_logger, &fw_task->parent.parent.state_machine, &fw_task->parent.parent.parent, scif_cb_logger_log_states, "SCIF_SAS_TASK_REQUEST_T", "base_state_machine", SCIF_LOG_OBJECT_TASK_MANAGEMENT ); } else { SCIF_LOG_WARNING(( sci_base_object_get_logger(fw_task), SCIF_LOG_OBJECT_TASK_MANAGEMENT, "Device:0x%x TaskRequest:0x%x Function:0x%x construct failed\n", fw_device, fw_task, scif_sas_task_request_get_function(fw_task) )); } } return status; }
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); }
/** * @brief This method constructs an scif sas smp request. * * @param[in] fw_controller The framework controller * @param[in] fw_device The smp device that the smp request targets to. * @param[in] fw_io_memory The memory space for the smp request. * @param[in] core_io_memory The memory space for the core request. * @param[in] io_tag The io tag for the internl io to be constructed. * @param[in] smp_command A pointer to the smp request data structure according * to SAS protocol. * * @return Indicate if the internal io was successfully constructed. * @retval SCI_SUCCESS This value is returned if the internal io was * successfully constructed. * @retval SCI_FAILURE This value is returned if the internal io was failed to * be constructed. */ SCI_STATUS scif_sas_io_request_construct_smp( SCIF_SAS_CONTROLLER_T * fw_controller, SCIF_SAS_REMOTE_DEVICE_T * fw_device, void * fw_io_memory, void * core_io_memory, U16 io_tag, SMP_REQUEST_T * smp_command, void * user_request_object ) { SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)fw_io_memory; SCI_STATUS status = SCI_SUCCESS; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_IO_REQUEST, "scif_sas_io_request_construct_smp(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", fw_controller, fw_device, fw_io_memory, core_io_memory, io_tag, smp_command, user_request_object )); // Construct the parent object first in order to ensure logging can // function. scif_sas_request_construct( &fw_io->parent, fw_device, sci_base_object_get_logger(fw_controller), scif_sas_io_request_state_table ); status = scic_io_request_construct( fw_device->domain->controller->core_object, fw_device->core_object, io_tag, (void*)fw_io, (U8 *)core_io_memory, &fw_io->parent.core_object ); if (status == SCI_SUCCESS) { //set object association. sci_object_set_association(fw_io, user_request_object); sci_object_set_association(fw_io->parent.core_object, fw_io); scif_sas_smp_request_construct(&fw_io->parent, smp_command); fw_io->parent.is_high_priority = TRUE; sci_base_state_machine_logger_initialize( &fw_io->parent.parent.state_machine_logger, &fw_io->parent.parent.state_machine, &fw_io->parent.parent.parent, scif_cb_logger_log_states, "SCIF_IO_REQUEST_T", "base_state_machine", SCIF_LOG_OBJECT_IO_REQUEST ); } return status; }
/** * @brief This method represents common functionality for the * scif_io_request_construct() and scif_sas_io_request_continue() * methods. * * @return This method returns an indication as to whether the * construction succeeded. */ static SCI_STATUS scif_sas_io_request_construct( SCIF_SAS_REMOTE_DEVICE_T * fw_device, SCIF_SAS_IO_REQUEST_T * fw_io, U16 io_tag, void * user_io_request_object, SCI_IO_REQUEST_HANDLE_T * scif_io_request, BOOL is_initial_construction ) { SCI_STATUS status; SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); //Currently, all the io requests sent to smp target are internal. //so we fail all the external io toward to it. //Todo: is there a better way to handle external io to smp target? if (dev_protocols.u.bits.attached_smp_target) return SCI_FAILURE_INVALID_REMOTE_DEVICE; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_IO_REQUEST, "scif_sas_io_request_construct(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x) enter\n", fw_device, fw_io, io_tag, user_io_request_object, scif_io_request, is_initial_construction )); // Initialize the users handle to the framework IO request. *scif_io_request = fw_io; // Construct the parent object first in order to ensure logging can // function. scif_sas_request_construct( &fw_io->parent, fw_device, sci_base_object_get_logger(fw_device), scif_sas_io_request_state_table ); status = scic_io_request_construct( fw_device->domain->controller->core_object, fw_device->core_object, io_tag, fw_io, ((U8 *)fw_io) + sizeof(SCIF_SAS_IO_REQUEST_T), &fw_io->parent.core_object ); if (status == SCI_SUCCESS) { // These associations must be set early for the core io request // object construction to complete correctly as there will be // callbacks into the user driver framework during core construction sci_object_set_association(fw_io, user_io_request_object); sci_object_set_association(fw_io->parent.core_object, fw_io); // Perform protocol specific core IO request construction. if (dev_protocols.u.bits.attached_ssp_target) status = scic_io_request_construct_basic_ssp(fw_io->parent.core_object); else if (dev_protocols.u.bits.attached_stp_target) { if (is_initial_construction == TRUE) sati_sequence_construct(&fw_io->parent.stp.sequence); #if !defined(DISABLE_ATAPI) if (!scic_remote_device_is_atapi(fw_device->core_object)) { #endif status = scif_sas_stp_io_request_construct(fw_io); #if !defined(DISABLE_ATAPI) } else status = scif_sas_stp_packet_io_request_construct(fw_io); #endif } sci_base_state_machine_logger_initialize( &fw_io->parent.parent.state_machine_logger, &fw_io->parent.parent.state_machine, &fw_io->parent.parent.parent, scif_cb_logger_log_states, "SCIF_IO_REQUEST_T", "base_state_machine", SCIF_LOG_OBJECT_IO_REQUEST ); } return status; }
SCI_STATUS scif_request_construct( SCI_CONTROLLER_HANDLE_T scif_controller, SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, U16 io_tag, void * user_io_request_object, void * io_request_memory, SCI_IO_REQUEST_HANDLE_T * scif_io_request ) { SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) io_request_memory; SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) scif_remote_device; SCI_STATUS status; SCIF_LOG_TRACE(( sci_base_object_get_logger(fw_device), SCIF_LOG_OBJECT_IO_REQUEST, "scif_io_request_construct(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", scif_controller, scif_remote_device, io_tag, user_io_request_object, io_request_memory, scif_io_request )); // Step 1: Create the scif io request. // Initialize the users handle to the framework IO request. *scif_io_request = fw_io; // Construct the parent object first in order to ensure logging can // function. scif_sas_request_construct( &fw_io->parent, fw_device, sci_base_object_get_logger(fw_device), scif_sas_io_request_state_table ); status = scic_io_request_construct( (void *) ((SCIF_SAS_CONTROLLER_T *)scif_controller)->core_object, (void *) fw_device->core_object, io_tag, fw_io, (U8 *)io_request_memory + sizeof(SCIF_SAS_IO_REQUEST_T), &fw_io->parent.core_object ); if (status == SCI_SUCCESS) { // These associations must be set early for the core io request // object construction to complete correctly as there will be // callbacks into the user driver framework during core construction sci_object_set_association(fw_io, user_io_request_object); sci_object_set_association(fw_io->parent.core_object, fw_io); sci_base_state_machine_logger_initialize( &fw_io->parent.parent.state_machine_logger, &fw_io->parent.parent.state_machine, &fw_io->parent.parent.parent, scif_cb_logger_log_states, "SCIF_IO_REQUEST_T", "base_state_machine", SCIF_LOG_OBJECT_IO_REQUEST ); } return status; }