aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_gadget.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-27 15:01:25 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-27 15:01:25 -0500
commit459d2a9f5fcf125ba736f7843189ccdfba11b1ff (patch)
tree6664f0ae653081521a3e1df0c506a2532ae6168e /drivers/usb/musb/musb_gadget.c
parent1428c20f7c38e9fbf59923d1b9615ebdaf2862b7 (diff)
parent9489e9dcae718d5fde988e4a684a0f55b5f94d17 (diff)
Merge tag 'v3.7-rc7' into asoc-ux500
Linux 3.7-rc7
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r--drivers/usb/musb/musb_gadget.c30
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;