]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/hw/ipath/ipath_intr.c
IB/ipath: Better comment for rmb() in ipath_intr()
[linux-2.6-omap-h63xx.git] / drivers / infiniband / hw / ipath / ipath_intr.c
index c61f9da2964ab25a51bb686808ffaa3c4ceb1e33..4795cb895f8577100fb8126a2aaa5bc8fd59769e 100644 (file)
@@ -795,6 +795,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd)
 {
        int i, im;
        __le64 val;
+       unsigned long flags;
 
        /* disable error interrupts, to avoid confusion */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL);
@@ -813,11 +814,14 @@ void ipath_clear_freeze(struct ipath_devdata *dd)
                         dd->ipath_control);
 
        /* ensure pio avail updates continue */
+       spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
                 dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD);
        ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                dd->ipath_sendctrl);
+                        dd->ipath_sendctrl);
+       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+       spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
        /*
         * We just enabled pioavailupdate, so dma copy is almost certainly
@@ -849,7 +853,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd)
 
 /* this is separate to allow for better optimization of ipath_intr() */
 
-static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp)
+static noinline void ipath_bad_intr(struct ipath_devdata *dd, u32 *unexpectp)
 {
        /*
         * sometimes happen during driver init and unload, don't want
@@ -892,7 +896,7 @@ static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp)
                          "ignoring\n");
 }
 
-static void ipath_bad_regread(struct ipath_devdata *dd)
+static noinline void ipath_bad_regread(struct ipath_devdata *dd)
 {
        static int allbits;
 
@@ -920,31 +924,9 @@ static void ipath_bad_regread(struct ipath_devdata *dd)
        }
 }
 
-static void handle_port_pioavail(struct ipath_devdata *dd)
-{
-       u32 i;
-       /*
-        * start from port 1, since for now port 0  is never using
-        * wait_event for PIO
-        */
-       for (i = 1; dd->ipath_portpiowait && i < dd->ipath_cfgports; i++) {
-               struct ipath_portdata *pd = dd->ipath_pd[i];
-
-               if (pd && pd->port_cnt &&
-                   dd->ipath_portpiowait & (1U << i)) {
-                       clear_bit(i, &dd->ipath_portpiowait);
-                       if (test_bit(IPATH_PORT_WAITING_PIO,
-                                    &pd->port_flag)) {
-                               clear_bit(IPATH_PORT_WAITING_PIO,
-                                         &pd->port_flag);
-                               wake_up_interruptible(&pd->port_wait);
-                       }
-               }
-       }
-}
-
 static void handle_layer_pioavail(struct ipath_devdata *dd)
 {
+       unsigned long flags;
        int ret;
 
        ret = ipath_ib_piobufavail(dd->verbs_dev);
@@ -953,9 +935,12 @@ static void handle_layer_pioavail(struct ipath_devdata *dd)
 
        return;
 set:
-       set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
+       spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
+       dd->ipath_sendctrl |= INFINIPATH_S_PIOINTBUFAVAIL;
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
                         dd->ipath_sendctrl);
+       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+       spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 }
 
 /*
@@ -969,7 +954,15 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
        int i;
        int rcvdint = 0;
 
-       /* test_bit below needs this... */
+       /*
+        * test_and_clear_bit(IPATH_PORT_WAITING_RCV) and
+        * test_and_clear_bit(IPATH_PORT_WAITING_URG) below
+        * would both like timely updates of the bits so that
+        * we don't pass them by unnecessarily.  the rmb()
+        * here ensures that we see them promptly -- the
+        * corresponding wmb()'s are in ipath_poll_urgent()
+        * and ipath_poll_next()...
+        */
        rmb();
        portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) &
                 dd->ipath_i_rcvavail_mask)
@@ -1191,12 +1184,14 @@ irqreturn_t ipath_intr(int irq, void *data)
                handle_urcv(dd, istat);
 
        if (istat & INFINIPATH_I_SPIOBUFAVAIL) {
-               clear_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
+               unsigned long flags;
+
+               spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
+               dd->ipath_sendctrl &= ~INFINIPATH_S_PIOINTBUFAVAIL;
                ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
                                 dd->ipath_sendctrl);
-
-               if (dd->ipath_portpiowait)
-                       handle_port_pioavail(dd);
+               ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+               spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
                handle_layer_pioavail(dd);
        }