summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Olson <dave.olson@qlogic.com>2008-04-16 21:09:29 -0700
committerRoland Dreier <rolandd@cisco.com>2008-04-16 21:09:29 -0700
commit555b203e48faeacc0373eda7bc87db874db37136 (patch)
tree84148fb8547b17125c9934b3d8f0decaf4441198
parent9355fb6a064723c71e80e9c78de3140b43bfb52d (diff)
IB/ipath: Make link state transition code ignore (transient) link recovery
The hardware-based recovery doesn't need any intervention, and in a few cases we can get a bit confused about state and skip steps such as turning off the link state LED when we consider recovery to be "down". So ignore this transition, and either we recover in hardware, or we transition to down, and will handle it then. Signed-off-by: Dave Olson <dave.olson@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 826b96b39952..3bad601fcc90 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -300,6 +300,18 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
ltstate = ipath_ib_linktrstate(dd, ibcs); /* linktrainingtate */
/*
+ * Since going into a recovery state causes the link state to go
+ * down and since recovery is transitory, it is better if we "miss"
+ * ever seeing the link training state go into recovery (i.e.,
+ * ignore this transition for link state special handling purposes)
+ * without even updating ipath_lastibcstat.
+ */
+ if ((ltstate == INFINIPATH_IBCS_LT_STATE_RECOVERRETRAIN) ||
+ (ltstate == INFINIPATH_IBCS_LT_STATE_RECOVERWAITRMT) ||
+ (ltstate == INFINIPATH_IBCS_LT_STATE_RECOVERIDLE))
+ goto done;
+
+ /*
* if linkstate transitions into INIT from any of the various down
* states, or if it transitions from any of the up (INIT or better)
* states into any of the down states (except link recovery), then
@@ -316,7 +328,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
}
} else if ((lastlstate >= INFINIPATH_IBCS_L_STATE_INIT ||
(dd->ipath_flags & IPATH_IB_FORCE_NOTIFY)) &&
- ltstate <= INFINIPATH_IBCS_LT_STATE_CFGDEBOUNCE &&
+ ltstate <= INFINIPATH_IBCS_LT_STATE_CFGWAITRMT &&
ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) {
int handled;
handled = dd->ipath_f_ib_updown(dd, 0, ibcs);
@@ -460,6 +472,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
skip_ibchange:
dd->ipath_lastibcstat = ibcs;
+done:
+ return;
}
static void handle_supp_msgs(struct ipath_devdata *dd,