aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_gadget.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 06:23:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 06:23:15 -0400
commit1be025d3cb40cd295123af2c394f7229ef9b30ca (patch)
tree5dc14e1ea412cc7fdc3e563ad23187059fe8bfb5 /drivers/usb/musb/musb_gadget.c
parent2d03423b2319cc854adeb28a03f65de5b5e0ab63 (diff)
parenta2c76b83fdd763c826f38a55127ccf25708099ce (diff)
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (260 commits) usb: renesas_usbhs: fixup inconsistent return from usbhs_pkt_push() usb/isp1760: Allow to optionally trigger low-level chip reset via GPIOLIB. USB: gadget: midi: memory leak in f_midi_bind_config() USB: gadget: midi: fix range check in f_midi_out_open() QE/FHCI: fixed the CONTROL bug usb: renesas_usbhs: tidyup for smatch warnings USB: Fix USB Kconfig dependency problem on 85xx/QoirQ platforms EHCI: workaround for MosChip controller bug usb: gadget: file_storage: fix race on unloading USB: ftdi_sio.c: Use ftdi async_icount structure for TIOCMIWAIT, as in other drivers USB: ftdi_sio.c:Fill MSR fields of the ftdi async_icount structure USB: ftdi_sio.c: Fill LSR fields of the ftdi async_icount structure USB: ftdi_sio.c:Fill TX field of the ftdi async_icount structure USB: ftdi_sio.c: Fill the RX field of the ftdi async_icount structure USB: ftdi_sio.c: Basic icount infrastructure for ftdi_sio usb/isp1760: Let OF bindings depend on general CONFIG_OF instead of PPC_OF . USB: ftdi_sio: Support TI/Luminary Micro Stellaris BD-ICDI Board USB: Fix runtime wakeup on OHCI xHCI/USB: Make xHCI driver have a BOS descriptor. usb: gadget: add new usb gadget for ACM and mass storage ...
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r--drivers/usb/musb/musb_gadget.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index fe8d14cac436..ae4a20acef6c 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -634,6 +634,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
634 u16 len; 634 u16 len;
635 u16 csr = musb_readw(epio, MUSB_RXCSR); 635 u16 csr = musb_readw(epio, MUSB_RXCSR);
636 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; 636 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
637 u8 use_mode_1;
637 638
638 if (hw_ep->is_shared_fifo) 639 if (hw_ep->is_shared_fifo)
639 musb_ep = &hw_ep->ep_in; 640 musb_ep = &hw_ep->ep_in;
@@ -683,6 +684,18 @@ static void rxstate(struct musb *musb, struct musb_request *req)
683 684
684 if (csr & MUSB_RXCSR_RXPKTRDY) { 685 if (csr & MUSB_RXCSR_RXPKTRDY) {
685 len = musb_readw(epio, MUSB_RXCOUNT); 686 len = musb_readw(epio, MUSB_RXCOUNT);
687
688 /*
689 * Enable Mode 1 on RX transfers only when short_not_ok flag
690 * is set. Currently short_not_ok flag is set only from
691 * file_storage and f_mass_storage drivers
692 */
693
694 if (request->short_not_ok && len == musb_ep->packet_sz)
695 use_mode_1 = 1;
696 else
697 use_mode_1 = 0;
698
686 if (request->actual < request->length) { 699 if (request->actual < request->length) {
687#ifdef CONFIG_USB_INVENTRA_DMA 700#ifdef CONFIG_USB_INVENTRA_DMA
688 if (is_buffer_mapped(req)) { 701 if (is_buffer_mapped(req)) {
@@ -714,37 +727,41 @@ static void rxstate(struct musb *musb, struct musb_request *req)
714 * then becomes usable as a runtime "use mode 1" hint... 727 * then becomes usable as a runtime "use mode 1" hint...
715 */ 728 */
716 729
717 csr |= MUSB_RXCSR_DMAENAB; 730 /* Experimental: Mode1 works with mass storage use cases */
718#ifdef USE_MODE1 731 if (use_mode_1) {
719 csr |= MUSB_RXCSR_AUTOCLEAR;
720 /* csr |= MUSB_RXCSR_DMAMODE; */
721
722 /* this special sequence (enabling and then
723 * disabling MUSB_RXCSR_DMAMODE) is required
724 * to get DMAReq to activate
725 */
726 musb_writew(epio, MUSB_RXCSR,
727 csr | MUSB_RXCSR_DMAMODE);
728#else
729 if (!musb_ep->hb_mult &&
730 musb_ep->hw_ep->rx_double_buffered)
731 csr |= MUSB_RXCSR_AUTOCLEAR; 732 csr |= MUSB_RXCSR_AUTOCLEAR;
732#endif 733 musb_writew(epio, MUSB_RXCSR, csr);
733 musb_writew(epio, MUSB_RXCSR, csr); 734 csr |= MUSB_RXCSR_DMAENAB;
735 musb_writew(epio, MUSB_RXCSR, csr);
736
737 /*
738 * this special sequence (enabling and then
739 * disabling MUSB_RXCSR_DMAMODE) is required
740 * to get DMAReq to activate
741 */
742 musb_writew(epio, MUSB_RXCSR,
743 csr | MUSB_RXCSR_DMAMODE);
744 musb_writew(epio, MUSB_RXCSR, csr);
745
746 } else {
747 if (!musb_ep->hb_mult &&
748 musb_ep->hw_ep->rx_double_buffered)
749 csr |= MUSB_RXCSR_AUTOCLEAR;
750 csr |= MUSB_RXCSR_DMAENAB;
751 musb_writew(epio, MUSB_RXCSR, csr);
752 }
734 753
735 if (request->actual < request->length) { 754 if (request->actual < request->length) {
736 int transfer_size = 0; 755 int transfer_size = 0;
737#ifdef USE_MODE1 756 if (use_mode_1) {
738 transfer_size = min(request->length - request->actual, 757 transfer_size = min(request->length - request->actual,
739 channel->max_len); 758 channel->max_len);
740#else
741 transfer_size = min(request->length - request->actual,
742 (unsigned)len);
743#endif
744 if (transfer_size <= musb_ep->packet_sz)
745 musb_ep->dma->desired_mode = 0;
746 else
747 musb_ep->dma->desired_mode = 1; 759 musb_ep->dma->desired_mode = 1;
760 } else {
761 transfer_size = min(request->length - request->actual,
762 (unsigned)len);
763 musb_ep->dma->desired_mode = 0;
764 }
748 765
749 use_dma = c->channel_program( 766 use_dma = c->channel_program(
750 channel, 767 channel,
@@ -1020,7 +1037,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
1020 goto fail; 1037 goto fail;
1021 1038
1022 /* REVISIT this rules out high bandwidth periodic transfers */ 1039 /* REVISIT this rules out high bandwidth periodic transfers */
1023 tmp = le16_to_cpu(desc->wMaxPacketSize); 1040 tmp = usb_endpoint_maxp(desc);
1024 if (tmp & ~0x07ff) { 1041 if (tmp & ~0x07ff) {
1025 int ok; 1042 int ok;
1026 1043