spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
                skip_cancel =
-                       !test_bit(IPATH_SDMA_DISABLED, statp) &&
-                       test_and_set_bit(IPATH_SDMA_ABORTING, statp);
+                       test_and_set_bit(IPATH_SDMA_ABORTING, statp)
+                       && !test_bit(IPATH_SDMA_DISABLED, statp);
                spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
                if (skip_cancel)
                        goto bail;
        ipath_disarm_piobufs(dd, 0,
                dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
 
+       if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
+               set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
+
        if (restore_sendctrl) {
                /* else done by caller later if needed */
                spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
                /* only wait so long for intr */
                dd->ipath_sdma_abort_intr_timeout = jiffies + HZ;
                dd->ipath_sdma_reset_wait = 200;
-               __set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
                if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
                        tasklet_hi_schedule(&dd->ipath_sdma_abort_task);
                spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
 
                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;
                /* 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;
        }
 
                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;
        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;
 }