Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / infiniband / hw / ipath / ipath_init_chip.c
index 414cdd1..dc83250 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. 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
@@ -36,7 +35,7 @@
 #include <linux/vmalloc.h>
 
 #include "ipath_kernel.h"
-#include "ipath_common.h"
+#include "ips_common.h"
 
 /*
  * min buffers we want to have per port, after driver
@@ -115,7 +114,6 @@ static int create_port0_egr(struct ipath_devdata *dd)
                                      "eager TID %u\n", e);
                        while (e != 0)
                                dev_kfree_skb(skbs[--e]);
-                       vfree(skbs);
                        ret = -ENOMEM;
                        goto bail;
                }
@@ -277,7 +275,7 @@ static int init_chip_first(struct ipath_devdata *dd,
        pd->port_port = 0;
        pd->port_cnt = 1;
        /* The port 0 pkey table is used by the layer interface. */
-       pd->port_pkeys[0] = IPATH_DEFAULT_P_KEY;
+       pd->port_pkeys[0] = IPS_DEFAULT_P_KEY;
        dd->ipath_rcvtidcnt =
                ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt);
        dd->ipath_rcvtidbase =
@@ -411,8 +409,17 @@ static int init_pioavailregs(struct ipath_devdata *dd)
        /* and its length */
        dd->ipath_freezelen = L1_CACHE_BYTES - sizeof(dd->ipath_statusp[0]);
 
-       ret = 0;
+       if (dd->ipath_unit * 64 > (IPATH_PORT0_RCVHDRTAIL_SIZE - 64)) {
+               ipath_dev_err(dd, "unit %u too large for port 0 "
+                             "rcvhdrtail buffer size\n", dd->ipath_unit);
+               ret = -ENODEV;
+       }
+       else
+               ret = 0;
 
+       /* so we can get current tail in ipath_kreceive(), per chip */
+       dd->ipath_hdrqtailptr = &ipath_port0_rcvhdrtail[
+               dd->ipath_unit * (64 / sizeof(*ipath_port0_rcvhdrtail))];
 done:
        return ret;
 }
@@ -645,9 +652,8 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
 {
        int ret = 0, i;
        u32 val32, kpiobufs;
-       u64 val;
+       u64 val, atmp;
        struct ipath_portdata *pd = NULL; /* keep gcc4 happy */
-       gfp_t gfp_flags = GFP_USER | __GFP_COMP;
 
        ret = init_housekeeping(dd, &pd, reinit);
        if (ret)
@@ -769,6 +775,24 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
                goto done;
        }
 
+       val = ipath_port0_rcvhdrtail_dma + dd->ipath_unit * 64;
+
+       /* verify that the alignment requirement was met */
+       ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdrtailaddr,
+                             0, val);
+       atmp = ipath_read_kreg64_port(
+               dd, dd->ipath_kregs->kr_rcvhdrtailaddr, 0);
+       if (val != atmp) {
+               ipath_dev_err(dd, "Catastrophic software error, "
+                             "RcvHdrTailAddr0 written as %llx, "
+                             "read back as %llx from %x\n",
+                             (unsigned long long) val,
+                             (unsigned long long) atmp,
+                             dd->ipath_kregs->kr_rcvhdrtailaddr);
+               ret = -EINVAL;
+               goto done;
+       }
+
        ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvbthqp, IPATH_KD_QP);
 
        /*
@@ -812,45 +836,25 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
        /* clear any interrups up to this point (ints still not enabled) */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL);
 
+       ipath_stats.sps_lid[dd->ipath_unit] = dd->ipath_lid;
+
        /*
         * Set up the port 0 (kernel) rcvhdr q and egr TIDs.  If doing
         * re-init, the simplest way to handle this is to free
         * existing, and re-allocate.
         */
-       if (reinit) {
-               struct ipath_portdata *pd = dd->ipath_pd[0];
-               dd->ipath_pd[0] = NULL;
-               ipath_free_pddata(dd, pd);
-       }
+       if (reinit)
+               ipath_free_pddata(dd, 0, 0);
        dd->ipath_f_tidtemplate(dd);
        ret = ipath_create_rcvhdrq(dd, pd);
-       if (!ret) {
-               dd->ipath_hdrqtailptr =
-                       (volatile __le64 *)pd->port_rcvhdrtail_kvaddr;
+       if (!ret)
                ret = create_port0_egr(dd);
-       }
        if (ret)
                ipath_dev_err(dd, "failed to allocate port 0 (kernel) "
                              "rcvhdrq and/or egr bufs\n");
        else
                enable_chip(dd, pd, reinit);
 
-
-       if (!ret && !reinit) {
-           /* used when we close a port, for DMA already in flight at close */
-               dd->ipath_dummy_hdrq = dma_alloc_coherent(
-                       &dd->pcidev->dev, pd->port_rcvhdrq_size,
-                       &dd->ipath_dummy_hdrq_phys,
-                       gfp_flags);
-               if (!dd->ipath_dummy_hdrq ) {
-                       dev_info(&dd->pcidev->dev,
-                               "Couldn't allocate 0x%lx bytes for dummy hdrq\n",
-                               pd->port_rcvhdrq_size);
-                       /* fallback to just 0'ing */
-                       dd->ipath_dummy_hdrq_phys = 0UL;
-               }
-       }
-
        /*
         * cause retrigger of pending interrupts ignored during init,
         * even if we had errors