ChangeSet 1.1276.1.58, 2003/08/28 10:53:17-07:00, david-b@pacbell.net [PATCH] USB: net2280, patch dma chains 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. drivers/usb/gadget/net2280.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c --- a/drivers/usb/gadget/net2280.c Tue Sep 2 12:42:59 2003 +++ b/drivers/usb/gadget/net2280.c Tue Sep 2 12:42:59 2003 @@ -2432,6 +2432,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++; }