]> Pileus Git - ~andy/linux/commitdiff
isci: Restore the ATAPI device RNC management code.
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>
Fri, 9 Mar 2012 06:42:09 +0000 (22:42 -0800)
committerDan Williams <dan.j.williams@intel.com>
Thu, 17 May 2012 21:33:43 +0000 (14:33 -0700)
The ATAPI specific and STP general RNC suspension code had been
incorrectly removed from the remote device code.

Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/scsi/isci/remote_device.c
drivers/scsi/isci/remote_device.h
drivers/scsi/isci/request.c

index 68ab4fb9032e7aa1ea68a69802ee3c4ce98aa03a..48765aa8432851f8bb38941af53ccc97832d191d 100644 (file)
@@ -72,8 +72,8 @@ const char *dev_state_name(enum sci_remote_device_states state)
 }
 #undef C
 
-static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
-                                                enum sci_remote_node_suspension_reasons reason)
+enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
+                                         enum sci_remote_node_suspension_reasons reason)
 {
        return sci_remote_node_context_suspend(&idev->rnc, reason,
                                               SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT);
@@ -565,6 +565,8 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev,
                                                     u32 event_code)
 {
        enum sci_status status;
+       struct sci_base_state_machine *sm = &idev->sm;
+       enum sci_remote_device_states state = sm->current_state_id;
 
        switch (scu_get_event_type(event_code)) {
        case SCU_EVENT_TYPE_RNC_OPS_MISC:
@@ -603,6 +605,30 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev,
        if (status != SCI_SUCCESS)
                return status;
 
+       /* Decode device-specific states that may require an RNC resume during
+        * normal operation.  When the abort path is active, these resumes are
+        * managed when the abort path exits.
+        */
+       if (state == SCI_STP_DEV_ATAPI_ERROR) {
+               /* For ATAPI error state resume the RNC right away. */
+               if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
+                   scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
+                       return sci_remote_node_context_resume(&idev->rnc,
+                                                             atapi_remote_device_resume_done,
+                                                             idev);
+               }
+       }
+
+       if (state == SCI_STP_DEV_IDLE) {
+
+               /* We pick up suspension events to handle specifically to this
+                * state. We resume the RNC right away.
+                */
+               if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
+                   scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
+                       status = sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
+       }
+
        return status;
 }
 
@@ -1137,21 +1163,6 @@ static void sci_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base
                                             idev->not_ready_reason);
 }
 
-static void sci_stp_remote_device_atapi_error_substate_enter(
-       struct sci_base_state_machine *sm)
-{
-       struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
-
-       /* This state is entered when an I/O is decoded with an error
-        * condition.  By this point the RNC expected suspension state is set.
-        * The error conditions suspend the device, so unsuspend here if
-        * possible.
-        */
-       sci_remote_node_context_resume(&idev->rnc,
-                                      atapi_remote_device_resume_done,
-                                      idev);
-}
-
 static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
 {
        struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
@@ -1202,9 +1213,7 @@ static const struct sci_base_state sci_remote_device_state_table[] = {
        [SCI_STP_DEV_NCQ_ERROR] = {
                .enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter,
        },
-       [SCI_STP_DEV_ATAPI_ERROR] = {
-               .enter_state = sci_stp_remote_device_atapi_error_substate_enter,
-       },
+       [SCI_STP_DEV_ATAPI_ERROR] = { },
        [SCI_STP_DEV_AWAIT_RESET] = { },
        [SCI_SMP_DEV_IDLE] = {
                .enter_state = sci_smp_remote_device_ready_idle_substate_enter,
index ff34c4e8c1b16f32741bddf7cd1a1ccad9d8c3fe..7674caae1d88bac82520c65b0cd6004e19db626f 100644 (file)
@@ -382,4 +382,6 @@ enum sci_status isci_remote_device_terminate_requests(
        struct isci_host *ihost,
        struct isci_remote_device *idev,
        struct isci_request *ireq);
+enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
+                                         enum sci_remote_node_suspension_reasons reason);
 #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */
index 415d5f55d1c634e6fd1cf32c3b6a0c629d47ba69..6c530e4275e2dfd0b3c718dee1fb45e439eaea6d 100644 (file)
@@ -2118,6 +2118,9 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq
                 * completion.
                 */
                if (ireq->stp.rsp.fis_type == FIS_REGD2H) {
+                       sci_remote_device_suspend(ireq->target_device,
+                                                 SCI_SW_SUSPEND_NORMAL);
+
                        ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
                        ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
                        sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);