diff options
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d0b87e7b4abf..b6b84dacc791 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); | 707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); |
708 | 708 | ||
709 | /* | 709 | /* |
710 | * use mode 1 only if we expect data of at least ep packet_sz | 710 | * Enable Mode 1 on RX transfers only when short_not_ok flag |
711 | * and have not yet received a short packet | 711 | * is set. Currently short_not_ok flag is set only from |
712 | * file_storage and f_mass_storage drivers | ||
712 | */ | 713 | */ |
713 | if ((request->length - request->actual >= musb_ep->packet_sz) && | 714 | |
714 | (fifo_count >= musb_ep->packet_sz)) | 715 | if (request->short_not_ok && fifo_count == musb_ep->packet_sz) |
715 | use_mode_1 = 1; | 716 | use_mode_1 = 1; |
716 | else | 717 | else |
717 | use_mode_1 = 0; | 718 | use_mode_1 = 0; |
@@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
727 | c = musb->dma_controller; | 728 | c = musb->dma_controller; |
728 | channel = musb_ep->dma; | 729 | channel = musb_ep->dma; |
729 | 730 | ||
731 | /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in | ||
732 | * mode 0 only. So we do not get endpoint interrupts due to DMA | ||
733 | * completion. We only get interrupts from DMA controller. | ||
734 | * | ||
735 | * We could operate in DMA mode 1 if we knew the size of the tranfer | ||
736 | * in advance. For mass storage class, request->length = what the host | ||
737 | * sends, so that'd work. But for pretty much everything else, | ||
738 | * request->length is routinely more than what the host sends. For | ||
739 | * most these gadgets, end of is signified either by a short packet, | ||
740 | * or filling the last byte of the buffer. (Sending extra data in | ||
741 | * that last pckate should trigger an overflow fault.) But in mode 1, | ||
742 | * we don't get DMA completion interrupt for short packets. | ||
743 | * | ||
744 | * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), | ||
745 | * to get endpoint interrupt on every DMA req, but that didn't seem | ||
746 | * to work reliably. | ||
747 | * | ||
748 | * REVISIT an updated g_file_storage can set req->short_not_ok, which | ||
749 | * then becomes usable as a runtime "use mode 1" hint... | ||
750 | */ | ||
751 | |||
730 | /* Experimental: Mode1 works with mass storage use cases */ | 752 | /* Experimental: Mode1 works with mass storage use cases */ |
731 | if (use_mode_1) { | 753 | if (use_mode_1) { |
732 | csr |= MUSB_RXCSR_AUTOCLEAR; | 754 | csr |= MUSB_RXCSR_AUTOCLEAR; |