diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 06:23:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 06:23:15 -0400 |
commit | 1be025d3cb40cd295123af2c394f7229ef9b30ca (patch) | |
tree | 5dc14e1ea412cc7fdc3e563ad23187059fe8bfb5 /drivers/usb/musb/musb_gadget.c | |
parent | 2d03423b2319cc854adeb28a03f65de5b5e0ab63 (diff) | |
parent | a2c76b83fdd763c826f38a55127ccf25708099ce (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.c | 71 |
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 | ||