コード例 #1
0
/**
 * @brief This method provides STOPPED state specific handling for
 *        when the framework attempts to start the remote device.  This
 *        method attempts to transition the state machine into the
 *        STARTING state.  If this is unsuccessful, then there is a direct
 *        transition into the FAILED state.
 *
 * @param[in]  remote_device This parameter specifies the remote device
 *             object for which the framework is attempting to start.
 *
 * @return This method returns an indication as to whether the start
 *         operating began successfully.
 */
static
SCI_STATUS scif_sas_remote_device_stopped_start_handler(
   SCI_BASE_REMOTE_DEVICE_T * remote_device
)
{
   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
                                          remote_device;

   sci_base_state_machine_change_state(
      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STARTING
   );

   // Check to see if the state transition occurred without issue.
   if (sci_base_state_machine_get_state(&fw_device->parent.state_machine)
       == SCI_BASE_REMOTE_DEVICE_STATE_FAILED)
   {
      SCIF_LOG_WARNING((
         sci_base_object_get_logger(fw_device),
         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
         "Domain:0x%x Device:0x%x Status:0x%x failed to start\n",
         fw_device->domain, fw_device, fw_device->operation_status
      ));
   }

   return fw_device->operation_status;
}
コード例 #2
0
/**
 * @brief This method provides default handling (i.e. returns an error);
 *        for when the core issues a ready notification and such a
 *        notification isn't supported.
 *
 * @param[in]  remote_device This parameter specifies the remote device object
 *             for which the notification has occured.
 *
 * @return none.
 */
void scif_sas_remote_device_default_ready_handler(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device
)
{
   SCIF_LOG_WARNING((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x State:0x%x invalid state to handle ready\n",
      fw_device,
      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
   ));
}
コード例 #3
0
void sci_base_state_machine_observer_default_update(
   SCI_BASE_OBSERVER_T *this_observer,
   SCI_BASE_SUBJECT_T  *the_subject
)
{
   SCI_BASE_STATE_MACHINE_OBSERVER_T *state_machine_observer;

   state_machine_observer = (SCI_BASE_STATE_MACHINE_OBSERVER_T *)this_observer;

   state_machine_observer->subject_state =
      sci_base_state_machine_get_state((SCI_BASE_STATE_MACHINE_T *)the_subject);
}
コード例 #4
0
static
SCI_STATUS scic_sds_remote_node_context_resuming_state_event_handler(
   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
   U32                                   event_code
)
{
   SCI_STATUS status;

   if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE)
   {
      status = SCI_SUCCESS;

      sci_base_state_machine_change_state(
         &this_rnc->state_machine,
         SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
            );
   }
   else
   {
      switch (scu_get_event_type(event_code))
      {
         case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
         case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
            // We really dont care if the hardware is going to suspend
            // the device since it's being resumed anyway
            SCIC_LOG_INFO((
               sci_base_object_get_logger(this_rnc->device),
               SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
                  SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
                  SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
               "SCIC Remote Node Context 0x%x was suspeneded by hardware while being resumed.\n",
               this_rnc
                  ));
            status = SCI_SUCCESS;
            break;

         default:
            SCIC_LOG_WARNING((
               sci_base_object_get_logger(this_rnc->device),
               SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
                  SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
                  SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
               "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n",
               this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
                  ));
            status = SCI_FAILURE;
            break;
      }
   }

   return status;
}
コード例 #5
0
/**
* This method will return TRUE if the remote node context is in a READY state
* otherwise it will return FALSE
*
* @param[in] this_rnc The state of the remote node context object to check.
*
* @return BOOL
* @retval TRUE if the remote node context is in the ready state.
* @retval FALSE if the remote node context is not in the ready state.
*/
   BOOL scic_sds_remote_node_context_is_ready(
   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
      )
{
   U32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine);

   if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE)
   {
      return TRUE;
   }

   return FALSE;
}
コード例 #6
0
/**
 * @brief This method provides default handling (i.e. returns an error);
 *        for when the core issues a stop completion notification and
 *        such a notification isn't supported.
 *
 * @param[in]  remote_device This parameter specifies the remote device object
 *             for which the completion notification has occured.
 * @param[in]  completion_status This parameter specifies the status
 *             of the completion operation.
 *
 * @return none.
 */
void scif_sas_remote_device_default_stop_complete_handler(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCI_STATUS                 completion_status
)
{
   SCIF_LOG_WARNING((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x State:0x%x invalid state to stop complete\n",
      fw_device,
      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
   ));
}
コード例 #7
0
/**
 * @brief This method provides default handling (i.e. returns an error);
 *        when there is an attempt to complete a reset to the remote device
 *        from an invalid state.
 *
 * @param[in]  remote_device This parameter specifies the remote device
 *             object on which there is an attempt to fail the device.
 *
 * @return This method returns an indication that the fail transition is not
 *         allowed.
 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
 */
SCI_STATUS scif_sas_remote_device_default_reset_complete_handler(
   SCI_BASE_REMOTE_DEVICE_T * remote_device
)
{
   SCIF_LOG_WARNING((
      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x State:0x%x invalid state to complete reset.\n",
      remote_device,
      sci_base_state_machine_get_state(
         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
   ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #8
0
/**
 * @brief This method provides DEFAULT handling for when the user
 *        attempts to destruct the supplied IO request.
 *
 * @param[in] io_request This parameter specifies the IO request object
 *            to be destructed.
 *
 * @return This method returns an indication that destruct operation is
 *         not allowed.
 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
 */
SCI_STATUS scif_sas_io_request_default_destruct_handler(
   SCI_BASE_REQUEST_T * io_request
)
{
   SCIF_LOG_ERROR((
      sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
      SCIF_LOG_OBJECT_IO_REQUEST,
      "IoRequest:0x%x State:0x%x invalid state to destruct.\n",
      io_request,
      sci_base_state_machine_get_state(
         &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
   ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #9
0
/**
 * @brief This method provides default handling (i.e. returns an error);
 *        when a user attempts to start a task on a remote device and a
 *        start task operation is not allowed.
 *
 * @param[in]  remote_device This parameter specifies the remote device
 *             object on which the user is attempting to perform a start
 *             task operation.
 * @param[in]  task_request This parameter specifies the task management
 *             request to be started.
 *
 * @return This method returns an indication that start task operations
 *         are not allowed.
 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
 */
SCI_STATUS scif_sas_remote_device_default_start_task_handler(
   SCI_BASE_REMOTE_DEVICE_T * remote_device,
   SCI_BASE_REQUEST_T       * task_request
)
{
   SCIF_LOG_WARNING((
      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "RemoteDevice:0x%x State:0x%x invalid state to start task\n",
      remote_device,
      sci_base_state_machine_get_state(
         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
   ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #10
0
/**
 * @brief This method provides DEFAULT handling for when the user
 *        attempts to destruct the supplied task request.
 *
 * @param[in] task_request This parameter specifies the task request object
 *            to be destructed.
 *
 * @return This method returns an indication that destruct operation is
 *         not allowed.
 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
 */
static
SCI_STATUS scif_sas_task_request_default_destruct_handler(
   SCI_BASE_REQUEST_T * task_request
)
{
   SCIF_LOG_ERROR((
      sci_base_object_get_logger((SCIF_SAS_TASK_REQUEST_T *) task_request),
      SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "TaskRequest:0x%x State:0x%x invalid state to destruct.\n",
      task_request,
      sci_base_state_machine_get_state(
         &((SCIF_SAS_TASK_REQUEST_T *) task_request)->parent.parent.state_machine)
   ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #11
0
static
SCI_STATUS scic_sds_remote_node_context_default_event_handler(
   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
   U32                                   event_code
)
{
   SCIC_LOG_WARNING((
      sci_base_object_get_logger(this_rnc->device),
      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
      "SCIC Remote Node Context 0x%x requested to process event 0x%x while in wrong state %d\n",
      this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
         ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #12
0
static
SCI_STATUS scic_sds_remote_node_context_await_suspension_state_event_handler(
   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
   U32                                   event_code
)
{
   SCI_STATUS status;

   switch (scu_get_event_type(event_code))
   {
      case SCU_EVENT_TL_RNC_SUSPEND_TX:
         sci_base_state_machine_change_state(
            &this_rnc->state_machine,
            SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
               );

         this_rnc->suspension_code = scu_get_event_specifier(event_code);
         status = SCI_SUCCESS;
         break;

      case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
         sci_base_state_machine_change_state(
            &this_rnc->state_machine,
            SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
               );

         this_rnc->suspension_code = scu_get_event_specifier(event_code);
         status = SCI_SUCCESS;
         break;

      default:
         SCIC_LOG_WARNING((
            sci_base_object_get_logger(this_rnc->device),
            SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
               SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
               SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
            "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n",
            this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
               ));

         status = SCI_FAILURE;
         break;
   }

   return status;
}
コード例 #13
0
// ---------------------------------------------------------------------------
static
SCI_STATUS scic_sds_remote_node_context_reset_required_start_io_handler(
   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
   struct SCIC_SDS_REQUEST             * the_request
)
{
   SCIC_LOG_WARNING((
      sci_base_object_get_logger(this_rnc->device),
      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
      "SCIC Remote Node Context 0x%x requested to start io 0x%x while in wrong state %d\n",
      this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine)
         ));

   return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
}
コード例 #14
0
/**
 * @brief This method provides default handling (i.e. returns an error);
 *        when a user attempts to complete an IO on a remote device and a
 *        complete IO operation is not allowed.
 *
 * @param[in]  remote_device This parameter specifies the remote device
 *             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.
 *
 * @return This method returns an indication that complete IO operations
 *         are not allowed.
 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
 */
SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler(
   SCI_BASE_REMOTE_DEVICE_T * remote_device,
   SCI_BASE_REQUEST_T       * io_request,
   void                     * response_data,
   SCI_IO_STATUS              completion_status
)
{
   SCIF_LOG_WARNING((
      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n",
      remote_device,
      sci_base_state_machine_get_state(
         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
   ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #15
0
static
SCI_STATUS scic_sds_remote_node_context_default_resume_handler(
   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
   void                                   * callback_parameter
)
{
   SCIC_LOG_WARNING((
      sci_base_object_get_logger(this_rnc->device),
      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
      "SCIC Remote Node Context 0x%x requested to resume while in wrong state %d\n",
      this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine)
         ));

   return SCI_FAILURE_INVALID_STATE;
}
コード例 #16
0
/**
 * @brief This method provides handling of device start complete duing
 *        UPDATING_PORT_WIDTH state.
 *
 * @param[in]  remote_device This parameter specifies the remote device object
 *             which is start complete.
 *
 * @return none.
 */
static
void scif_sas_remote_device_updating_port_width_state_start_complete_handler(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCI_STATUS                 completion_status
)
{
   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x updating port width state start complete handler\n",
      fw_device,
      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
   ));

   if ( fw_device->destination_state
           == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
   {
      //if the destination state of this device change to STOPPING, no matter
      //whether we need to update the port width again, just make the device
      //go to the STOPPING state.
      sci_base_state_machine_change_state(
         &fw_device->parent.state_machine,
         SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
      );
   }
   else if ( scic_remote_device_get_port_width(fw_device->core_object)
                != fw_device->device_port_width
            && fw_device->device_port_width != 0)
   {
      scic_remote_device_stop(
         fw_device->core_object,
         SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT
      );
   }
   else
   {
      //Port width updating succeeds. Transfer to destination state.
      sci_base_state_machine_change_state(
         &fw_device->parent.state_machine,
         SCI_BASE_REMOTE_DEVICE_STATE_READY
      );
   }
}
コード例 #17
0
static
SCI_STATUS scic_sds_remote_node_context_default_destruct_handler(
   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
   void                                   * callback_parameter
)
{
   SCIC_LOG_WARNING((
      sci_base_object_get_logger(this_rnc->device),
      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
      "SCIC Remote Node Context 0x%x requested to stop while in unexpected state %d\n",
      this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine)
         ));

   // We have decided that the destruct request on the remote node context can not fail
   // since it is either in the initial/destroyed state or is can be destroyed.
   return SCI_SUCCESS;
}
コード例 #18
0
/**
 * @brief This method provides handling of device stop complete duing
 *        UPDATING_PORT_WIDTH state.
 *
 * @param[in]  remote_device This parameter specifies the remote device object
 *             which is stop complete.
 *
 * @return none.
 */
static
void scif_sas_remote_device_updating_port_width_state_stop_complete_handler(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCI_STATUS                 completion_status
)
{
   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x updating port width state stop complete handler\n",
      fw_device,
      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
   ));

   if ( fw_device->destination_state
           == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
   {
      //Device directly transits to STOPPED STATE from UPDATING_PORT_WIDTH state,
      fw_device->domain->device_start_count--;

      //if the destination state of this device change to STOPPING, no matter
      //whether we need to update the port width again, just make the device
      //go to the STOPPED state.
      sci_base_state_machine_change_state(
         &fw_device->parent.state_machine,
         SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
      );
   }
   else
   {
      scic_remote_device_set_port_width(
         fw_device->core_object,
         fw_device->device_port_width
      );

      //Device stop complete, means the RNC has been destructed. Now we need to
      //start core device so the RNC with updated port width will be posted.
      scic_remote_device_start(
         fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
   }
}
コード例 #19
0
/**
 * @brief This method will attempt to handle an operation timeout (i.e.
 *        discovery or reset).
 *
 * @param[in]  cookie This parameter specifies the domain in which the
 *             timeout occurred.
 *
 * @return none
 */
static
void scif_sas_domain_operation_timeout_handler(
   void * cookie
)
{
   SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) cookie;
   U32                 state;

   state = sci_base_state_machine_get_state(&fw_domain->parent.state_machine);

   // Based upon the state of the domain, we know whether we were in the
   // process of performing discovery or a reset.
   if (state == SCI_BASE_DOMAIN_STATE_DISCOVERING)
   {
      SCIF_LOG_WARNING((
         sci_base_object_get_logger(fw_domain),
         SCIF_LOG_OBJECT_DOMAIN,
         "Domain:0x%x State:0x%x DISCOVER timeout!\n",
         fw_domain, state
      ));

      fw_domain->operation.status = SCI_FAILURE_TIMEOUT;

      //search all the smp devices in the domain and cancel their activities
      //if there is any outstanding activity remained. The smp devices will terminate
      //all the started internal IOs.
      scif_sas_domain_cancel_smp_activities(fw_domain);

      scif_sas_domain_continue_discover(fw_domain);
   }
   else
   {
      SCIF_LOG_ERROR((
         sci_base_object_get_logger(fw_domain),
         SCIF_LOG_OBJECT_DOMAIN,
         "Domain:0x%x State:0x%x operation timeout in invalid state\n",
         fw_domain, state
      ));
   }
}
コード例 #20
0
/**
 * @brief This methods finds the first device that is in STOPPED state and its
 *        connection_rate is still in SPINUP_HOLD(value 3).
 *
 * @param[in] fw_domain The framework domain object
 *
 * @return SCIF_SAS_REMOTE_DEVICE_T The device that is in SPINUP_HOLD or NULL.
 */
SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_device_in_spinup_hold(
   SCIF_SAS_DOMAIN_T        * fw_domain
)
{
   SCI_ABSTRACT_ELEMENT_T   * current_element;
   SCIF_SAS_REMOTE_DEVICE_T * current_device;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_domain),
      SCIF_LOG_OBJECT_DOMAIN,
      "scif_sas_domain_find_device_in_spinup_hold(0x%x) enter\n",
      fw_domain
   ));

   //search throught domain's device list to find the first sata device on spinup_hold
   current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
   while (current_element != NULL )
   {
      current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
                       sci_abstract_list_get_object(current_element);

      //We must get the next element before we remove the current
      //device. Or else, we will get wrong next_element, since the erased
      //element has been put into free pool.
      current_element = sci_abstract_list_get_next(current_element);

      if ( sci_base_state_machine_get_state(&current_device->parent.state_machine) ==
              SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
          && scic_remote_device_get_connection_rate(current_device->core_object) ==
                SCI_SATA_SPINUP_HOLD )
      {
         return current_device;
      }
   }

   return NULL;
}
コード例 #21
0
/**
 * This is the function that is called when the state machine wants to notify
 * this observer that there has been a state change.
 *
 * @param[in] observer The state machine logger that is observing the state
 *       machine.
 * @param[in] subject The state machine that is being observed.
 */
static
void sci_base_state_machine_logger_update(
   SCI_BASE_OBSERVER_T *observer,
   SCI_BASE_SUBJECT_T  *subject
)
{
   SCI_BASE_STATE_MACHINE_LOGGER_T *this_observer;
   this_observer = (SCI_BASE_STATE_MACHINE_LOGGER_T *)observer;

   this_observer->log_function(
      sci_base_object_get_logger(this_observer->log_object),
      this_observer->log_mask,
      "%s 0x%08x %s has transitioned from %d to %d\n",
      this_observer->log_object_name,
      this_observer->log_object,
      this_observer->log_state_machine_name,
      this_observer->parent.subject_state,
      sci_base_state_machine_get_state((SCI_BASE_STATE_MACHINE_T *)subject)
   );

   sci_base_state_machine_observer_default_update(
      &this_observer->parent.parent, subject
   );
}
コード例 #22
0
/**
 * @brief This method provides handling (i.e. returns an error);
 *        when a user attempts to stop a remote device during the updating
 *        port width state, it will record the destination state for this
 *        device to be STOPPING, instead of usually READY state.
 *
 * @param[in]  remote_device This parameter specifies the remote device object
 *             on which the user is attempting to perform a stop operation.
 *
 * @return This method always return SCI_SUCCESS.
 */
static
SCI_STATUS scif_sas_remote_device_updating_port_width_state_stop_handler(
   SCI_BASE_REMOTE_DEVICE_T * remote_device
)
{
   SCIF_SAS_REMOTE_DEVICE_T * fw_device =
      (SCIF_SAS_REMOTE_DEVICE_T *)remote_device;

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE,
      "RemoteDevice:0x%x updating port width state stop handler\n",
      fw_device,
      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
   ));

   //Can't stop the device right now. Remember the pending stopping request.
   //When exit the UPDATING_PORT_WIDTH state, we will check this variable
   //to decide which state to go.
   fw_device->destination_state =
      SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING;

   return SCI_SUCCESS;
}
コード例 #23
0
/**
 *  This method will handle events received while the STP device is in the
 *  ready command substate.
 *
 *  @param [in] this_device This is the device object that is receiving the
 *         event.
 *  @param [in] event_code The event code to process.
 *
 *  @return SCI_STATUS
 */
static
SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_event_handler(
   SCIC_SDS_REMOTE_DEVICE_T * this_device,
   U32                        event_code
)
{
   SCI_STATUS status;

   status = scic_sds_remote_device_general_event_handler(this_device, event_code);

   switch (scu_get_event_code(event_code))
   {
   case SCU_EVENT_TL_RNC_SUSPEND_TX:
   case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
      /// @todo We need to decode and understand why the hardware suspended the device.
      ///       The suspension reason was probably due to an SDB error FIS received.
      break;

   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DATA_LEN_ERR:
   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_OFFSET_ERR:
   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DMASETUP_DIERR:
   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_XFERCNT_ERR:
   case SCU_EVENT_TL_RNC_SUSPEND_TX_RX_DONE_PLD_LEN_ERR:
      this_device->not_ready_reason =
         SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;

      sci_base_state_machine_change_state(
         &this_device->ready_substate_machine,
         SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
      );

      // We have a notification that the driver requested a suspend operation
      // this should not happen.
      SCIC_LOG_WARNING((
         sci_base_object_get_logger(this_device),
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
         "SCIC Remote device 0x%x received driver suspend event %x while in ncq ready substate %d\n",
         this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
      ));

      // Since we didn't expect to get here start the device again.
      status = scic_sds_remote_device_resume(this_device);
      break;

   case SCU_EVENT_POST_RCN_RELEASE:
      /// @todo Do we need to store the suspend state on the device?
      SCIC_LOG_INFO((
         sci_base_object_get_logger(this_device),
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
         "SCIC Remote device 0x%x received driver release event %x while in the ready substate %d\n",
         this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
      ));
      break;

   default:
      // Some other event just log it and continue
      SCIC_LOG_WARNING((
         sci_base_object_get_logger(this_device),
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
         "SCIC Remote device 0x%x received driver unexpected event %x while in the ready substate %d\n",
         this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
      ));

      status = SCI_FAILURE_INVALID_STATE;
      break;
   }

   return status;
}