From b0be3b6cc195ba732189b04f1d43ec843c3e54c9 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Mon, 12 Jul 2010 13:19:48 +0200 Subject: [PATCH] MUSB - Fix mode 0 DMA, and last mode 1 packet: - Set TXPKTRDY in the dma callback, to force the last packet to be sent. --- drivers/usb/musb/musb_gadget.c | 23 +++++++++++++++-------- drivers/usb/musb/musbhsdma.c | 23 +++++++++++++---------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 82bcb0d..7349873 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -495,17 +495,22 @@ void musb_g_tx(struct musb *musb, u8 epnum) } if (is_dma || request->actual == request->length) { +#ifdef CONFIG_USB_INVENTRA_DMA + if (is_dma && (!dma->desired_mode || + ((request->actual % + musb_ep->packet_sz) != 0))) { + DBG(4, "Flushing FIFO...\n"); + musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_FLUSHFIFO); + return; + } +#endif + /* * First, maybe a terminating short packet. Some DMA * engines might handle this by themselves. */ if ((request->zero && request->length && request->length % musb_ep->packet_sz == 0) -#ifdef CONFIG_USB_INVENTRA_DMA - || (is_dma && (!dma->desired_mode || - (request->actual & - (musb_ep->packet_sz - 1)))) -#endif ) { /* * On DMA completion, FIFO may not be @@ -514,9 +519,11 @@ void musb_g_tx(struct musb *musb, u8 epnum) if (csr & MUSB_TXCSR_TXPKTRDY) return; - DBG(4, "sending zero pkt\n"); - musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE - | MUSB_TXCSR_TXPKTRDY); + DBG(4, "sending zero pkt (zero=%d, length=%d, actual=%d, " + "dma->desired_mode=%d)\n", + request->zero, request->length, request->actual, + dma->desired_mode); + musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_TXPKTRDY); request->zero = 0; } diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 22a2978..76c3d09 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -530,12 +530,12 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) channel->status = MUSB_DMA_STATUS_FREE; /* completed */ - if ((devctl & MUSB_DEVCTL_HM) - && (musb_channel->transmit) - && ((channel->desired_mode == 0) - || (channel->actual_len & - (musb_channel->max_packet_sz - 1))) - ) { + if ((musb_channel->transmit) + && ( + (channel->desired_mode == 0) || + ((channel->actual_len % + musb_channel->max_packet_sz) != 0)) + ) { u8 epnum = musb_channel->epnum; int offset = MUSB_EP_OFFSET(epnum, MUSB_TXCSR); @@ -547,11 +547,14 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) */ musb_ep_select(mbase, epnum); txcsr = musb_readw(mbase, offset); - txcsr &= ~(MUSB_TXCSR_DMAENAB + if (channel->desired_mode == 1) { + txcsr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_AUTOSET); - musb_writew(mbase, offset, txcsr); - /* Send out the packet */ - txcsr &= ~MUSB_TXCSR_DMAMODE; + musb_writew(mbase, offset, txcsr); + /* Send out the packet */ + txcsr &= ~MUSB_TXCSR_DMAMODE; + txcsr |= MUSB_TXCSR_DMAENAB; + } txcsr |= MUSB_TXCSR_TXPKTRDY; musb_writew(mbase, offset, txcsr); } -- 2.1.4