/**
 * @brief This method provides handling for failed stp TASK MANAGEMENT
 *           request.
 *
 * @param[in] fw_device This parameter specifies the target device the
 *            task management request towards to.
 * @param[in] fw_request This parameter specifies the failed task management
 *            request.
 * @param[in] completion_status This parameter sprecifies the completion
 *            status of the task management request's core status.
 *
 * @return None.
 */
void scif_sas_stp_task_request_abort_task_set_failure_handler(
   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
   SCIF_SAS_TASK_REQUEST_T  * fw_task
)
{
#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
   SCIF_SAS_DOMAIN_T         * fw_domain = fw_device->domain;
   SCI_FAST_LIST_ELEMENT_T   * pending_request_element;
   SCIF_SAS_REQUEST_T        * pending_request = NULL;

   pending_request_element = fw_domain->request_list.list_head;

   // Cycle through the list of IO requests. search all the
   // outstanding IOs with "waiting for abort task set" flag,
   // completes them now.
   while (pending_request_element != NULL)
   {
      pending_request =
         (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(pending_request_element);

      // The current element may be deleted from the list becasue of
      // IO completion so advance to the next element early
      pending_request_element = sci_fast_list_get_next(pending_request_element);

      if ( pending_request->device == fw_device
           && pending_request->is_waiting_for_abort_task_set == TRUE )
      {
         //In case the pending_request is still in the middle of aborting.
         //abort it again to the core.
         SCI_STATUS abort_status;

         //Reset the flag now since we are process the read log ext command now.
         pending_request->is_waiting_for_abort_task_set = FALSE;

         abort_status = scic_controller_terminate_request(
                           fw_domain->controller->core_object,
                           fw_device->core_object,
                           pending_request->core_object
                        );

         if (abort_status == SCI_FAILURE_INVALID_STATE)
         {
            //the request must have not be in aborting state anymore, complete it now.
            scif_cb_io_request_complete(
               fw_domain->controller,
               fw_device,
               pending_request,
               SCI_IO_FAILURE_TERMINATED
            );
         }
         //otherwise, the abort succeeded. Since the waiting flag is cleared,
         //the pending request will be completed later.
      }
   }
#endif //#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
}
Esempio n. 2
0
void scic_cb_io_request_complete(
   SCI_CONTROLLER_HANDLE_T     controller,
   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
   SCI_IO_REQUEST_HANDLE_T     io_request,
   SCI_IO_STATUS               completion_status
)
{
   SCI_STATUS                 status;
   SCIF_SAS_CONTROLLER_T    * fw_controller = (SCIF_SAS_CONTROLLER_T*)
                                      sci_object_get_association(controller);
   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
                                      sci_object_get_association(remote_device);
   SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*)
                                      sci_object_get_association(io_request);

   SCIF_LOG_TRACE((
      sci_base_object_get_logger(controller),
      SCIF_LOG_OBJECT_IO_REQUEST,
      "scic_cb_io_request_complete(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
      controller, remote_device, io_request, completion_status
   ));

   // Invoke the common completion handler routine.
   // A non-successful return indicates we are not in a correct state to
   // receive a completion notification for this request.
   status = fw_request->state_handlers->complete_handler(&fw_request->parent);

   // If the status indicates the completion handler was successful, then
   // allow protocol specific completion processing to occur.
   if (status == SCI_SUCCESS)
   {
      if (fw_request->protocol_complete_handler != NULL)
      {
         status = fw_request->protocol_complete_handler(
                     fw_controller, fw_device, fw_request, (SCI_STATUS *)&completion_status
                  );
      }

      // If this isn't an internal framework IO request, then simply pass the
      // notification up to the SCIF user.
      if ( status == SCI_SUCCESS )
      {
         if (fw_request->is_high_priority == FALSE)
         {
            if (fw_request->is_waiting_for_abort_task_set == FALSE)
            {
               scif_cb_io_request_complete(
                  fw_controller, fw_device, fw_request, completion_status);
            }
            else
            {
               // do nothing - will complete the I/O when the abort task
               //  set completes
            }
         }
         else
            scif_sas_controller_complete_high_priority_io(
               fw_controller, fw_device, fw_request);
      }
      else if ( status == SCI_WARNING_SEQUENCE_INCOMPLETE )
      {
         scif_sas_io_request_continue(fw_controller, fw_device, fw_request);
      }
   }
}