예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
/**
 * @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;
}
예제 #6
0
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;
}
예제 #7
0
파일: isci.c 프로젝트: tomtor/freebsd
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);
}
예제 #8
0
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;
}
예제 #9
0
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);
}
예제 #10
0
/**
 * @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;
}
예제 #11
0
/**
 * @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;
}
예제 #12
0
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;
}