Commit e7379aaa authored by Ming Lei's avatar Ming Lei Committed by Greg Kroah-Hartman

usb: musb: gadget: fix ZLP sending in musb_g_tx(v1)

This patch fixes the problem reported by Sergei:

>how come? we need to send ZLP before giving back the request.
>Well, look at the code ionce again. We need to send ZLP *after*
>request->actual == request->length, but as the check is inserted
>after the ZLP send, ZLP *may* be sent once the first DMA completes,
>not the last.

The patch also has been discussed on the link below:

	http://marc.info/?t=128454814900001&r=1&w=2Signed-off-by: default avatarMing Lei <tom.leiming@gmail.com>
Reported-by: default avatarSergei Shtylyov <sshtylyov@mvista.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent a6038ee7
...@@ -477,40 +477,39 @@ void musb_g_tx(struct musb *musb, u8 epnum) ...@@ -477,40 +477,39 @@ void musb_g_tx(struct musb *musb, u8 epnum)
epnum, csr, musb_ep->dma->actual_len, request); epnum, csr, musb_ep->dma->actual_len, request);
} }
if (is_dma || request->actual == request->length) { /*
/* * First, maybe a terminating short packet. Some DMA
* First, maybe a terminating short packet. Some DMA * engines might handle this by themselves.
* engines might handle this by themselves. */
*/ if ((request->zero && request->length
if ((request->zero && request->length && (request->length % musb_ep->packet_sz == 0)
&& request->length % musb_ep->packet_sz == 0) && (request->actual == request->length))
#ifdef CONFIG_USB_INVENTRA_DMA #ifdef CONFIG_USB_INVENTRA_DMA
|| (is_dma && (!dma->desired_mode || || (is_dma && (!dma->desired_mode ||
(request->actual & (request->actual &
(musb_ep->packet_sz - 1)))) (musb_ep->packet_sz - 1))))
#endif #endif
) { ) {
/* /*
* On DMA completion, FIFO may not be * On DMA completion, FIFO may not be
* available yet... * available yet...
*/ */
if (csr & MUSB_TXCSR_TXPKTRDY) if (csr & MUSB_TXCSR_TXPKTRDY)
return; return;
DBG(4, "sending zero pkt\n"); DBG(4, "sending zero pkt\n");
musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE
| MUSB_TXCSR_TXPKTRDY); | MUSB_TXCSR_TXPKTRDY);
request->zero = 0; request->zero = 0;
} }
if (request->actual == request->length) { if (request->actual == request->length) {
musb_g_giveback(musb_ep, request, 0); musb_g_giveback(musb_ep, request, 0);
request = musb_ep->desc ? next_request(musb_ep) : NULL; request = musb_ep->desc ? next_request(musb_ep) : NULL;
if (!request) { if (!request) {
DBG(4, "%s idle now\n", DBG(4, "%s idle now\n",
musb_ep->end_point.name); musb_ep->end_point.name);
return; return;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment