aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2010-09-24 06:44:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:21:56 -0400
commite7379aaa5ca12f9e011eb5a6bcba88e9bbbfbf87 (patch)
tree50509fa9b9da211ad2ce342d11e7a376544a8327 /drivers/usb/musb
parenta6038ee76a29ea31f8aae4eb6c419794c739e077 (diff)
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=2 Signed-off-by: Ming Lei <tom.leiming@gmail.com> Reported-by: Sergei 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: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/musb_gadget.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 6a8c061b66f1..3f1cc5a8381f 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -477,40 +477,39 @@ void musb_g_tx(struct musb *musb, u8 epnum)
477 epnum, csr, musb_ep->dma->actual_len, request); 477 epnum, csr, musb_ep->dma->actual_len, request);
478 } 478 }
479 479
480 if (is_dma || request->actual == request->length) { 480 /*
481 /* 481 * First, maybe a terminating short packet. Some DMA
482 * First, maybe a terminating short packet. Some DMA 482 * engines might handle this by themselves.
483 * engines might handle this by themselves. 483 */
484 */ 484 if ((request->zero && request->length
485 if ((request->zero && request->length 485 && (request->length % musb_ep->packet_sz == 0)
486 && request->length % musb_ep->packet_sz == 0) 486 && (request->actual == request->length))
487#ifdef CONFIG_USB_INVENTRA_DMA 487#ifdef CONFIG_USB_INVENTRA_DMA
488 || (is_dma && (!dma->desired_mode || 488 || (is_dma && (!dma->desired_mode ||
489 (request->actual & 489 (request->actual &
490 (musb_ep->packet_sz - 1)))) 490 (musb_ep->packet_sz - 1))))
491#endif 491#endif
492 ) { 492 ) {
493 /* 493 /*
494 * On DMA completion, FIFO may not be 494 * On DMA completion, FIFO may not be
495 * available yet... 495 * available yet...
496 */ 496 */
497 if (csr & MUSB_TXCSR_TXPKTRDY) 497 if (csr & MUSB_TXCSR_TXPKTRDY)
498 return; 498 return;
499 499
500 DBG(4, "sending zero pkt\n"); 500 DBG(4, "sending zero pkt\n");
501 musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE 501 musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE
502 | MUSB_TXCSR_TXPKTRDY); 502 | MUSB_TXCSR_TXPKTRDY);
503 request->zero = 0; 503 request->zero = 0;
504 } 504 }
505 505
506 if (request->actual == request->length) { 506 if (request->actual == request->length) {
507 musb_g_giveback(musb_ep, request, 0); 507 musb_g_giveback(musb_ep, request, 0);
508 request = musb_ep->desc ? next_request(musb_ep) : NULL; 508 request = musb_ep->desc ? next_request(musb_ep) : NULL;
509 if (!request) { 509 if (!request) {
510 DBG(4, "%s idle now\n", 510 DBG(4, "%s idle now\n",
511 musb_ep->end_point.name); 511 musb_ep->end_point.name);
512 return; 512 return;
513 }
514 } 513 }
515 } 514 }
516 515