isci: unify remote_device frame_handlers
authorDan Williams <dan.j.williams@intel.com>
Sun, 1 May 2011 23:51:11 +0000 (16:51 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sun, 3 Jul 2011 11:04:45 +0000 (04:04 -0700)
Implement all states in scic_sds_remote_device_frame() and delete
the state handler.

Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/scsi/isci/remote_device.c
drivers/scsi/isci/remote_device.h

index 53f4ecf..0295349 100644 (file)
@@ -277,20 +277,96 @@ enum sci_status scic_sds_remote_device_suspend(struct scic_sds_remote_device *sc
                                                    suspend_type, NULL, NULL);
 }
 
-/**
- *
- * @sci_dev: The remote device for which the event handling is being
- *    requested.
- * @frame_index: This is the frame index that is being processed.
- *
- * This method invokes the frame handler for the remote device state machine
- * enum sci_status
- */
-enum sci_status scic_sds_remote_device_frame_handler(
-       struct scic_sds_remote_device *sci_dev,
-       u32 frame_index)
+enum sci_status scic_sds_remote_device_frame_handler(struct scic_sds_remote_device *sci_dev,
+                                                    u32 frame_index)
 {
-       return sci_dev->state_handlers->frame_handler(sci_dev, frame_index);
+       struct sci_base_state_machine *sm = &sci_dev->state_machine;
+       enum scic_sds_remote_device_states state = sm->current_state_id;
+       struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller;
+       enum sci_status status;
+
+       switch (state) {
+       case SCI_BASE_REMOTE_DEVICE_STATE_INITIAL:
+       case SCI_BASE_REMOTE_DEVICE_STATE_STOPPED:
+       case SCI_BASE_REMOTE_DEVICE_STATE_STARTING:
+       case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
+       case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
+       case SCI_BASE_REMOTE_DEVICE_STATE_FINAL:
+       default:
+               dev_warn(scirdev_to_dev(sci_dev), "%s: in wrong state: %d\n",
+                        __func__, state);
+               /* Return the frame back to the controller */
+               scic_sds_controller_release_frame(scic, frame_index);
+               return SCI_FAILURE_INVALID_STATE;
+       case SCI_BASE_REMOTE_DEVICE_STATE_READY:
+       case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR:
+       case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET:
+       case SCI_BASE_REMOTE_DEVICE_STATE_STOPPING:
+       case SCI_BASE_REMOTE_DEVICE_STATE_FAILED:
+       case SCI_BASE_REMOTE_DEVICE_STATE_RESETTING: {
+               struct scic_sds_request *sci_req;
+               struct sci_ssp_frame_header *hdr;
+
+               status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
+                                                                      frame_index,
+                                                                      (void **)&hdr);
+               if (status != SCI_SUCCESS)
+                       return status;
+
+               sci_req = scic_sds_controller_get_io_request_from_tag(scic, hdr->tag);
+               if (sci_req && sci_req->target_device == sci_dev) {
+                       /* The IO request is now in charge of releasing the frame */
+                       status = sci_req->state_handlers->frame_handler(sci_req,
+                                                                       frame_index);
+               } else {
+                       /* We could not map this tag to a valid IO
+                        * request Just toss the frame and continue
+                        */
+                       scic_sds_controller_release_frame(scic, frame_index);
+               }
+               break;
+       }
+       case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ: {
+               struct sata_fis_header *hdr;
+
+               status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
+                                                                      frame_index,
+                                                                      (void **)&hdr);
+               if (status != SCI_SUCCESS)
+                       return status;
+
+               if (hdr->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
+                   (hdr->status & ATA_STATUS_REG_ERROR_BIT)) {
+                       sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
+
+                       /* TODO Check sactive and complete associated IO if any. */
+                       sci_base_state_machine_change_state(sm, SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
+               } else if (hdr->fis_type == SATA_FIS_TYPE_REGD2H &&
+                          (hdr->status & ATA_STATUS_REG_ERROR_BIT)) {
+                       /*
+                        * Some devices return D2H FIS when an NCQ error is detected.
+                        * Treat this like an SDB error FIS ready reason.
+                        */
+                       sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
+                       sci_base_state_machine_change_state(&sci_dev->state_machine,
+                                                           SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
+               } else
+                       status = SCI_FAILURE;
+
+               scic_sds_controller_release_frame(scic, frame_index);
+               break;
+       }
+       case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
+       case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
+               /* The device does not process any UF received from the hardware while
+                * in this state.  All unsolicited frames are forwarded to the io request
+                * object.
+                */
+               status = scic_sds_io_request_frame_handler(sci_dev->working_request, frame_index);
+               break;
+       }
+
+       return status;
 }
 
 static bool is_remote_device_ready(struct scic_sds_remote_device *sci_dev)
@@ -720,136 +796,6 @@ static void remote_device_resume_done(void *_dev)
                                            SCI_BASE_REMOTE_DEVICE_STATE_READY);
 }
 
-/**
- *
- * @device: The struct scic_sds_remote_device which is then cast into a
- *    struct scic_sds_remote_device.
- * @frame_index: The frame index for which the struct scic_sds_controller wants this
- *    device object to process.
- *
- * This method is the default unsolicited frame handler.  It logs a warning,
- * releases the frame and returns a failure. enum sci_status
- * SCI_FAILURE_INVALID_STATE
- */
-static enum sci_status scic_sds_remote_device_default_frame_handler(
-       struct scic_sds_remote_device *sci_dev,
-       u32 frame_index)
-{
-       dev_warn(scirdev_to_dev(sci_dev),
-                "%s: SCIC Remote Device requested to handle frame %x "
-                "while in wrong state %d\n",
-                __func__,
-                frame_index,
-                sci_base_state_machine_get_state(
-                        &sci_dev->state_machine));
-
-       /* Return the frame back to the controller */
-       scic_sds_controller_release_frame(
-               scic_sds_remote_device_get_controller(sci_dev), frame_index
-               );
-
-       return SCI_FAILURE_INVALID_STATE;
-}
-
-/**
- *
- * @device: The struct scic_sds_remote_device which is then cast into a
- *    struct scic_sds_remote_device.
- * @frame_index: The frame index for which the struct scic_sds_controller wants this
- *    device object to process.
- *
- * This method is a general ssp frame handler.  In most cases the device object
- * needs to route the unsolicited frame processing to the io request object.
- * This method decodes the tag for the io request object and routes the
- * unsolicited frame to that object. enum sci_status SCI_FAILURE_INVALID_STATE
- */
-static enum sci_status scic_sds_remote_device_general_frame_handler(
-       struct scic_sds_remote_device *sci_dev,
-       u32 frame_index)
-{
-       enum sci_status result;
-       struct sci_ssp_frame_header *frame_header;
-       struct scic_sds_request *io_request;
-
-       result = scic_sds_unsolicited_frame_control_get_header(
-               &(scic_sds_remote_device_get_controller(sci_dev)->uf_control),
-               frame_index,
-               (void **)&frame_header
-               );
-
-       if (SCI_SUCCESS == result) {
-               io_request = scic_sds_controller_get_io_request_from_tag(
-                       scic_sds_remote_device_get_controller(sci_dev), frame_header->tag);
-
-               if ((io_request == NULL)
-                   || (io_request->target_device != sci_dev)) {
-                       /*
-                        * We could not map this tag to a valid IO request
-                        * Just toss the frame and continue */
-                       scic_sds_controller_release_frame(
-                               scic_sds_remote_device_get_controller(sci_dev), frame_index
-                               );
-               } else {
-                       /* The IO request is now in charge of releasing the frame */
-                       result = io_request->state_handlers->frame_handler(
-                               io_request, frame_index);
-               }
-       }
-
-       return result;
-}
-
-static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev,
-                                                                                  u32 frame_index)
-{
-       enum sci_status status;
-       struct sata_fis_header *frame_header;
-       struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller;
-
-       status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
-                                                              frame_index,
-                                                              (void **)&frame_header);
-       if (status != SCI_SUCCESS)
-               return status;
-
-       if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
-           (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
-               sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
-
-               /* TODO Check sactive and complete associated IO if any. */
-
-               sci_base_state_machine_change_state(&sci_dev->state_machine,
-                                                   SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
-       } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H &&
-                  (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
-               /*
-                * Some devices return D2H FIS when an NCQ error is detected.
-                * Treat this like an SDB error FIS ready reason.
-                */
-               sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
-
-               sci_base_state_machine_change_state(&sci_dev->state_machine,
-                                                   SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
-       } else
-               status = SCI_FAILURE;
-
-       scic_sds_controller_release_frame(scic, frame_index);
-
-       return status;
-}
-
-static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
-       struct scic_sds_remote_device *sci_dev,
-       u32 frame_index)
-{
-       /* The device doe not process any UF received from the hardware while
-        * in this state.  All unsolicited frames are forwarded to the io
-        * request object.
-        */
-       return scic_sds_io_request_frame_handler(sci_dev->working_request,
-                                                frame_index);
-}
-
 static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *_dev)
 {
        struct scic_sds_remote_device *sci_dev = _dev;
@@ -863,69 +809,36 @@ static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handl
                isci_remote_device_ready(scic->ihost, idev);
 }
 
-static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handler(
-       struct scic_sds_remote_device *sci_dev,
-       u32 frame_index)
-{
-       enum sci_status status;
-
-       /* The device does not process any UF received from the hardware while
-        * in this state.  All unsolicited frames are forwarded to the io request
-        * object.
-        */
-       status = scic_sds_io_request_frame_handler(
-               sci_dev->working_request,
-               frame_index
-               );
-
-       return status;
-}
-
 static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = {
        [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
-               .frame_handler          = scic_sds_remote_device_default_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
-               .frame_handler          = scic_sds_remote_device_default_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
-               .frame_handler          = scic_sds_remote_device_default_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
-               .frame_handler          = scic_sds_remote_device_general_frame_handler,
        },
        [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
-               .frame_handler                  = scic_sds_remote_device_default_frame_handler
        },
        [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
-               .frame_handler                  = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
        },
        [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
-               .frame_handler                  = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
        },
        [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
-               .frame_handler                  = scic_sds_remote_device_general_frame_handler
        },
        [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
-               .frame_handler                  = scic_sds_remote_device_general_frame_handler
        },
        [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
-               .frame_handler          = scic_sds_remote_device_default_frame_handler
        },
        [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
-               .frame_handler          = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = {
-               .frame_handler          = scic_sds_remote_device_general_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
-               .frame_handler          = scic_sds_remote_device_general_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
-               .frame_handler          = scic_sds_remote_device_general_frame_handler
        },
        [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
-               .frame_handler          = scic_sds_remote_device_default_frame_handler
        }
 };
 
index e376ec2..1577b12 100644 (file)
@@ -386,7 +386,6 @@ typedef void (*scic_sds_remote_device_ready_not_ready_handler_t)(
  *
  */
 struct scic_sds_remote_device_state_handler {
-       scic_sds_remote_device_frame_handler_t frame_handler;
 };
 
 /**