Ejemplo n.º 1
0
/**
 * @brief this routine is called by OS' DPC to start io requests from internal
 *        high priority request queue
 * @param[in] fw_controller The framework controller.
 *
 * @return none
 */
void scif_sas_controller_start_high_priority_io(
   SCIF_SAS_CONTROLLER_T * fw_controller
)
{
   POINTER_UINT            io_address;
   SCIF_SAS_IO_REQUEST_T * fw_io;
   SCI_STATUS              status;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_controller),
      SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_controller_start_high_priority_io(0x%x) enter\n",
      fw_controller
   ));

   while ( !sci_pool_empty(fw_controller->hprq.pool) )
   {
      sci_pool_get(fw_controller->hprq.pool, io_address);

      fw_io = (SCIF_SAS_IO_REQUEST_T *)io_address;

      status = fw_controller->state_handlers->start_high_priority_io_handler(
         (SCI_BASE_CONTROLLER_T*) fw_controller,
         (SCI_BASE_REMOTE_DEVICE_T*) fw_io->parent.device,
         (SCI_BASE_REQUEST_T*) fw_io,
         SCI_CONTROLLER_INVALID_IO_TAG
      );
   }
}
Ejemplo n.º 2
0
/**
 * @brief construct a smp Report Genernal command to the fw_device.
 *
 * @param[in] fw_controller The framework controller object.
 * @param[in] fw_device the framework device that the REPORT GENERAL command
 *       targets to.
 *
 * @return void * address to the built scif sas smp request.
 */
void * scif_sas_smp_request_construct_report_general(
   SCIF_SAS_CONTROLLER_T    * fw_controller,
   SCIF_SAS_REMOTE_DEVICE_T * fw_device
)
{
   SMP_REQUEST_T smp_report_general;

   // Build the REPORT GENERAL request.
   scif_sas_smp_protocol_request_construct(
      &smp_report_general,
      SMP_FUNCTION_REPORT_GENERAL,
      sizeof(SMP_RESPONSE_REPORT_GENERAL_T) / sizeof(U32),
      0
   );

   smp_report_general.request.report_general.crc = 0;

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "SMP REPORT GENERAL -  Device:0x%x\n",
      fw_device
   ));

   return scif_sas_smp_request_build(
             fw_controller, fw_device, &smp_report_general, NULL, NULL);
}
Ejemplo n.º 3
0
void scic_cb_controller_stop_complete(
   SCI_CONTROLLER_HANDLE_T  controller,
   SCI_STATUS               completion_status
)
{
   SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)
                                         sci_object_get_association(controller);

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(controller),
      SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
      "scic_cb_controller_stop_complete(0x%x, 0x%x) enter\n",
      controller, completion_status
   ));

   if (completion_status == SCI_SUCCESS)
   {
      sci_base_state_machine_change_state(
         &fw_controller->parent.state_machine,
         SCI_BASE_CONTROLLER_STATE_STOPPED
      );
   }
   else
   {
      sci_base_state_machine_change_state(
         &fw_controller->parent.state_machine,
         SCI_BASE_CONTROLLER_STATE_FAILED
      );
   }

   scif_cb_controller_stop_complete(fw_controller, completion_status);
}
/**
 * @brief This method provides STOPPING state specific handling for
 *        when the core remote device object issues a stop completion
 *        notification.
 *
 * @note There is no need to ensure all IO/Task requests are complete
 *       before transitioning to the STOPPED state.  The SCI Core will
 *       ensure this is accomplished.
 *
 * @param[in]  remote_device This parameter specifies the remote device
 *             object for which the completion occurred.
 * @param[in]  completion_status This parameter specifies the status
 *             of the completion operation.
 *
 * @return none.
 */
static
void scif_sas_remote_device_stopping_stop_complete_handler(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCI_STATUS                 completion_status
)
{
   // Transition directly to the STOPPED state since the core ensures
   // all IO/Tasks are complete.
   sci_base_state_machine_change_state(
      &fw_device->parent.state_machine,
      SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
   );

   if (completion_status != SCI_SUCCESS)
   {
      SCIF_LOG_ERROR((
         sci_base_object_get_logger(fw_device),
         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
         "Device:0x%x Status:0x%x failed to stop core device\n",
         fw_device, completion_status
      ));

      // Something is seriously wrong.  Stopping the core remote device
      // shouldn't fail in anyway.
      scif_cb_controller_error(fw_device->domain->controller,
              SCI_CONTROLLER_REMOTE_DEVICE_ERROR);
   }
}
Ejemplo n.º 5
0
void scic_cb_controller_start_complete(
   SCI_CONTROLLER_HANDLE_T  controller,
   SCI_STATUS               completion_status
)
{
   SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)
                                         sci_object_get_association(controller);

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(controller),
      SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
      "scic_cb_controller_start_complete(0x%x, 0x%x) enter\n",
      controller, completion_status
   ));

   if (completion_status == SCI_SUCCESS
       || completion_status == SCI_FAILURE_TIMEOUT)
   {
      // Even the initialization of the core controller timed out, framework
      // controller should still transit to READY state.
      sci_base_state_machine_change_state(
         &fw_controller->parent.state_machine,
         SCI_BASE_CONTROLLER_STATE_READY
      );
   }

   scif_cb_controller_start_complete(fw_controller, completion_status);
}
Ejemplo n.º 6
0
SCI_STATUS scif_controller_complete_task(
   SCI_CONTROLLER_HANDLE_T     controller,
   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
   SCI_TASK_REQUEST_HANDLE_T   task_request
)
{
   SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;

   // Validate the user supplied parameters.
   if (  (controller == SCI_INVALID_HANDLE)
      || (remote_device == SCI_INVALID_HANDLE)
      || (task_request == SCI_INVALID_HANDLE) )
   {
      return SCI_FAILURE_INVALID_PARAMETER_VALUE;
   }

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(controller),
      SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "scif_controller_complete_task(0x%x, 0x%x, 0x%x) enter\n",
      controller, remote_device, task_request
   ));

   return fw_controller->state_handlers->complete_task_handler(
             (SCI_BASE_CONTROLLER_T*) controller,
             (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
             (SCI_BASE_REQUEST_T*) task_request
          );
}
Ejemplo n.º 7
0
SCI_IO_STATUS scif_controller_start_io(
   SCI_CONTROLLER_HANDLE_T     controller,
   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
   SCI_IO_REQUEST_HANDLE_T     io_request,
   U16                         io_tag
)
{
   SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
   SCI_STATUS              status;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(controller),
      SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_controller_start_io(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
      controller, remote_device, io_request, io_tag
   ));

   if (
         sci_pool_empty(fw_controller->hprq.pool)
      || scif_sas_controller_sufficient_resource(controller)
      )
   {
      status = fw_controller->state_handlers->start_io_handler(
                (SCI_BASE_CONTROLLER_T*) controller,
                (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
                (SCI_BASE_REQUEST_T*) io_request,
                io_tag
             );
   }
   else
      status = SCI_FAILURE_INSUFFICIENT_RESOURCES;

   return (SCI_IO_STATUS)status;
}
Ejemplo n.º 8
0
/**
 * @brief construct a SMP Report Manufacturer Info request to the fw_device.
 *
 * @param[in] fw_controller The framework controller object.
 * @param[in] fw_device the framework device that the REPORT MANUFACTURER
 *            INFO targets to.
 *
 * @return void * address to the built scif sas smp request.
 */
void * scif_sas_smp_request_construct_report_manufacturer_info(
   SCIF_SAS_CONTROLLER_T    * fw_controller,
   SCIF_SAS_REMOTE_DEVICE_T * fw_device
)
{
   SMP_REQUEST_T smp_report_manufacturer_info;

   scif_sas_smp_protocol_request_construct(
      &smp_report_manufacturer_info,
      SMP_FUNCTION_REPORT_MANUFACTURER_INFORMATION,
      sizeof(SMP_RESPONSE_REPORT_MANUFACTURER_INFORMATION_T) / sizeof(U32),
      0
   );

   smp_report_manufacturer_info.request.report_general.crc = 0;

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "SMP REPORT MANUFACTURER_INFO -  Device:0x%x\n",
      fw_device
   ));

   return scif_sas_smp_request_build(
             fw_controller, fw_device, &smp_report_manufacturer_info, NULL, NULL
          );
}
Ejemplo n.º 9
0
/**
 * @brief construct a smp Discover command to the fw_device.
 * @param[in] fw_controller The framework controller object.
 * @param[in] fw_device the framework smp device that DISCOVER command targets
 *       to.
 * @param[in] phy_identifier The phy index the DISCOVER command targets to.
 *
 * @return void * address to the built scif sas smp request.
 */
void * scif_sas_smp_request_construct_discover(
   SCIF_SAS_CONTROLLER_T    * fw_controller,
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   U8                         phy_identifier,
   void                     * external_request_object,
   void                     * external_memory
)
{
   SMP_REQUEST_T smp_discover;

   scif_sas_smp_protocol_request_construct(
      &smp_discover,
      SMP_FUNCTION_DISCOVER,
      sizeof(SMP_RESPONSE_DISCOVER_T) / sizeof(U32),
      sizeof(SMP_REQUEST_PHY_IDENTIFIER_T) / sizeof(U32)
   );

   smp_discover.request.discover.phy_identifier = phy_identifier;

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "SMP DISCOVER - Device:0x%x PhyId:0x%x\n",
      fw_device, phy_identifier
   ));

   return scif_sas_smp_request_build(
             fw_controller, fw_device, &smp_discover,
             external_request_object, external_memory
          );
}
/**
 * @brief This method implements the actions taken when entering the
 *        FAILED state.  This includes setting the state handler methods
 *        and issuing a scif_cb_remote_device_failed() notification to
 *        the user.
 *
 * @param[in]  object This parameter specifies the base object for which
 *             the state transition is occurring.  This is cast into a
 *             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
 *
 * @return none
 */
static
void scif_sas_remote_device_failed_state_enter(
   SCI_BASE_OBJECT_T *object
)
{
   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;

   SET_STATE_HANDLER(
      fw_device,
      scif_sas_remote_device_state_handler_table,
      SCI_BASE_REMOTE_DEVICE_STATE_FAILED
   );

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
      "Domain:0x%x Device:0x%x Status:0x%x device failed\n",
      fw_device->domain, fw_device, fw_device->operation_status
   ));

   // Notify the user that the device has failed.
   scif_cb_remote_device_failed(
      fw_device->domain->controller,
      fw_device->domain,
      fw_device,
      fw_device->operation_status
   );

   // Only call start_complete for the remote device if the device failed
   // from the STARTING state.
   if (fw_device->parent.state_machine.previous_state_id
       == SCI_BASE_REMOTE_DEVICE_STATE_STARTING)
      scif_sas_domain_remote_device_start_complete(fw_device->domain,fw_device);
}
Ejemplo n.º 11
0
/**
 * @brief This method provides SATA/STP CONSTRUCTED state specific handling
 *        for when the user attempts to complete the supplied IO request.
 *        This method will be invoked in the event the call to start the
 *        core IO request fails for some reason.  In this situation, the
 *        NCQ tag will be freed.
 *
 * @param[in] io_request This parameter specifies the IO request object
 *            to be started.
 *
 * @return This method returns a value indicating if the IO request was
 *         successfully started or not.
 * @retval SCI_SUCCESS This return value indicates successful starting
 *         of the IO request.
 */
static
SCI_STATUS scif_sas_stp_io_request_constructed_complete_handler(
   SCI_BASE_REQUEST_T * io_request
)
{
   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(io_request),
      SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_sas_stp_io_request_constructed_complete_handler(0x%x) enter\n",
      io_request
   ));

   if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA)
   {
      // For NCQ, we need to return the tag back to the free pool.
      if (fw_io->parent.stp.ncq_tag != SCIF_SAS_INVALID_NCQ_TAG)
         scif_sas_stp_remote_device_free_ncq_tag(
            fw_io->parent.device, fw_io->parent.stp.ncq_tag
         );
   }

   return SCI_SUCCESS;
}
Ejemplo n.º 12
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);
}
/**
 * This method will perform the STP request (both io or task) completion
 * processing for await reset state.
 *
 * @param[in] device This parameter specifies the device for which the
 *            request is being completed.
 * @param[in] request This parameter specifies the request being completed.
 *
 * @return This method returns an indication as to whether the request
 *         processing completed successfully.
 */
static
SCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
   SCI_BASE_REMOTE_DEVICE_T * device,
   SCI_BASE_REQUEST_T       * request
)
{
   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
   SCIC_SDS_REQUEST_T       * the_request = (SCIC_SDS_REQUEST_T *)request;
   SCI_STATUS                 status;

   status = scic_sds_io_request_complete(the_request);

   if (status == SCI_SUCCESS)
   {
      status = scic_sds_port_complete_io(
                  this_device->owning_port, this_device, the_request
               );

      if (status == SCI_SUCCESS)
         scic_sds_remote_device_decrement_request_count(this_device);
   }

   if (status != SCI_SUCCESS)
   {
      SCIC_LOG_ERROR((
         sci_base_object_get_logger(this_device),
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
         "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
         this_device->owning_port, this_device, the_request, status
      ));
   }

   return status;
}
Ejemplo n.º 14
0
/**

 * @brief This routine is to allocate the memory for creating a smp phy object.
 *
 * @param[in] scif_controller handle to frame controller
 *
 * @return SCIF_SAS_SMP_PHY_T * An allocated space for smp phy. If failed to allocate,
 *            return NULL.
 */
SCIF_SAS_SMP_PHY_T * scif_sas_controller_allocate_smp_phy(
   SCIF_SAS_CONTROLLER_T * fw_controller
)
{
   SCIF_SAS_SMP_PHY_T * smp_phy;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_controller),
      SCIF_LOG_OBJECT_CONTROLLER,
      "scif_controller_allocate_smp_phy(0x%x) enter\n",
      fw_controller
   ));

   if( !sci_fast_list_is_empty(&fw_controller->smp_phy_memory_list) )
   {
      smp_phy = (SCIF_SAS_SMP_PHY_T *)
         sci_fast_list_remove_head(&fw_controller->smp_phy_memory_list);

      //clean the memory.
      memset((char*)smp_phy,
             0,
             sizeof(SCIF_SAS_SMP_PHY_T)
            );

      return smp_phy;
   }
   else
      return NULL;
}
/**
 * @brief This handler is currently solely used by smp remote device for
 *        discovering.
 *
 * @param[in]  remote_device This parameter specifies the remote device
 *             object on which the user is attempting to perform a complete high
 *             priority IO operation.
 * @param[in]  io_request This parameter specifies the high priority IO request
 *             to be completed.
 *
 * @return SCI_STATUS indicate whether the io complete successfully.
 */
SCI_STATUS
scif_sas_remote_device_ready_task_management_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_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
                                           remote_device;
   SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
   SCI_STATUS                 status     = SCI_SUCCESS;
   SCIC_TRANSPORT_PROTOCOL    protocol;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(remote_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
      remote_device, io_request, response_data, completion_status
   ));

   fw_device->request_count--;

   // we are back to ready operational sub state here.
   sci_base_state_machine_change_state(
      &fw_device->ready_substate_machine,
      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
   );

   protocol = scic_io_request_get_protocol(fw_request->core_object);

   // If this request was an SMP initiator request we created, then
   // decode the response.
   if (protocol == SCIC_SMP_PROTOCOL)
   {
      if (completion_status != SCI_IO_FAILURE_TERMINATED)
      {
         status = scif_sas_smp_remote_device_decode_smp_response(
                     fw_device, fw_request, response_data, completion_status
                  );
      }
      else
         scif_sas_smp_remote_device_terminated_request_handler(fw_device, fw_request);
   }
   else
   {
      // Currently, there are only internal SMP requests.  So, default work
      // is simply to clean up the internal request.
      if (fw_request->is_internal == TRUE)
      {
         scif_sas_internal_io_request_complete(
            fw_device->domain->controller,
            (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_request,
            SCI_SUCCESS
         );
      }
   }

   return status;
}
Ejemplo n.º 16
0
/**
 * @brief This method implements the actions taken when entering the
 *        STARTING state.  This includes setting the state handlers and
 *        checking to see if the core port has already become READY.
 *
 * @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_starting_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_STARTING
   );

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

   scif_sas_domain_transition_from_discovering_state(fw_domain);

   // If we entered the STARTING state and the core port is actually ready,
   // then directly transition into the READY state.  This can occur
   // if we were in the middle of discovery when the port failed
   // (causing a transition to STOPPING), then before reaching STOPPED
   // the port becomes ready again.
   if (fw_domain->is_port_ready == TRUE)
   {
      sci_base_state_machine_change_state(
         &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_READY
      );
   }
}
/**
 * @brief This method implements the actions taken when entering the
 *        READY OPERATIONAL substate.  This includes setting the state
 *        handler methods and issuing a scif_cb_remote_device_ready()
 *        notification to the user.
 *
 * @param[in]  object This parameter specifies the base object for which
 *             the state transition is occurring.  This is cast into a
 *             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
 *
 * @return none
 */
static
void scif_sas_remote_device_ready_operational_substate_enter(
   SCI_BASE_OBJECT_T *object
)
{
   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;

   SET_STATE_HANDLER(
      fw_device,
      scif_sas_remote_device_ready_substate_handler_table,
      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
   );

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
      "Domain:0x%x Device:0x%x device ready\n",
      fw_device->domain, fw_device
   ));

   // Notify the user that the device has become ready.
   scif_cb_remote_device_ready(
      fw_device->domain->controller, fw_device->domain, fw_device
   );
}
Ejemplo n.º 18
0
/**
 * @brief construct a smp REPORT PHY SATA command to the fw_device.
 * @param[in] fw_controller The framework controller object.
 * @param[in] fw_device the framework smp device that DISCOVER command targets
 *       to.
 * @param[in] phy_identifier The phy index the DISCOVER command targets to.
 *
 * @return void * address to the built scif sas smp request.
 */
void * scif_sas_smp_request_construct_report_phy_sata(
   SCIF_SAS_CONTROLLER_T    * fw_controller,
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   U8                         phy_identifier
)
{
   SMP_REQUEST_T report_phy_sata;

   scif_sas_smp_protocol_request_construct(
      &report_phy_sata,
      SMP_FUNCTION_REPORT_PHY_SATA,
      sizeof(SMP_RESPONSE_REPORT_PHY_SATA_T) / sizeof(U32),
      sizeof(SMP_REQUEST_PHY_IDENTIFIER_T) / sizeof(U32)
   );

   report_phy_sata.request.report_phy_sata.phy_identifier = phy_identifier;

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "SMP REPORT PHY SATA - Device:0x%x PhyId:0x%x\n",
      fw_device, phy_identifier
   ));

   return scif_sas_smp_request_build(
             fw_controller, fw_device, &report_phy_sata, NULL, NULL);
}
Ejemplo n.º 19
0
/**
 * @brief This method is called by the SCI user to build an SMP pass-through
 *        IO request.
 *
 * @pre
 *        - The user must have previously called scic_io_request_construct()
 *          on the supplied IO request.
 *
 * @param[in]  scic_smp_request This parameter specifies the handle to the
 *             io request object to be built.
 *
 * @param[in]  passthru_cb This parameter specifies the pointer to the callback
 *             structure that contains the function pointers
 *
 * @return Indicate if the controller successfully built the IO request.
 */
SCI_STATUS scic_io_request_construct_smp_pass_through(
   SCI_IO_REQUEST_HANDLE_T  scic_smp_request,
   SCIC_SMP_PASSTHRU_REQUEST_CALLBACKS_T *passthru_cb
)
{
   SMP_REQUEST_T smp_request;
   U8 * request_buffer;
   U32 request_buffer_length_in_bytes;

   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *) scic_smp_request;
   SCIC_LOG_TRACE((
      sci_base_object_get_logger(this_request),
      SCIC_LOG_OBJECT_SMP_IO_REQUEST,
      "scic_io_request_construct_smp_pass_through(0x%x) enter\n",
      this_request
   ));

   this_request->protocol                     = SCIC_SMP_PROTOCOL;
   this_request->has_started_substate_machine = TRUE;

   // Call the callback function to retrieve the SMP passthrough request
   request_buffer_length_in_bytes = passthru_cb->scic_cb_smp_passthru_get_request (
                                       (void *)this_request,
                                       &request_buffer
                                    );

   //copy the request to smp request
   memcpy((char *)&smp_request.request.vendor_specific_request,
        request_buffer,
        request_buffer_length_in_bytes);

   //the header length in smp_request is in dwords - the sas spec has similar way,
   //but the csmi header contains the number of bytes, so we need to convert the
   //number of bytes to number of dwords
   smp_request.header.request_length = (U8) (request_buffer_length_in_bytes / sizeof (U32));

   //Grab the other needed fields from the smp request using callbacks
   smp_request.header.smp_frame_type = passthru_cb->scic_cb_smp_passthru_get_frame_type ((void *)this_request);
   smp_request.header.function = passthru_cb->scic_cb_smp_passthru_get_function ((void *)this_request);
   smp_request.header.allocated_response_length = passthru_cb->scic_cb_smp_passthru_get_allocated_response_length((void *)this_request);

   // Construct the started sub-state machine.
   sci_base_state_machine_construct(
      &this_request->started_substate_machine,
      &this_request->parent.parent,
      scic_sds_smp_request_started_substate_table,
      SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
   );

   // Construct the SMP SCU Task Context
   scu_smp_request_construct_task_context (this_request, &smp_request);

   sci_base_state_machine_change_state(
      &this_request->parent.state_machine,
      SCI_BASE_REQUEST_STATE_CONSTRUCTED
   );

   return SCI_SUCCESS;
}
Ejemplo n.º 20
0
/**
 * @brief This method will construct the STP PACKET protocol specific IO
 *        request object.
 *
 * @pre The scif_sas_request_construct() method should be invoked before
 *      calling this method.
 *
 * @param[in,out] fw_io This parameter specifies the stp packet io request
 *                to be constructed.
 *
 * @return Indicate if the construction was successful.
 * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START
 * @return SCI_FAILURE_IO_RESPONSE_VALID
 * @return SCI_FAILURE This return value indicates a change in the translator
 *         where a new return code has been given, but is not yet understood
 *         by this routine.
 */
SCI_STATUS scif_sas_stp_packet_io_request_construct(
   SCIF_SAS_IO_REQUEST_T * fw_io
)
{
   SATI_STATUS                sati_status;
   SCI_STATUS                 sci_status = SCI_FAILURE;
   SCIF_SAS_REMOTE_DEVICE_T * fw_device  = fw_io->parent.device;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_io),
      SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_sas_stp_packet_io_request_construct(0x%x) enter\n",
      fw_io
   ));

   sati_status = sati_atapi_translate_command(
                    &fw_io->parent.stp.sequence,
                    &fw_device->protocol_device.stp_device.sati_device,
                    fw_io,
                    fw_io
                 );

   if (sati_status == SATI_SUCCESS)
   {
      // Allow the core to finish construction of the IO request.
      sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object);

      fw_io->parent.protocol_complete_handler
         = scif_sas_stp_core_cb_packet_io_request_complete_handler;
   }
   else if (sati_status == SATI_COMPLETE)
      sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START;
   else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA)
      sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
   else
   {
      SCIF_LOG_ERROR((
         sci_base_object_get_logger(fw_io),
         SCIF_LOG_OBJECT_IO_REQUEST,
         "Unexpected SAT ATAPI translation failure 0x%x\n",
         fw_io
      ));
   }

   return sci_status;
}
Ejemplo n.º 21
0
/**
 * @file
 *
 * @brief This file contains the method implementations for the
 *        SCIF_SAS_STP_TASK_REQUEST object.  The contents will implement
 *        SATA/STP specific functionality.
 */
SCI_STATUS scif_sas_stp_task_request_construct(
   SCIF_SAS_TASK_REQUEST_T * fw_task
)
{
   SCI_STATUS                 sci_status = SCI_FAILURE;

#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
   SATI_STATUS                sati_status;
   SCIF_SAS_REMOTE_DEVICE_T * fw_device  = fw_task->parent.device;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_task),
      SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "scif_sas_stp_task_request_construct(0x%x) enter\n",
      fw_task
   ));

   // The translator will indirectly invoke core methods to set the fields
   // of the ATA register FIS inside of this method.
   sati_status = sati_translate_task_management(
                    &fw_task->parent.stp.sequence,
                    &fw_device->protocol_device.stp_device.sati_device,
                    fw_task,
                    fw_task
                 );

   if (sati_status == SATI_SUCCESS)
   {
      sci_status = scic_task_request_construct_sata(fw_task->parent.core_object);
      //fw_task->parent.state_handlers = &stp_io_request_constructed_handlers;
      fw_task->parent.protocol_complete_handler =
         scif_sas_stp_core_cb_task_request_complete_handler;
   }
   else
   {
      SCIF_LOG_ERROR((
         sci_base_object_get_logger(fw_task),
         SCIF_LOG_OBJECT_TASK_MANAGEMENT,
         "Task 0x%x received unexpected SAT translation failure 0x%x\n",
         fw_task, sati_status
      ));
   }
#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)

   return sci_status;
}
Ejemplo n.º 22
0
/**
 * @brief This method attempts to allocate a valid NCQ tag from the list
 *        of available tags in the remote device.
 *
 * @todo Attempt to find a CLZ like instruction to optimize this routine
 *       down into a few instructions.  I know there is one like it for IA.
 *
 * @param[in] fw_device This parameter specifies the remote device
 *            for which to allocate an available NCQ tag.
 *
 * @return Return an available NCQ tag.
 * @retval 0-31 These values indicate an available tag was successfully
 *         allocated.
 * @return SCIF_SAS_STP_INVALID_NCQ_TAG This value indicates that there are
 *         no available NCQ tags.
 */
U8 scif_sas_stp_remote_device_allocate_ncq_tag(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device
)
{
   U8  ncq_tag  = 0;
   U32 tag_mask = 1;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_sas_stp_remote_device_allocate_ncq_tag(0x%x)\n",
      fw_device
   ));

   // Try to find an unused NCQ tag.
   while (  (fw_device->protocol_device.stp_device.s_active & tag_mask)
         && (ncq_tag < fw_device->protocol_device.stp_device.sati_device.ncq_depth) )
   {
      tag_mask <<= 1;
      ncq_tag++;
   }

   // Check to see if we were able to find an available NCQ tag.
   if (ncq_tag < fw_device->protocol_device.stp_device.sati_device.ncq_depth)
   {
      SCIF_LOG_INFO((
         sci_base_object_get_logger(fw_device),
         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
         "RemoteDevice:0x%x NcqTag:0x%x successful NCQ TAG allocation\n",
         fw_device, ncq_tag
      ));

      fw_device->protocol_device.stp_device.s_active |= tag_mask;
      return ncq_tag;
   }

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
      "RemoteDevice:0x%x unable to allocate NCQ TAG\n",
      fw_device
   ));

   // All NCQ tags are in use.
   return SCIF_SAS_INVALID_NCQ_TAG;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
/**
 * @brief This method will terminate the requests outstanding in the core
 *        based on the supplied criteria.
 *        - if the all three parameters are specified then only the single
 *          SCIF_SAS_REQUEST object is terminated.
 *        - if only the SCIF_SAS_DOMAIN and SCIF_SAS_REMOTE_DEVICE are
 *          specified, then all SCIF_SAS_REQUEST objects outstanding at
 *          the device are terminated.  The one exclusion to this rule is
 *          that the fw_requestor is not terminated.
 *        - if only the SCIF_SAS_DOMAIN object is specified, then all
 *          SCIF_SAS_REQUEST objects outstanding in the domain are
 *          terminated.
 *
 * @param[in]  fw_domain This parameter specifies the domain in which to
 *             terminate requests.
 * @param[in]  fw_device This parameter specifies the remote device in
 *             which to terminate requests.  This parameter can be NULL
 *             as long as the fw_request parameter is NULL.  It is a
 *             required parameter if the fw_request parameter is not NULL.
 * @param[in]  fw_request This parameter specifies the request object to
 *             be terminated.  This parameter can be NULL.
 * @param[in]  fw_requestor This parameter specifies the task management
 *             request that is responsible for the termination of requests.
 *
 * @return none
 */
void scif_sas_domain_terminate_requests(
   SCIF_SAS_DOMAIN_T        * fw_domain,
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCIF_SAS_REQUEST_T       * fw_request,
   SCIF_SAS_TASK_REQUEST_T  * fw_requestor
)
{
   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_domain),
      SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "scif_sas_domain_terminate_requests(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
      fw_domain, fw_device, fw_request, fw_requestor
   ));

   if (fw_request != NULL)
   {
      fw_request->terminate_requestor = fw_requestor;
      fw_request->state_handlers->abort_handler(&fw_request->parent);
   }
   else
   {
      SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
      SCIF_SAS_REQUEST_T      * request = NULL;

      // Cycle through the fast list of IO requests.  Terminate each
      // outstanding requests that matches the criteria supplied by the
      // caller.
      while (element != NULL)
      {
         request = (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(element);
         // The current element may be deleted from the list becasue of
         // IO completion so advance to the next element early
         element = sci_fast_list_get_next(element);

         // Ensure we pass the supplied criteria before terminating the
         // request.
         if (
               (fw_device == NULL)
            || (
                  (request->device == fw_device)
               && (fw_requestor != (SCIF_SAS_TASK_REQUEST_T*) request)
               )
            )
         {
            if (
                  (request->is_waiting_for_abort_task_set == FALSE) ||
                  (request->terminate_requestor == NULL)
               )
            {
               request->terminate_requestor = fw_requestor;
               request->state_handlers->abort_handler(&request->parent);
            }
         }
      }
   }
}
Ejemplo n.º 25
0
/**
 * @brief This method provides STP PACKET io request STARTED state specific handling for
 *        when the user attempts to complete the supplied IO request.
 *        It will perform data/response translation.
 *
 * @param[in] io_request This parameter specifies the IO request object
 *            to be started.
 *
 * @return This method returns a value indicating if the IO request was
 *         successfully completed or not.
 */
static
SCI_STATUS scif_sas_stp_core_cb_packet_io_request_complete_handler(
   SCIF_SAS_CONTROLLER_T    * fw_controller,
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCIF_SAS_REQUEST_T       * fw_request,
   SCI_STATUS               * completion_status
)
{
   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request;
   SATI_STATUS sati_status;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_controller),
      SCIF_LOG_OBJECT_IO_REQUEST,
      "scif_sas_stp_packet_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
      fw_controller, fw_device, fw_request, *completion_status
   ));

   if (*completion_status == SCI_FAILURE_IO_RESPONSE_VALID)
   {
      sati_status = sati_atapi_translate_command_response(
                       &fw_io->parent.stp.sequence, fw_io, fw_io
                    );

      if (sati_status == SATI_COMPLETE)
         *completion_status = SCI_SUCCESS;
      else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA)
         *completion_status = SCI_FAILURE_IO_RESPONSE_VALID;
      else if (sati_status == SATI_SEQUENCE_INCOMPLETE)
      {
         // The translation indicates that additional REQUEST SENSE command is
         // necessary to finish the original SCSI request.  As a result,
         // do not complete the IO and begin the next stage of the IO.
         return SCI_WARNING_SEQUENCE_INCOMPLETE;
      }
      else
      {
         // Something unexpected occurred during translation.  Fail the
         // IO request to the user.
         *completion_status = SCI_FAILURE;
      }
   }
   else if (*completion_status == SCI_SUCCESS &&
        fw_request->stp.sequence.state == SATI_SEQUENCE_STATE_INCOMPLETE)
   {
      //The internal Request Sense command is completed successfully.
      sati_atapi_translate_request_sense_response(
         &fw_io->parent.stp.sequence, fw_io, fw_io
      );

      *completion_status = SCI_FAILURE_IO_RESPONSE_VALID;
   }

   return SCI_SUCCESS;
}
Ejemplo n.º 26
0
BOOL scic_cb_io_request_do_copy_rx_frames(
   void * scic_user_io_request
)
{
   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_io),
      SCIF_LOG_OBJECT_IO_REQUEST,
      "scic_cb_io_request_do_copy_rx_frames(0x%x) enter\n",
      fw_io
   ));

   // If the translation was a PIO DATA IN (i.e. read) and the request
   // was actually a READ payload operation, then copy the data, since
   // there will be SGL space allocated for the transfer.
   if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_PIO_DATA_IN)
   {
      if (
            (fw_io->parent.stp.sequence.type ==  SATI_SEQUENCE_ATA_PASSTHROUGH_12)
         || (fw_io->parent.stp.sequence.type ==  SATI_SEQUENCE_ATA_PASSTHROUGH_16)
         || (
               (fw_io->parent.stp.sequence.type >= SATI_SEQUENCE_TYPE_READ_MIN)
            && (fw_io->parent.stp.sequence.type <= SATI_SEQUENCE_TYPE_READ_MAX)
            )
         )
      {
           SCIF_LOG_TRACE((
                 sci_base_object_get_logger(fw_io),
                 SCIF_LOG_OBJECT_IO_REQUEST,
                 "scic_cb_io_request_do_copy_rx_frames(0x%x) TRUE\n",
                 fw_io
              ));
           return TRUE;
      }
   }

   // For all other requests we leave the data in the core buffers.
   // This allows the translation to translate without having to have
   // separate space allocated into which to copy the data.
   return FALSE;
}
/**
 * This method will perform the STP request completion processing common
 * to IO requests and task requests of all types
 *
 * @param[in] device This parameter specifies the device for which the
 *            request is being completed.
 * @param[in] request This parameter specifies the request being completed.
 *
 * @return This method returns an indication as to whether the request
 *         processing completed successfully.
 */
static
SCI_STATUS scic_sds_stp_remote_device_complete_request(
   SCI_BASE_REMOTE_DEVICE_T * device,
   SCI_BASE_REQUEST_T       * request
)
{
   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
   SCIC_SDS_REQUEST_T       * the_request = (SCIC_SDS_REQUEST_T *)request;
   SCI_STATUS                 status;

   status = scic_sds_io_request_complete(the_request);

   if (status == SCI_SUCCESS)
   {
      status = scic_sds_port_complete_io(
                  this_device->owning_port, this_device, the_request
               );

      if (status == SCI_SUCCESS)
      {
         scic_sds_remote_device_decrement_request_count(this_device);
         if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED)
         {
            //This request causes hardware error, device needs to be Lun Reset.
            //So here we force the state machine to IDLE state so the rest IOs
            //can reach RNC state handler, these IOs will be completed by RNC with
            //status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
            sci_base_state_machine_change_state(
               &this_device->ready_substate_machine,
               SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
            );
         }
         else if (scic_sds_remote_device_get_request_count(this_device) == 0)
         {
            sci_base_state_machine_change_state(
               &this_device->ready_substate_machine,
               SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
            );
         }
      }
   }

   if (status != SCI_SUCCESS)
   {
      SCIC_LOG_ERROR((
         sci_base_object_get_logger(this_device),
         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
         "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
         this_device->owning_port, this_device, the_request, status
      ));
   }

   return status;
}
Ejemplo n.º 28
0
/**
 * @brief This method performs functionality required after a task management
 *        operation (either a task management request or a silicon task
 *        termination) has finished.
 *
 * @param[in]  fw_task This parameter specifies the request that has
 *             the operation completing.
 *
 * @return none
 */
void scif_sas_task_request_operation_complete(
   SCIF_SAS_TASK_REQUEST_T * fw_task
)
{
   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_task),
      SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "scif_sas_task_request_operation_complete(0x%x) enter\n",
      fw_task
   ));

   fw_task->affected_request_count--;

   SCIF_LOG_INFO((
      sci_base_object_get_logger(fw_task),
      SCIF_LOG_OBJECT_TASK_MANAGEMENT,
      "TaskRequest:0x%x current affected request count:0x%x\n",
      fw_task, fw_task->affected_request_count
   ));
}
Ejemplo n.º 29
0
/**
 * @brief This method will attempt to destruct a framework controller.
 *        This includes free any resources retreived from the user (e.g.
 *        timers).
 *
 * @param[in]  fw_controller This parameter specifies the framework
 *             controller to destructed.
 *
 * @return none
 */
void scif_sas_controller_destruct(
   SCIF_SAS_CONTROLLER_T * fw_controller
)
{
   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_controller),
      SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
      "scif_sas_controller_destruct(0x%x) enter\n",
      fw_controller
   ));
}
/**
 * @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)
   ));
}