示例#1
0
/**
 * @brief This method implements the actions taken when entering the
 *        STOPPED state.
 *
 * @param[in]  object This parameter specifies the base object for which
 *             the state transition is occurring.  This is cast into a
 *             SCIF_SAS_DOMAIN object in the method implementation.
 *
 * @return none
 */
static
void scif_sas_domain_stopped_state_enter(
   SCI_BASE_OBJECT_T * object
)
{
   SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)object;

   SET_STATE_HANDLER(
      fw_domain,
      scif_sas_domain_state_handler_table,
      SCI_BASE_DOMAIN_STATE_STOPPED
   );

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_domain),
      SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "scif_sas_domain_stopped_state_enter(0x%x) enter\n",
      fw_domain
   ));

   // A hot unplug of the direct attached device has occurred.  Thus,
   // notify the user. Note, if the controller is not in READY state,
   // mostly likely the controller is in STOPPING or STOPPED state,
   // meaning the controller is in the process of stopping, we should
   // not call back to user in the middle of controller stopping.
   if(fw_domain->controller->parent.state_machine.current_state_id
         == SCI_BASE_CONTROLLER_STATE_READY)
      scif_cb_domain_change_notification(fw_domain->controller, fw_domain);
}
示例#2
0
void scic_cb_port_bc_change_primitive_recieved(
   SCI_CONTROLLER_HANDLE_T  controller,
   SCI_PORT_HANDLE_T        port,
   SCI_PHY_HANDLE_T         phy
)
{
   SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
                                   sci_object_get_association(port);

   SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)
                                           sci_object_get_association(controller);

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_domain),
      SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "scic_cb_port_bc_change_primitive_recieved(0x%x, 0x%x, 0x%x) enter\n",
      controller, port, phy
   ));

   if (fw_domain->broadcast_change_count == 0)
   {  // Enable the BCN detection only if the bcn_count is zero. If bcn_count is
      // not zero at this time, we won't enable BCN detection since all non-zero
      // BCN_count means same to us. Furthermore, we avoid BCN storm by not
      // always enabling the BCN_detection.
      scic_port_enable_broadcast_change_notification(fw_domain->core_object);
   }

   fw_domain->broadcast_change_count++;

   //if there is smp device on this domain that is in the middle of discover
   //process or smp target reset, don't notify the driver layer.
   if( ! scif_sas_domain_is_in_smp_activity(fw_domain) )
      // Notify the user that there is, potentially, a change to the domain.
      scif_cb_domain_change_notification(fw_controller, fw_domain);
}
示例#3
0
/**
 * @brief This method implements the actions taken when entering the
 *        READY state.  If the transition into this state came from:
 *        - the STARTING state, then alert the user via a
 *          scif_cb_domain_change_notification() that the domain
 *          has at least 1 device ready for discovery.
 *        - the DISCOVERING state, then alert the user that
 *          discovery is complete via the
 *          scif_cb_domain_discovery_complete() notification that
 *          discovery is finished.
 *
 * @param[in]  object This parameter specifies the base object for which
 *             the state transition is occurring.  This is cast into a
 *             SCIF_SAS_DOMAIN object in the method implementation.
 *
 * @return none
 */
static
void scif_sas_domain_ready_state_enter(
   SCI_BASE_OBJECT_T * object
)
{
   SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)object;

   SET_STATE_HANDLER(
      fw_domain,
      scif_sas_domain_state_handler_table,
      SCI_BASE_DOMAIN_STATE_READY
   );

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_domain),
      SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "scif_sas_domain_ready_state_enter(0x%x) enter\n",
      fw_domain
   ));

   if (fw_domain->parent.state_machine.previous_state_id
       == SCI_BASE_DOMAIN_STATE_STARTING)
   {
      scif_cb_domain_ready(fw_domain->controller, fw_domain);

      // Only indicate the domain change notification if the previous
      // state was the STARTING state.  We issue the notification here
      // as opposed to exit of the STARTING state so that the appropriate
      // state handlers are in place should the user call
      // scif_domain_discover() from scif_cb_domain_change_notification()
      scif_cb_domain_change_notification(fw_domain->controller, fw_domain);
   }
   else if (fw_domain->parent.state_machine.previous_state_id
            == SCI_BASE_DOMAIN_STATE_DISCOVERING)
   {
      //if domain discovery timed out, we will NOT go back to discover even
      //the broadcast change count is not zero. Instead we finish the discovery
      //back to user. User can check the operation status and decide to
      //retry discover all over again.
      if (fw_domain->operation.status == SCI_FAILURE_TIMEOUT)
         fw_domain->broadcast_change_count = 0;

      // Check the broadcast change count to determine if discovery
      // is indeed complete.
      if (fw_domain->broadcast_change_count == 0)
      {
         scif_sas_domain_transition_from_discovering_state(fw_domain);
         scif_cb_domain_ready(fw_domain->controller, fw_domain);
      }
      else
      {
         // The broadcast change count indicates something my have
         // changed in the domain, while a discovery was ongoing.
         // Thus, we should start discovery over again.
         sci_base_state_machine_change_state(
            &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_DISCOVERING
         );
      }

      // Enable the BCN because underneath hardware may disabled any further
      // BCN.
      scic_port_enable_broadcast_change_notification(fw_domain->core_object);
   }
}