summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_diag.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 08:20:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 08:20:06 -0700
commit75e98b34155264d943aa53edce465e87f3ccbadf (patch)
tree08d100a14ab9f5314c393286ce8c5436ef387d75 /drivers/infiniband/hw/ipath/ipath_diag.c
parent30bc94566e396b432b72e2f3518e19225dc2672d (diff)
parent0a22ab92f51478796d5f3997f4f5922409c98b10 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (104 commits) IB/iser: Don't change itt endianness IB/mlx4: Update module version and release date IPoIB: Handle case when P_Key is deleted and re-added at same index IB/iser: Release connection resources on RDMA_CM_EVENT_DEVICE_REMOVAL event IB/mlx4: Fix incorrect comment IB/mlx4: Fix race when detaching a QP from a multicast group IB/ehca: Support all ibv_devinfo values in query_device() and query_port() RDMA/nes: Free IRQ before killing tasklet IB/mthca: Update module version and release date IB/mlx4: Update QP state if query QP succeeds IB/mthca: Update QP state if query QP succeeds RDMA/amso1100: Add check for NULL reply_msg in c2_intr() IB/mlx4: Add support for resizing CQs IB/mlx4: Add support for modifying CQ moderation parameters IPoIB: Support modifying IPoIB CQ event moderation IB/core: Add support for modify CQ IPoIB: Add basic ethtool support mlx4_core: Increase max number of QPs to 128K RDMA/amso1100: Add support for "send with invalidate" work requests IB/core: Add support for "send with invalidate" work requests ...
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_diag.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_diag.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c
index 4137c7770f1..6d49d2f18a8 100644
--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
@@ -330,13 +330,19 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
struct ipath_devdata *dd;
ssize_t ret = 0;
u64 val;
+ u32 l_state, lt_state; /* LinkState, LinkTrainingState */
- if (count != sizeof(dp)) {
+ if (count < sizeof(odp)) {
ret = -EINVAL;
goto bail;
}
- if (copy_from_user(&dp, data, sizeof(dp))) {
+ if (count == sizeof(dp)) {
+ if (copy_from_user(&dp, data, sizeof(dp))) {
+ ret = -EFAULT;
+ goto bail;
+ }
+ } else if (copy_from_user(&odp, data, sizeof(odp))) {
ret = -EFAULT;
goto bail;
}
@@ -396,10 +402,17 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
ret = -ENODEV;
goto bail;
}
- /* Check link state, but not if we have custom PBC */
- val = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK;
- if (!dp.pbc_wd && val != IPATH_IBSTATE_INIT &&
- val != IPATH_IBSTATE_ARM && val != IPATH_IBSTATE_ACTIVE) {
+ /*
+ * Want to skip check for l_state if using custom PBC,
+ * because we might be trying to force an SM packet out.
+ * first-cut, skip _all_ state checking in that case.
+ */
+ val = ipath_ib_state(dd, dd->ipath_lastibcstat);
+ lt_state = ipath_ib_linktrstate(dd, dd->ipath_lastibcstat);
+ l_state = ipath_ib_linkstate(dd, dd->ipath_lastibcstat);
+ if (!dp.pbc_wd && (lt_state != INFINIPATH_IBCS_LT_STATE_LINKUP ||
+ (val != dd->ib_init && val != dd->ib_arm &&
+ val != dd->ib_active))) {
ipath_cdbg(VERBOSE, "unit %u not ready (state %llx)\n",
dd->ipath_unit, (unsigned long long) val);
ret = -EINVAL;
@@ -431,15 +444,17 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
goto bail;
}
- piobuf = ipath_getpiobuf(dd, &pbufn);
+ plen >>= 2; /* in dwords */
+
+ piobuf = ipath_getpiobuf(dd, plen, &pbufn);
if (!piobuf) {
ipath_cdbg(VERBOSE, "No PIO buffers avail unit for %u\n",
dd->ipath_unit);
ret = -EBUSY;
goto bail;
}
-
- plen >>= 2; /* in dwords */
+ /* disarm it just to be extra sure */
+ ipath_disarm_piobufs(dd, pbufn, 1);
if (ipath_debug & __IPATH_PKTDBG)
ipath_cdbg(VERBOSE, "unit %u 0x%x+1w pio%d\n",