diff options
author | Jeff Skirvin <jeffrey.d.skirvin@intel.com> | 2012-03-09 01:41:58 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2012-05-17 17:33:40 -0400 |
commit | c94fc1ad25de885e1c59f714f19bc726e7a21caf (patch) | |
tree | f522804dabddeb78304384f897264f731588eab0 /drivers/scsi/isci | |
parent | d6b2a0e4a066ea51322e16e66b25028cb0b4ca7e (diff) |
isci: Distinguish between remote device suspension cases
For NCQ error conditions among others, there is no need to enable
the link layer hang detect timer.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 27 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.c | 19 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.h | 5 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 2 |
4 files changed, 28 insertions, 25 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index b14eff3c76d0..cc8ab69a2022 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -72,10 +72,11 @@ const char *dev_state_name(enum sci_remote_device_states state) | |||
72 | } | 72 | } |
73 | #undef C | 73 | #undef C |
74 | 74 | ||
75 | static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev) | 75 | static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, |
76 | enum sci_remote_node_suspension_reasons reason) | ||
76 | { | 77 | { |
77 | return sci_remote_node_context_suspend(&idev->rnc, | 78 | return sci_remote_node_context_suspend(&idev->rnc, |
78 | SCI_SOFTWARE_SUSPENSION, | 79 | reason, |
79 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, | 80 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, |
80 | NULL, NULL); | 81 | NULL, NULL); |
81 | } | 82 | } |
@@ -199,7 +200,7 @@ static void isci_remote_device_not_ready(struct isci_host *ihost, | |||
199 | set_bit(IDEV_IO_NCQERROR, &idev->flags); | 200 | set_bit(IDEV_IO_NCQERROR, &idev->flags); |
200 | 201 | ||
201 | /* Suspend the remote device so the I/O can be terminated. */ | 202 | /* Suspend the remote device so the I/O can be terminated. */ |
202 | sci_remote_device_suspend(idev); | 203 | sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL); |
203 | 204 | ||
204 | /* Kill all outstanding requests for the device. */ | 205 | /* Kill all outstanding requests for the device. */ |
205 | sci_remote_device_terminate_requests(idev); | 206 | sci_remote_device_terminate_requests(idev); |
@@ -268,7 +269,8 @@ enum sci_status sci_remote_device_stop(struct isci_remote_device *idev, | |||
268 | rnc_destruct_done, | 269 | rnc_destruct_done, |
269 | idev); | 270 | idev); |
270 | else { | 271 | else { |
271 | sci_remote_device_suspend(idev); | 272 | sci_remote_device_suspend( |
273 | idev, SCI_SW_SUSPEND_LINKHANG_DETECT); | ||
272 | sci_remote_device_terminate_requests(idev); | 274 | sci_remote_device_terminate_requests(idev); |
273 | } | 275 | } |
274 | return SCI_SUCCESS; | 276 | return SCI_SUCCESS; |
@@ -473,11 +475,7 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, | |||
473 | status = SCI_SUCCESS; | 475 | status = SCI_SUCCESS; |
474 | 476 | ||
475 | /* Suspend the associated RNC */ | 477 | /* Suspend the associated RNC */ |
476 | sci_remote_node_context_suspend( | 478 | sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL); |
477 | &idev->rnc, | ||
478 | SCI_SOFTWARE_SUSPENSION, | ||
479 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, | ||
480 | NULL, NULL); | ||
481 | 479 | ||
482 | dev_dbg(scirdev_to_dev(idev), | 480 | dev_dbg(scirdev_to_dev(idev), |
483 | "%s: device: %p event code: %x: %s\n", | 481 | "%s: device: %p event code: %x: %s\n", |
@@ -789,9 +787,8 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost, | |||
789 | * the correct action when the remote node context is suspended | 787 | * the correct action when the remote node context is suspended |
790 | * and later resumed. | 788 | * and later resumed. |
791 | */ | 789 | */ |
792 | sci_remote_node_context_suspend( | 790 | sci_remote_device_suspend(idev, |
793 | &idev->rnc, SCI_SOFTWARE_SUSPENSION, | 791 | SCI_SW_SUSPEND_LINKHANG_DETECT); |
794 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL); | ||
795 | 792 | ||
796 | status = sci_remote_node_context_start_task(&idev->rnc, ireq, | 793 | status = sci_remote_node_context_start_task(&idev->rnc, ireq, |
797 | sci_remote_device_continue_request, idev); | 794 | sci_remote_device_continue_request, idev); |
@@ -986,9 +983,7 @@ static void sci_remote_device_resetting_state_enter(struct sci_base_state_machin | |||
986 | dev_dbg(&ihost->pdev->dev, | 983 | dev_dbg(&ihost->pdev->dev, |
987 | "%s: isci_device = %p\n", __func__, idev); | 984 | "%s: isci_device = %p\n", __func__, idev); |
988 | 985 | ||
989 | sci_remote_node_context_suspend( | 986 | sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT); |
990 | &idev->rnc, SCI_SOFTWARE_SUSPENSION, | ||
991 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL); | ||
992 | } | 987 | } |
993 | 988 | ||
994 | static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm) | 989 | static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm) |
@@ -1486,7 +1481,7 @@ enum sci_status isci_remote_device_suspend_terminate( | |||
1486 | 1481 | ||
1487 | /* Put the device into suspension. */ | 1482 | /* Put the device into suspension. */ |
1488 | spin_lock_irqsave(&ihost->scic_lock, flags); | 1483 | spin_lock_irqsave(&ihost->scic_lock, flags); |
1489 | sci_remote_device_suspend(idev); | 1484 | sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT); |
1490 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 1485 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
1491 | 1486 | ||
1492 | /* Terminate and wait for the completions. */ | 1487 | /* Terminate and wait for the completions. */ |
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c index adbb4b80d9e4..85bf5ec26417 100644 --- a/drivers/scsi/isci/remote_node_context.c +++ b/drivers/scsi/isci/remote_node_context.c | |||
@@ -52,7 +52,7 @@ | |||
52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
54 | */ | 54 | */ |
55 | 55 | #include <scsi/sas_ata.h> | |
56 | #include "host.h" | 56 | #include "host.h" |
57 | #include "isci.h" | 57 | #include "isci.h" |
58 | #include "remote_device.h" | 58 | #include "remote_device.h" |
@@ -315,7 +315,7 @@ static void sci_remote_node_context_ready_state_enter(struct sci_base_state_mach | |||
315 | if ((dest_select == RNC_DEST_SUSPENDED) || | 315 | if ((dest_select == RNC_DEST_SUSPENDED) || |
316 | (dest_select == RNC_DEST_SUSPENDED_RESUME)) { | 316 | (dest_select == RNC_DEST_SUSPENDED_RESUME)) { |
317 | sci_remote_node_context_suspend( | 317 | sci_remote_node_context_suspend( |
318 | rnc, SCI_SOFTWARE_SUSPENSION, | 318 | rnc, SCI_SW_SUSPEND_NORMAL, |
319 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL); | 319 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL); |
320 | 320 | ||
321 | if (dest_select == RNC_DEST_SUSPENDED_RESUME) { | 321 | if (dest_select == RNC_DEST_SUSPENDED_RESUME) { |
@@ -352,8 +352,10 @@ static void sci_remote_node_context_await_suspend_state_exit( | |||
352 | { | 352 | { |
353 | struct sci_remote_node_context *rnc | 353 | struct sci_remote_node_context *rnc |
354 | = container_of(sm, typeof(*rnc), sm); | 354 | = container_of(sm, typeof(*rnc), sm); |
355 | struct isci_remote_device *idev = rnc_to_dev(rnc); | ||
355 | 356 | ||
356 | isci_dev_set_hang_detection_timeout(rnc_to_dev(rnc), 0); | 357 | if (dev_is_sata(idev->domain_dev)) |
358 | isci_dev_set_hang_detection_timeout(idev, 0); | ||
357 | } | 359 | } |
358 | 360 | ||
359 | static const struct sci_base_state sci_remote_node_context_state_table[] = { | 361 | static const struct sci_base_state sci_remote_node_context_state_table[] = { |
@@ -556,7 +558,7 @@ enum sci_status sci_remote_node_context_suspend( | |||
556 | suspend_type); | 558 | suspend_type); |
557 | 559 | ||
558 | /* Disable automatic state continuations if explicitly suspending. */ | 560 | /* Disable automatic state continuations if explicitly suspending. */ |
559 | if ((suspend_reason != SCI_SOFTWARE_SUSPENSION) || | 561 | if ((suspend_reason == SCI_HW_SUSPEND) || |
560 | (sci_rnc->destination_state == RNC_DEST_FINAL)) | 562 | (sci_rnc->destination_state == RNC_DEST_FINAL)) |
561 | dest_param = sci_rnc->destination_state; | 563 | dest_param = sci_rnc->destination_state; |
562 | 564 | ||
@@ -612,8 +614,13 @@ enum sci_status sci_remote_node_context_suspend( | |||
612 | wake_up_all(&ihost->eventq); /* Let observers look. */ | 614 | wake_up_all(&ihost->eventq); /* Let observers look. */ |
613 | return SCI_SUCCESS; | 615 | return SCI_SUCCESS; |
614 | } | 616 | } |
615 | if (suspend_reason == SCI_SOFTWARE_SUSPENSION) { | 617 | if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) || |
616 | isci_dev_set_hang_detection_timeout(idev, 0x00000001); | 618 | (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) { |
619 | |||
620 | if ((suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT) | ||
621 | && dev_is_sata(idev->domain_dev)) | ||
622 | isci_dev_set_hang_detection_timeout(idev, 0x00000001); | ||
623 | |||
617 | sci_remote_device_post_request( | 624 | sci_remote_device_post_request( |
618 | idev, SCI_SOFTWARE_SUSPEND_CMD); | 625 | idev, SCI_SOFTWARE_SUSPEND_CMD); |
619 | } | 626 | } |
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h index 48319066b4d6..364da3722aa4 100644 --- a/drivers/scsi/isci/remote_node_context.h +++ b/drivers/scsi/isci/remote_node_context.h | |||
@@ -76,8 +76,9 @@ | |||
76 | #define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF | 76 | #define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF |
77 | 77 | ||
78 | enum sci_remote_node_suspension_reasons { | 78 | enum sci_remote_node_suspension_reasons { |
79 | SCU_HARDWARE_SUSPENSION, | 79 | SCI_HW_SUSPEND, |
80 | SCI_SOFTWARE_SUSPENSION | 80 | SCI_SW_SUSPEND_NORMAL, |
81 | SCI_SW_SUSPEND_LINKHANG_DETECT | ||
81 | }; | 82 | }; |
82 | #define SCI_SOFTWARE_SUSPEND_CMD SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX | 83 | #define SCI_SOFTWARE_SUSPEND_CMD SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
83 | #define SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT SCU_EVENT_TL_RNC_SUSPEND_TX_RX | 84 | #define SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT SCU_EVENT_TL_RNC_SUSPEND_TX_RX |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 662f36de8052..48b409d68c0d 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -2380,7 +2380,7 @@ static void sci_request_handle_suspending_completions( | |||
2380 | 2380 | ||
2381 | sci_remote_node_context_suspend( | 2381 | sci_remote_node_context_suspend( |
2382 | &ireq->target_device->rnc, | 2382 | &ireq->target_device->rnc, |
2383 | SCU_HARDWARE_SUSPENSION, | 2383 | SCI_HW_SUSPEND, |
2384 | (is_tx_rx) ? SCU_EVENT_TL_RNC_SUSPEND_TX_RX | 2384 | (is_tx_rx) ? SCU_EVENT_TL_RNC_SUSPEND_TX_RX |
2385 | : SCU_EVENT_TL_RNC_SUSPEND_TX, | 2385 | : SCU_EVENT_TL_RNC_SUSPEND_TX, |
2386 | NULL, NULL); | 2386 | NULL, NULL); |