One person working on a mass-storage driver (the usb protocol side, not the block subsystem side) ran into a bug in how a bit of net2280 dma automagic was handled.
This patch fixes it by calling existing dma chain patchup code when the dma engine was forced to "hiccup" by having a not-yet-valid entry in it. The hiccup is needed in this case since the IN data stage mustn't terminate with a short transfer (zero length packet); but the status stage is always a short packet. The "terminate with short packet" bit is endpoint state, not request state, so IN dma queues sometimes need this kind of fixup.
Please merge.
- Dave
--- 1.28/drivers/usb/gadget/net2280.c Sat Aug 23 19:04:48 2003
+++ edited/net2280.c Thu Aug 28 08:26:28 2003
@@ -2431,6 +2431,28 @@
if ((tmp & (1 << DMA_SCATTER_GATHER_ENABLE)) == 0
|| (tmp & (1 << DMA_ENABLE)) == 0)
restart_dma (ep);
+#ifdef USE_DMA_CHAINING
+ else if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+ struct net2280_request *req;
+ u32 dmacount;
+
+ /* the descriptor at the head of the chain
+ * may still have VALID_BIT clear; that's
+ * used to trigger changing DMA_FIFO_VALIDATE
+ * (affects automagic zlp writes).
+ */
+ req = list_entry (ep->queue.next,
+ struct net2280_request, queue);
+ dmacount = req->td->dmacount;
+ dmacount &= __constant_cpu_to_le32 (
+ (1 << VALID_BIT)
+ | DMA_BYTE_COUNT_MASK);
+ if (dmacount && (dmacount & valid_bit) == 0) {
+ stop_dma (ep->dma);
+ restart_dma (ep);
+ }
+ }
+#endif
}
ep->irqs++;
}
