Пример #1
0
/**
 * @brief This routine destructs a smp phy object for an expander phy and free the smp
 *           phy to controller's smp phy memory.
 * @param[in] this_smp_phy The smp phy to be destructed.
 *
 * @return None
 */
void scif_sas_smp_phy_destruct(
   SCIF_SAS_SMP_PHY_T       * this_smp_phy
)
{
   SCIF_SAS_REMOTE_DEVICE_T * owning_device = this_smp_phy->owning_device;
   SCIF_SAS_CONTROLLER_T * fw_controller = owning_device->domain->controller;

   if ( ( this_smp_phy->attached_device_type == SMP_EDGE_EXPANDER_DEVICE
         || this_smp_phy->attached_device_type == SMP_FANOUT_EXPANDER_DEVICE)
       && this_smp_phy->u.attached_phy != NULL )
   {
      //update the counterpart phy from the other smp phy list.
      this_smp_phy->u.attached_phy->attached_device_type = SMP_NO_DEVICE_ATTACHED;
      this_smp_phy->u.attached_phy->u.attached_phy = NULL;
   }

   //remove curr_smp_phy
   sci_fast_list_remove_element(&this_smp_phy->list_element);
   scif_sas_controller_free_smp_phy(fw_controller, this_smp_phy);
}
Пример #2
0
/**
 * @brief This method retry the external smp request.
 *
 * @param[in] fw_device This parameter specifies the remote device for
 *            which the internal IO request is destined.
 * @param[in] old_internal_io This parameter specifies the old smp request to be
 *            retried.
 *
 * @return none.
 */
SCI_STATUS scif_sas_smp_external_request_retry(
   SCIF_SAS_IO_REQUEST_T    * old_io
)
{
   SCIF_SAS_REMOTE_DEVICE_T * fw_device = old_io->parent.device;
   SCIF_SAS_CONTROLLER_T * fw_controller;
   SCIF_SAS_IO_REQUEST_T * new_io;
   void                  * new_request_memory = NULL;
   U8                      retry_count = old_io->retry_count;

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(fw_device),
      SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
      "scif_sas_smp_external_request_retry(0x%x) time %d!\n",
      old_io
   ));

   fw_controller = fw_device->domain->controller;

   // Before we construct new io using the same memory, we need to
   // remove the IO from the list of outstanding requests on the domain
   // so that we don't damage the domain's fast list of request.
   sci_fast_list_remove_element(&old_io->parent.list_element);

   switch (fw_device->protocol_device.smp_device.current_smp_request)
   {
      case SMP_FUNCTION_DISCOVER:
         //we are retrying an external io, we are going to reuse the
         //old io's memory. new_request_memory is same as old_io.
         new_request_memory = scif_sas_smp_request_construct_discover(
            fw_controller, fw_device,
            fw_device->protocol_device.smp_device.current_activity_phy_index,
            (void *)sci_object_get_association(old_io),
            (void *)old_io
         );

         break;

      case SMP_FUNCTION_PHY_CONTROL:
         //Phy Control command always uses external io memory.
         new_request_memory = scif_sas_smp_request_construct_phy_control(
            fw_controller, fw_device, PHY_OPERATION_HARD_RESET,
            fw_device->protocol_device.smp_device.current_activity_phy_index,
            (void *)sci_object_get_association(old_io),
            (void *)old_io
         );

         break;

      default:
         //unsupported case, TBD
         return SCI_FAILURE;
   } //end of switch

   //set the retry count to new built smp request.
   new_io = (SCIF_SAS_IO_REQUEST_T *) new_request_memory;
   new_io->retry_count = ++retry_count;

   //put into the high priority queue.
   sci_pool_put(fw_controller->hprq.pool, (POINTER_UINT) new_request_memory);

   //schedule the DPC to start new io.
   scif_cb_start_internal_io_task_schedule(
      fw_controller, scif_sas_controller_start_high_priority_io, fw_controller
   );

   return SCI_SUCCESS;
}