[ofa-general] [PATCH 13/28] IB/ipath - Fix the mtrr_add args for chips with 2 buffer sizes

Arthur Jones arthur.jones at qlogic.com
Tue Jun 19 16:41:45 PDT 2007


From: Dave Olson <dave.olson at qlogic.com>

The values passed have never been right for iba 6120 chips, but
just happened to work.  We needed to select the right buffer
offset in the chip (both are in same register), and the total
length was wrong also, but was covered by the rounding up.

Signed-off-by: Dave Olson <dave.olson at qlogic.com>
---

 drivers/infiniband/hw/ipath/ipath_wc_x86_64.c |   27 ++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
index 04696e6..9f409fd 100644
--- a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
+++ b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
@@ -63,12 +63,29 @@ int ipath_enable_wc(struct ipath_devdata *dd)
 	 * of 2 address matching the length (which has to be a power of 2).
 	 * For rev1, that means the base address, for rev2, it will be just
 	 * the PIO buffers themselves.
+	 * For chips with two sets of buffers, the calculations are
+	 * somewhat more complicated; we need to sum, and the piobufbase
+	 * register has both offsets, 2K in low 32 bits, 4K in high 32 bits.
+	 * The buffers are still packed, so a single range covers both.
 	 */
-	pioaddr = addr + dd->ipath_piobufbase;
-	piolen = (dd->ipath_piobcnt2k +
-		  dd->ipath_piobcnt4k) *
-		ALIGN(dd->ipath_piobcnt2k +
-		      dd->ipath_piobcnt4k, dd->ipath_palign);
+	if (dd->ipath_piobcnt2k && dd->ipath_piobcnt4k) { /* 2 sizes */
+		unsigned long pio2kbase, pio4kbase;
+		pio2kbase = dd->ipath_piobufbase & 0xffffffffUL;
+		pio4kbase = (dd->ipath_piobufbase >> 32) & 0xffffffffUL;
+		if (pio2kbase < pio4kbase) { /* all, for now */
+			pioaddr = addr + pio2kbase;
+			piolen = pio4kbase - pio2kbase +
+				dd->ipath_piobcnt4k * dd->ipath_4kalign;
+		} else {
+			pioaddr = addr + pio4kbase;
+			piolen = pio2kbase - pio4kbase +
+				dd->ipath_piobcnt2k * dd->ipath_palign;
+		}
+	} else {  /* single buffer size (2K, currently) */
+		pioaddr = addr + dd->ipath_piobufbase;
+		piolen = dd->ipath_piobcnt2k * dd->ipath_palign +
+			dd->ipath_piobcnt4k * dd->ipath_4kalign;
+	}
 
 	for (bits = 0; !(piolen & (1ULL << bits)); bits++)
 		/* do nothing */ ;




More information about the general mailing list