|
@@ -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 */ ;
|