remaining = musb_readl(ep_conf, TUSB_EP_RX_OFFSET);
remaining = TUSB_EP_CONFIG_XFR_SIZE(remaining);
+
+ /* HW issue #10: XFR_SIZE may get corrupt on async DMA */
+ if (unlikely(remaining > chdat->transfer_len)) {
+ WARN("Corrupt XFR_SIZE with async DMA: %lu\n", remaining);
+ remaining = 0;
+ }
+
channel->dwActualLength = chdat->transfer_len - remaining;
pio = chdat->len - channel->dwActualLength;
if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
return FALSE;
+ /*
+ * HW issue #10: Async dma will eventually corrupt the XFR_SIZE
+ * register which will cause missed DMA interrupt. We could try to
+ * use a timer for the callback, but it is unsafe as the XFR_SIZE
+ * register is corrupt, and we won't know if the DMA worked.
+ */
+ if (dma_addr & 0x2)
+ return FALSE;
+
chdat->transfer_len = len & ~0x1f;
if (len < packet_sz)