remaining = TUSB_EP_CONFIG_XFR_SIZE(remaining);
 
-       /* HW issue #10: XFR_SIZE may get corrupt on async DMA */
+       /* HW issue #10: XFR_SIZE may get corrupt on DMA (both async & sync) */
        if (unlikely(remaining > chdat->transfer_len)) {
-               WARN("Corrupt XFR_SIZE with DMA: %lu\n", remaining);
+               DBG(2, "Corrupt %s dma ch%i XFR_SIZE: 0x%08lx\n",
+                       chdat->tx ? "tx" : "rx", chdat->ch,
+                       remaining);
                remaining = 0;
        }
 
        channel->actual_len = chdat->transfer_len - remaining;
        pio = chdat->len - channel->actual_len;
 
-       DBG(2, "DMA remaining %lu/%u\n", remaining, chdat->transfer_len);
+       DBG(3, "DMA remaining %lu/%u\n", remaining, chdat->transfer_len);
 
        /* Transfer remaining 1 - 31 bytes */
        if (pio > 0 && pio < 32) {
                u8      *buf;
 
-               DBG(2, "Using PIO for remaining %lu bytes\n", pio);
+               DBG(3, "Using PIO for remaining %lu bytes\n", pio);
                buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
                if (chdat->tx) {
                        consistent_sync(phys_to_virt((u32)chdat->dma_addr),
        void __iomem                    *ep_conf = hw_ep->conf;
        dma_addr_t                      fifo = hw_ep->fifo_sync;
        struct omap_dma_channel_params  dma_params;
+       u32                             dma_remaining;
        int                             src_burst, dst_burst;
        u16                             csr;
        int                             ch;
        if (dma_addr & 0x2)
                return false;
 
+       /*
+        * Because of HW issue #10, it seems like mixing sync DMA and async
+        * PIO access can confuse the DMA. Make sure XFR_SIZE is reset before
+        * using the channel for DMA.
+        */
+       if (chdat->tx)
+               dma_remaining = musb_readl(ep_conf, TUSB_EP_TX_OFFSET);
+       else
+               dma_remaining = musb_readl(ep_conf, TUSB_EP_RX_OFFSET);
+
+       dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
+       if (dma_remaining) {
+               DBG(2, "Busy %s dma ch%i, not using: %08x\n",
+                       chdat->tx ? "tx" : "rx", chdat->ch,
+                       dma_remaining);
+               return false;
+       }
+
+
        chdat->transfer_len = len & ~0x1f;
 
        if (len < packet_sz)