summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-02 16:45:18 -0800
committerDan Williams <dan.j.williams@intel.com>2011-07-03 03:55:29 -0700
commit27ce51df9a333ca7e05e09f6d25becf26ac1ff45 (patch)
treedbd50cc736c0eeb7e10ee2b15320c9f06b789f02
parentd7628d052242d634dc1e2584c422e690578918a3 (diff)
downloadlinux-stable-27ce51df9a333ca7e05e09f6d25becf26ac1ff45.tar.gz
linux-stable-27ce51df9a333ca7e05e09f6d25becf26ac1ff45.tar.bz2
linux-stable-27ce51df9a333ca7e05e09f6d25becf26ac1ff45.zip
isci: fix hang after target reset
When aborting a task context we need to be sure that the hardware has acted on this request (retrieved the task context) before invalidating the remote node context. In the case of the "dummy" task context and remote node we do not have the full state machine that goes through the complete tc abort and rnc invalidate states. Instead we ensure the hardware has seen and acted on Signed-off-by: Jacek Danecki <Jacek.Danecki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
index 410c9a104bc0..a41fe426ac26 100644
--- a/drivers/scsi/isci/core/scic_sds_port.c
+++ b/drivers/scsi/isci/core/scic_sds_port.c
@@ -1673,12 +1673,6 @@ static void scic_sds_port_ready_substate_waiting_enter(
scic_sds_port_suspend_port_task_scheduler(this_port);
- /* Kill the dummy task for this port if it has not yet posted
- * the hardware will treat this as a NOP and just return abort
- * complete.
- */
- scic_sds_port_abort_dummy_request(this_port);
-
this_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;
if (this_port->active_phy_mask != 0) {
@@ -1744,6 +1738,13 @@ static void scic_sds_port_ready_substate_operational_exit(
{
struct scic_sds_port *this_port = (struct scic_sds_port *)object;
+/*
+ * Kill the dummy task for this port if it has not yet posted
+ * the hardware will treat this as a NOP and just return abort
+ * complete.
+ */
+ scic_sds_port_abort_dummy_request(this_port);
+
isci_event_port_not_ready(
scic_sds_port_get_controller(this_port),
this_port,
@@ -2643,6 +2644,13 @@ void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port)
rnc->ssp.is_valid = false;
+ /* ensure the preceding tc abort request has reached the
+ * controller and give it ample time to act before posting the rnc
+ * invalidate
+ */
+ SMU_ISR_READ(scic); /* flush */
+ udelay(10);
+
command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;