aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-09 01:41:58 -0500
committerDan Williams <dan.j.williams@intel.com>2012-05-17 17:33:40 -0400
commitc94fc1ad25de885e1c59f714f19bc726e7a21caf (patch)
treef522804dabddeb78304384f897264f731588eab0 /drivers
parentd6b2a0e4a066ea51322e16e66b25028cb0b4ca7e (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')
-rw-r--r--drivers/scsi/isci/remote_device.c27
-rw-r--r--drivers/scsi/isci/remote_node_context.c19
-rw-r--r--drivers/scsi/isci/remote_node_context.h5
-rw-r--r--drivers/scsi/isci/request.c2
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
75static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev) 75static 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
994static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm) 989static 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
359static const struct sci_base_state sci_remote_node_context_state_table[] = { 361static 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
78enum sci_remote_node_suspension_reasons { 78enum 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);