FreeBSD/sys/dev/isci/scil/scif_sas_controller_state_handlers.c
/**
 * @brief This method provides common handling for several states
 *        when a user attempts to start an internal request.
 *
 * @param[in]  controller This parameter specifies the controller object
 *             on which the user is attempting to perform a start IO
 *             operation.
 * @param[in]  remote_device This parameter specifies the remote deivce
 *             object on which the user is attempting to perform a start IO
 *             operation.
 * @param[in]  io_request This parameter specifies the IO request to be
 *             started.
 * @param[in]  io_tag This parameter specifies the optional allocated
 *             IO tag.  Please reference scif_controller_start_io() for
 *             more information.
 *
 * @return This method returns an indication of whether the start IO
 *         operation succeeded.
 * @retval SCI_SUCCESS This value is returned when the start IO operation
 *         begins successfully.
 */
@brief This method provides common handling for several states
when a user attempts to start an internal request.

@param[in]  controller This parameter specifies the controller object
on which the user is attempting to perform a start IO
operation.
@param[in]  remote_device This parameter specifies the remote deivce
object on which the user is attempting to perform a start IO
operation.
@param[in]  io_request This parameter specifies the IO request to be
started.
@param[in]  io_tag This parameter specifies the optional allocated
IO tag.  Please reference scif_controller_start_io() for
more information.

@return This method returns an indication of whether the start IO
operation succeeded.
@retval SCI_SUCCESS This value is returned when the start IO operation
begins successfully.
@brief This method provides common handling for several states when a user attempts to start an internal request . @param [ in ] controller This parameter specifies the controller object on which the user is attempting to perform a start IO operation . @param [ in ] remote_device This parameter specifies the remote deivce object on which the user is attempting to perform a start IO operation . @param [ in ] io_request This parameter specifies the IO request to be started . @param [ in ] io_tag This parameter specifies the optional allocated IO tag . Please reference scif_controller_start_io () for more information . @return This method returns an indication of whether the start IO operation succeeded . @retval SCI_SUCCESS This value is returned when the start IO operation begins successfully .
static
SCI_STATUS scif_sas_controller_common_start_high_priority_io_handler(
   SCI_BASE_CONTROLLER_T    * controller,
   SCI_BASE_REMOTE_DEVICE_T * remote_device,
   SCI_BASE_REQUEST_T       * io_request,
   U16                        io_tag
)
{
   SCI_STATUS                status;
   SCIF_SAS_IO_REQUEST_T    *fw_io         = (SCIF_SAS_IO_REQUEST_T*)io_request;
   SCIF_SAS_CONTROLLER_T    *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
   SCIF_SAS_REMOTE_DEVICE_T *fw_device     = (SCIF_SAS_REMOTE_DEVICE_T*)
                                             remote_device;
   status = fw_device->domain->state_handlers->start_high_priority_io_handler(
               &fw_device->domain->parent, remote_device, io_request
            );
   if (status == SCI_SUCCESS)
   {
      status = (SCI_STATUS)scic_controller_start_io(
                  fw_controller->core_object,
                  fw_device->core_object,
                  fw_io->parent.core_object,
                  io_tag
               );
      if (status == SCI_SUCCESS)
      {
         sci_base_state_machine_change_state(
            &io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED
         );
      }
      else
      {
         fw_device->domain->state_handlers->complete_io_handler(
            &fw_device->domain->parent, remote_device, io_request
         );
         fw_io->parent.state_handlers->complete_handler(io_request);
         SCIF_LOG_WARNING((
            sci_base_object_get_logger(fw_controller),
            SCIF_LOG_OBJECT_CONTROLLER,
            "Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n",
            fw_controller, fw_io, status
         ));
      }
   }
   else
   {
      SCIF_LOG_WARNING((
         sci_base_object_get_logger(fw_controller),
         SCIF_LOG_OBJECT_CONTROLLER,
         "Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n",
         fw_controller, fw_io, status
      ));
      fw_io->parent.state_handlers->complete_handler(io_request);
   }
   if (fw_io->parent.is_internal && status != SCI_SUCCESS )
   {
      SCIC_TRANSPORT_PROTOCOL protocol =
         scic_io_request_get_protocol(fw_io->parent.core_object);
      U8 retry_count = fw_io->retry_count;
      scif_sas_internal_io_request_destruct(
         fw_device->domain->controller,
         (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io
      );
      if ( protocol == SCIC_SMP_PROTOCOL )
      {
         if (fw_device->protocol_device.smp_device.smp_activity_timer != NULL)
         {
            scif_cb_timer_destroy (
               fw_controller,
               fw_device->protocol_device.smp_device.smp_activity_timer
            );
            fw_device->protocol_device.smp_device.smp_activity_timer = NULL;
         }
         if ( retry_count < SCIF_SAS_IO_RETRY_LIMIT)
         {
         scif_sas_smp_remote_device_retry_internal_io(
            (SCIF_SAS_REMOTE_DEVICE_T *)remote_device,
            retry_count,
            SMP_REQUEST_RETRY_WAIT_DURATION
         );
      }
   }
   }
   return status;
}
static SCI_STATUS scif_sas_controller_common_start_high_priority_io_handler ( SCI_BASE_CONTROLLER_T * controller , SCI_BASE_REMOTE_DEVICE_T * remote_device , SCI_BASE_REQUEST_T * io_request , U16 io_tag ) { SCI_STATUS status ; SCIF_SAS_IO_REQUEST_T * fw_io = ( SCIF_SAS_IO_REQUEST_T * ) io_request ; SCIF_SAS_CONTROLLER_T * fw_controller = ( SCIF_SAS_CONTROLLER_T * ) controller ; SCIF_SAS_REMOTE_DEVICE_T * fw_device = ( SCIF_SAS_REMOTE_DEVICE_T * ) remote_device ; status = fw_device -> domain -> state_handlers -> start_high_priority_io_handler ( & fw_device -> domain -> parent , remote_device , io_request ) ; if ( status == SCI_SUCCESS ) { status = ( SCI_STATUS ) scic_controller_start_io ( fw_controller -> core_object , fw_device -> core_object , fw_io -> parent . core_object , io_tag ) ; if ( status == SCI_SUCCESS ) { sci_base_state_machine_change_state ( & io_request -> state_machine , SCI_BASE_REQUEST_STATE_STARTED ) ; } else { fw_device -> domain -> state_handlers -> complete_io_handler ( & fw_device -> domain -> parent , remote_device , io_request ) ; fw_io -> parent . state_handlers -> complete_handler ( io_request ) ; SCIF_LOG_WARNING ( ( sci_base_object_get_logger ( fw_controller ) , SCIF_LOG_OBJECT_CONTROLLER , " \n " , fw_controller , fw_io , status ) ) ; } } else { SCIF_LOG_WARNING ( ( sci_base_object_get_logger ( fw_controller ) , SCIF_LOG_OBJECT_CONTROLLER , " \n " , fw_controller , fw_io , status ) ) ; fw_io -> parent . state_handlers -> complete_handler ( io_request ) ; } if ( fw_io -> parent . is_internal && status != SCI_SUCCESS ) { SCIC_TRANSPORT_PROTOCOL protocol = scic_io_request_get_protocol ( fw_io -> parent . core_object ) ; U8 retry_count = fw_io -> retry_count ; scif_sas_internal_io_request_destruct ( fw_device -> domain -> controller , ( SCIF_SAS_INTERNAL_IO_REQUEST_T * ) fw_io ) ; if ( protocol == SCIC_SMP_PROTOCOL ) { if ( fw_device -> protocol_device . smp_device . smp_activity_timer != NULL ) { scif_cb_timer_destroy ( fw_controller , fw_device -> protocol_device . smp_device . smp_activity_timer ) ; fw_device -> protocol_device . smp_device . smp_activity_timer = NULL ; } if ( retry_count < SCIF_SAS_IO_RETRY_LIMIT ) { scif_sas_smp_remote_device_retry_internal_io ( ( SCIF_SAS_REMOTE_DEVICE_T * ) remote_device , retry_count , SMP_REQUEST_RETRY_WAIT_DURATION ) ; } } } return status ; }
@brief This method provides common handling for several states
        when a user attempts to start an internal request.
@brief This method provides common handling for several states when a user attempts to start an internal request .
// Check to see that the other objects in the framework allowed // this IO to be started. // Ask the core to start processing for this IO request. // We were able to start the core request. As a result, // commit to starting the request for the framework by changing // the state of the IO request. // We were unable to start the core IO request. As a result, // back out the start operation for the framework.  It's easier to // back out the framework start operation then to backout the core // start IO operation. // Invoke the IO completion handler.  For most IOs, this does nothing // since we are still in the constructed state.  For NCQ, this will // the return of the NCQ tag back to the remote device free pool. // Invoke the IO completion handler.  For most IOs, this does nothing // since we are still in the constructed state.  For NCQ, this will // the return of the NCQ tag back to the remote device free pool. //destroy the smp_activity_timer //we should retry for finite times //An internal smp request failed being started, most likely due to remote device //is not in ready state, for example, UPDATING_PORT_WIDTH state. In this case, //we should retry the IO.