IB/ipath: Allow more flexible user register alignments
authorRalph Campbell <ralph.campbell@qlogic.com>
Mon, 7 Jan 2008 05:02:34 +0000 (21:02 -0800)
committerRoland Dreier <rolandd@cisco.com>
Fri, 25 Jan 2008 22:15:39 +0000 (14:15 -0800)
User registers have different alignments on different chips (4KB on
older, 64KB on 7220).  Allow mapping the user registers on kernels with
page sizes up to 64K.

Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_iba6110.c
drivers/infiniband/hw/ipath/ipath_iba6120.c
drivers/infiniband/hw/ipath/ipath_kernel.h

index 9e5714d68ee1d8486b2bc2119d36fb171d3f56b0..0b877ed76712f5b105461741f4d7725da10038fb 100644 (file)
@@ -169,7 +169,7 @@ static int ipath_get_base_info(struct file *fp,
                kinfo->spi_piocnt = dd->ipath_pbufsport;
                kinfo->spi_piobufbase = (u64) pd->port_piobufs;
                kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
-                       dd->ipath_palign * pd->port_port;
+                       dd->ipath_ureg_align * pd->port_port;
        } else if (master) {
                kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) +
                                    (dd->ipath_pbufsport % subport_cnt);
@@ -186,7 +186,7 @@ static int ipath_get_base_info(struct file *fp,
        }
        if (shared) {
                kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase +
-                       dd->ipath_palign * pd->port_port;
+                       dd->ipath_ureg_align * pd->port_port;
                kinfo->spi_port_rcvegrbuf = kinfo->spi_rcv_egrbufs;
                kinfo->spi_port_rcvhdr_base = kinfo->spi_rcvhdr_base;
                kinfo->spi_port_rcvhdr_tailaddr = kinfo->spi_rcvhdr_tailaddr;
@@ -1271,7 +1271,7 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
                goto bail;
        }
 
-       ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+       ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port;
        if (!pd->port_subport_cnt) {
                /* port is not shared */
                piocnt = dd->ipath_pbufsport;
index dffb6826579a2e9af96050daf7ebb12c0a4a72f7..5ecf65b8f85a829a68f3400eea5c89e64374d0be 100644 (file)
@@ -739,6 +739,13 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
                              dd->ipath_htspeed);
        ret = 0;
 
+       /*
+        * set here, not in ipath_init_*_funcs because we have to do
+        * it after we can read chip registers.
+        */
+       dd->ipath_ureg_align =
+               ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign);
+
 bail:
        return ret;
 }
index 66925b255ccd4ffe14234881e7ceb4fde6594f1d..23de8da0f16b360121b05fcfcc2cb78adf33f684 100644 (file)
@@ -613,6 +613,14 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
                        dd->ipath_f_put_tid = ipath_pe_put_tid_2;
        }
 
+
+       /*
+        * set here, not in ipath_init_*_funcs because we have to do
+        * it after we can read chip registers.
+        */
+       dd->ipath_ureg_align =
+               ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign);
+
        return ret;
 }
 
index 4f7bc08796bcbf543efa6d1825a0aa4301e3fef0..08272bef24759d48268c8f0334e7422ee632cda0 100644 (file)
@@ -395,6 +395,8 @@ struct ipath_devdata {
        void *ipath_dummy_hdrq; /* used after port close */
        dma_addr_t ipath_dummy_hdrq_phys;
 
+       unsigned long ipath_ureg_align; /* user register alignment */
+
        /*
         * Shadow copies of registers; size indicates read access size.
         * Most of them are readonly, but some are write-only register,
@@ -865,7 +867,7 @@ static inline u32 ipath_read_ureg32(const struct ipath_devdata *dd,
        return readl(regno + (u64 __iomem *)
                     (dd->ipath_uregbase +
                      (char __iomem *)dd->ipath_kregbase +
-                     dd->ipath_palign * port));
+                     dd->ipath_ureg_align * port));
 }
 
 /**
@@ -882,7 +884,7 @@ static inline void ipath_write_ureg(const struct ipath_devdata *dd,
 {
        u64 __iomem *ubase = (u64 __iomem *)
                (dd->ipath_uregbase + (char __iomem *) dd->ipath_kregbase +
-                dd->ipath_palign * port);
+                dd->ipath_ureg_align * port);
        if (dd->ipath_kregbase)
                writeq(value, &ubase[regno]);
 }