include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / infiniband / hw / ipath / ipath_sdma.c
index 0d07682..98ac18e 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
@@ -263,14 +264,10 @@ static void sdma_abort_task(unsigned long opaque)
                hwstatus = ipath_read_kreg64(dd,
                                dd->ipath_kregs->kr_senddmastatus);
 
-               if (/* ScoreBoardDrainInProg */
-                   test_bit(63, &hwstatus) ||
-                   /* AbortInProg */
-                   test_bit(62, &hwstatus) ||
-                   /* InternalSDmaEnable */
-                   test_bit(61, &hwstatus) ||
-                   /* ScbEmpty */
-                   !test_bit(30, &hwstatus)) {
+               if ((hwstatus & (IPATH_SDMA_STATUS_SCORE_BOARD_DRAIN_IN_PROG |
+                                IPATH_SDMA_STATUS_ABORT_IN_PROG             |
+                                IPATH_SDMA_STATUS_INTERNAL_SDMA_ENABLE)) ||
+                   !(hwstatus & IPATH_SDMA_STATUS_SCB_EMPTY)) {
                        if (dd->ipath_sdma_reset_wait > 0) {
                                /* not done shutting down sdma */
                                --dd->ipath_sdma_reset_wait;
@@ -308,13 +305,15 @@ static void sdma_abort_task(unsigned long opaque)
                spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
 
                /*
-                * Don't restart sdma here. Wait until link is up to ACTIVE.
-                * VL15 MADs used to bring the link up use PIO, and multiple
-                * link transitions otherwise cause the sdma engine to be
+                * Don't restart sdma here (with the exception
+                * below). Wait until link is up to ACTIVE.  VL15 MADs
+                * used to bring the link up use PIO, and multiple link
+                * transitions otherwise cause the sdma engine to be
                 * stopped and started multiple times.
-                * The disable is done here, including the shadow, so the
-                * state is kept consistent.
-                * See ipath_restart_sdma() for the actual starting of sdma.
+                * The disable is done here, including the shadow,
+                * so the state is kept consistent.
+                * See ipath_restart_sdma() for the actual starting
+                * of sdma.
                 */
                spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
                dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE;
@@ -326,6 +325,13 @@ static void sdma_abort_task(unsigned long opaque)
                /* make sure I see next message */
                dd->ipath_sdma_abort_jiffies = 0;
 
+               /*
+                * Not everything that takes SDMA offline is a link
+                * status change.  If the link was up, restart SDMA.
+                */
+               if (dd->ipath_flags & IPATH_LINKACTIVE)
+                       ipath_restart_sdma(dd);
+
                goto done;
        }
 
@@ -336,7 +342,7 @@ resched:
         * state change
         */
        if (jiffies > dd->ipath_sdma_abort_jiffies) {
-               ipath_dbg("looping with status 0x%016llx\n",
+               ipath_dbg("looping with status 0x%08lx\n",
                          dd->ipath_sdma_status);
                dd->ipath_sdma_abort_jiffies = jiffies + 5 * HZ;
        }
@@ -427,7 +433,12 @@ int setup_sdma(struct ipath_devdata *dd)
                goto done;
        }
 
-       dd->ipath_sdma_status = 0;
+       /*
+        * Set initial status as if we had been up, then gone down.
+        * This lets initial start on transition to ACTIVE be the
+        * same as restart after link flap.
+        */
+       dd->ipath_sdma_status = IPATH_SDMA_ABORT_ABORTED;
        dd->ipath_sdma_abort_jiffies = 0;
        dd->ipath_sdma_generation = 0;
        dd->ipath_sdma_descq_tail = 0;
@@ -601,7 +612,7 @@ void ipath_restart_sdma(struct ipath_devdata *dd)
        }
        spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
        if (!needed) {
-               ipath_dbg("invalid attempt to restart SDMA, status 0x%016llx\n",
+               ipath_dbg("invalid attempt to restart SDMA, status 0x%08lx\n",
                        dd->ipath_sdma_status);
                goto bail;
        }
@@ -618,6 +629,9 @@ void ipath_restart_sdma(struct ipath_devdata *dd)
        ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
        spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
+       /* notify upper layers */
+       ipath_ib_piobufavail(dd->verbs_dev);
+
 bail:
        return;
 }
@@ -685,10 +699,8 @@ retry:
 
        addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr,
                              tx->map_len, DMA_TO_DEVICE);
-       if (dma_mapping_error(addr)) {
-               ret = -EIO;
-               goto unlock;
-       }
+       if (dma_mapping_error(&dd->pcidev->dev, addr))
+               goto ioerr;
 
        dwoffset = tx->map_len >> 2;
        make_sdma_desc(dd, sdmadesc, (u64) addr, dwoffset, 0);
@@ -728,6 +740,8 @@ retry:
                dw = (len + 3) >> 2;
                addr = dma_map_single(&dd->pcidev->dev, sge->vaddr, dw << 2,
                                      DMA_TO_DEVICE);
+               if (dma_mapping_error(&dd->pcidev->dev, addr))
+                       goto unmap;
                make_sdma_desc(dd, sdmadesc, (u64) addr, dw, dwoffset);
                /* SDmaUseLargeBuf has to be set in every descriptor */
                if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_USELARGEBUF)
@@ -768,10 +782,10 @@ retry:
                descqp = &dd->ipath_sdma_descq[dd->ipath_sdma_descq_cnt].qw[0];
        descqp -= 2;
        /* SDmaLastDesc */
-       descqp[0] |= __constant_cpu_to_le64(1ULL << 11);
+       descqp[0] |= cpu_to_le64(1ULL << 11);
        if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_INTREQ) {
                /* SDmaIntReq */
-               descqp[0] |= __constant_cpu_to_le64(1ULL << 15);
+               descqp[0] |= cpu_to_le64(1ULL << 15);
        }
 
        /* Commit writes to memory and advance the tail on the chip */
@@ -785,7 +799,18 @@ retry:
        list_add_tail(&tx->txreq.list, &dd->ipath_sdma_activelist);
        if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_VL15)
                vl15_watchdog_enq(dd);
-
+       goto unlock;
+
+unmap:
+       while (tail != dd->ipath_sdma_descq_tail) {
+               if (!tail)
+                       tail = dd->ipath_sdma_descq_cnt - 1;
+               else
+                       tail--;
+               unmap_desc(dd, tail);
+       }
+ioerr:
+       ret = -EIO;
 unlock:
        spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
 fail: