diff options
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 156 |
1 files changed, 16 insertions, 140 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 83eddedcd9be..ba7092349fa9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -46,48 +46,6 @@ | |||
46 | #include "musb_core.h" | 46 | #include "musb_core.h" |
47 | 47 | ||
48 | 48 | ||
49 | /* MUSB PERIPHERAL status 3-mar-2006: | ||
50 | * | ||
51 | * - EP0 seems solid. It passes both USBCV and usbtest control cases. | ||
52 | * Minor glitches: | ||
53 | * | ||
54 | * + remote wakeup to Linux hosts work, but saw USBCV failures; | ||
55 | * in one test run (operator error?) | ||
56 | * + endpoint halt tests -- in both usbtest and usbcv -- seem | ||
57 | * to break when dma is enabled ... is something wrongly | ||
58 | * clearing SENDSTALL? | ||
59 | * | ||
60 | * - Mass storage behaved ok when last tested. Network traffic patterns | ||
61 | * (with lots of short transfers etc) need retesting; they turn up the | ||
62 | * worst cases of the DMA, since short packets are typical but are not | ||
63 | * required. | ||
64 | * | ||
65 | * - TX/IN | ||
66 | * + both pio and dma behave in with network and g_zero tests | ||
67 | * + no cppi throughput issues other than no-hw-queueing | ||
68 | * + failed with FLAT_REG (DaVinci) | ||
69 | * + seems to behave with double buffering, PIO -and- CPPI | ||
70 | * + with gadgetfs + AIO, requests got lost? | ||
71 | * | ||
72 | * - RX/OUT | ||
73 | * + both pio and dma behave in with network and g_zero tests | ||
74 | * + dma is slow in typical case (short_not_ok is clear) | ||
75 | * + double buffering ok with PIO | ||
76 | * + double buffering *FAILS* with CPPI, wrong data bytes sometimes | ||
77 | * + request lossage observed with gadgetfs | ||
78 | * | ||
79 | * - ISO not tested ... might work, but only weakly isochronous | ||
80 | * | ||
81 | * - Gadget driver disabling of softconnect during bind() is ignored; so | ||
82 | * drivers can't hold off host requests until userspace is ready. | ||
83 | * (Workaround: they can turn it off later.) | ||
84 | * | ||
85 | * - PORTABILITY (assumes PIO works): | ||
86 | * + DaVinci, basically works with cppi dma | ||
87 | * + OMAP 2430, ditto with mentor dma | ||
88 | * + TUSB 6010, platform-specific dma in the works | ||
89 | */ | ||
90 | |||
91 | /* ----------------------------------------------------------------------- */ | 49 | /* ----------------------------------------------------------------------- */ |
92 | 50 | ||
93 | #define is_buffer_mapped(req) (is_dma_capable() && \ | 51 | #define is_buffer_mapped(req) (is_dma_capable() && \ |
@@ -280,41 +238,6 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep) | |||
280 | return ep->packet_sz; | 238 | return ep->packet_sz; |
281 | } | 239 | } |
282 | 240 | ||
283 | |||
284 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
285 | |||
286 | /* Peripheral tx (IN) using Mentor DMA works as follows: | ||
287 | Only mode 0 is used for transfers <= wPktSize, | ||
288 | mode 1 is used for larger transfers, | ||
289 | |||
290 | One of the following happens: | ||
291 | - Host sends IN token which causes an endpoint interrupt | ||
292 | -> TxAvail | ||
293 | -> if DMA is currently busy, exit. | ||
294 | -> if queue is non-empty, txstate(). | ||
295 | |||
296 | - Request is queued by the gadget driver. | ||
297 | -> if queue was previously empty, txstate() | ||
298 | |||
299 | txstate() | ||
300 | -> start | ||
301 | /\ -> setup DMA | ||
302 | | (data is transferred to the FIFO, then sent out when | ||
303 | | IN token(s) are recd from Host. | ||
304 | | -> DMA interrupt on completion | ||
305 | | calls TxAvail. | ||
306 | | -> stop DMA, ~DMAENAB, | ||
307 | | -> set TxPktRdy for last short pkt or zlp | ||
308 | | -> Complete Request | ||
309 | | -> Continue next request (call txstate) | ||
310 | |___________________________________| | ||
311 | |||
312 | * Non-Mentor DMA engines can of course work differently, such as by | ||
313 | * upleveling from irq-per-packet to irq-per-buffer. | ||
314 | */ | ||
315 | |||
316 | #endif | ||
317 | |||
318 | /* | 241 | /* |
319 | * An endpoint is transmitting data. This can be called either from | 242 | * An endpoint is transmitting data. This can be called either from |
320 | * the IRQ routine or from ep.queue() to kickstart a request on an | 243 | * the IRQ routine or from ep.queue() to kickstart a request on an |
@@ -621,37 +544,6 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
621 | 544 | ||
622 | /* ------------------------------------------------------------ */ | 545 | /* ------------------------------------------------------------ */ |
623 | 546 | ||
624 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
625 | |||
626 | /* Peripheral rx (OUT) using Mentor DMA works as follows: | ||
627 | - Only mode 0 is used. | ||
628 | |||
629 | - Request is queued by the gadget class driver. | ||
630 | -> if queue was previously empty, rxstate() | ||
631 | |||
632 | - Host sends OUT token which causes an endpoint interrupt | ||
633 | /\ -> RxReady | ||
634 | | -> if request queued, call rxstate | ||
635 | | /\ -> setup DMA | ||
636 | | | -> DMA interrupt on completion | ||
637 | | | -> RxReady | ||
638 | | | -> stop DMA | ||
639 | | | -> ack the read | ||
640 | | | -> if data recd = max expected | ||
641 | | | by the request, or host | ||
642 | | | sent a short packet, | ||
643 | | | complete the request, | ||
644 | | | and start the next one. | ||
645 | | |_____________________________________| | ||
646 | | else just wait for the host | ||
647 | | to send the next OUT token. | ||
648 | |__________________________________________________| | ||
649 | |||
650 | * Non-Mentor DMA engines can of course work differently. | ||
651 | */ | ||
652 | |||
653 | #endif | ||
654 | |||
655 | /* | 547 | /* |
656 | * Context: controller locked, IRQs blocked, endpoint selected | 548 | * Context: controller locked, IRQs blocked, endpoint selected |
657 | */ | 549 | */ |
@@ -740,7 +632,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
740 | struct dma_controller *c; | 632 | struct dma_controller *c; |
741 | struct dma_channel *channel; | 633 | struct dma_channel *channel; |
742 | int use_dma = 0; | 634 | int use_dma = 0; |
743 | int transfer_size; | 635 | unsigned int transfer_size; |
744 | 636 | ||
745 | c = musb->dma_controller; | 637 | c = musb->dma_controller; |
746 | channel = musb_ep->dma; | 638 | channel = musb_ep->dma; |
@@ -782,10 +674,11 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
782 | csr | MUSB_RXCSR_DMAMODE); | 674 | csr | MUSB_RXCSR_DMAMODE); |
783 | musb_writew(epio, MUSB_RXCSR, csr); | 675 | musb_writew(epio, MUSB_RXCSR, csr); |
784 | 676 | ||
785 | transfer_size = min(request->length - request->actual, | 677 | transfer_size = min_t(unsigned int, |
678 | request->length - | ||
679 | request->actual, | ||
786 | channel->max_len); | 680 | channel->max_len); |
787 | musb_ep->dma->desired_mode = 1; | 681 | musb_ep->dma->desired_mode = 1; |
788 | |||
789 | } else { | 682 | } else { |
790 | if (!musb_ep->hb_mult && | 683 | if (!musb_ep->hb_mult && |
791 | musb_ep->hw_ep->rx_double_buffered) | 684 | musb_ep->hw_ep->rx_double_buffered) |
@@ -815,7 +708,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
815 | 708 | ||
816 | struct dma_controller *c; | 709 | struct dma_controller *c; |
817 | struct dma_channel *channel; | 710 | struct dma_channel *channel; |
818 | int transfer_size = 0; | 711 | unsigned int transfer_size = 0; |
819 | 712 | ||
820 | c = musb->dma_controller; | 713 | c = musb->dma_controller; |
821 | channel = musb_ep->dma; | 714 | channel = musb_ep->dma; |
@@ -824,11 +717,13 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
824 | if (fifo_count < musb_ep->packet_sz) | 717 | if (fifo_count < musb_ep->packet_sz) |
825 | transfer_size = fifo_count; | 718 | transfer_size = fifo_count; |
826 | else if (request->short_not_ok) | 719 | else if (request->short_not_ok) |
827 | transfer_size = min(request->length - | 720 | transfer_size = min_t(unsigned int, |
721 | request->length - | ||
828 | request->actual, | 722 | request->actual, |
829 | channel->max_len); | 723 | channel->max_len); |
830 | else | 724 | else |
831 | transfer_size = min(request->length - | 725 | transfer_size = min_t(unsigned int, |
726 | request->length - | ||
832 | request->actual, | 727 | request->actual, |
833 | (unsigned)fifo_count); | 728 | (unsigned)fifo_count); |
834 | 729 | ||
@@ -1681,7 +1576,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) | |||
1681 | goto done; | 1576 | goto done; |
1682 | default: | 1577 | default: |
1683 | dev_dbg(musb->controller, "Unhandled wake: %s\n", | 1578 | dev_dbg(musb->controller, "Unhandled wake: %s\n", |
1684 | otg_state_string(musb->xceiv->state)); | 1579 | usb_otg_state_string(musb->xceiv->state)); |
1685 | goto done; | 1580 | goto done; |
1686 | } | 1581 | } |
1687 | 1582 | ||
@@ -1801,13 +1696,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { | |||
1801 | * all peripheral ports are external... | 1696 | * all peripheral ports are external... |
1802 | */ | 1697 | */ |
1803 | 1698 | ||
1804 | static void musb_gadget_release(struct device *dev) | ||
1805 | { | ||
1806 | /* kref_put(WHAT) */ | ||
1807 | dev_dbg(dev, "%s\n", __func__); | ||
1808 | } | ||
1809 | |||
1810 | |||
1811 | static void | 1699 | static void |
1812 | init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) | 1700 | init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) |
1813 | { | 1701 | { |
@@ -1892,12 +1780,7 @@ int musb_gadget_setup(struct musb *musb) | |||
1892 | musb->g.speed = USB_SPEED_UNKNOWN; | 1780 | musb->g.speed = USB_SPEED_UNKNOWN; |
1893 | 1781 | ||
1894 | /* this "gadget" abstracts/virtualizes the controller */ | 1782 | /* this "gadget" abstracts/virtualizes the controller */ |
1895 | dev_set_name(&musb->g.dev, "gadget"); | ||
1896 | musb->g.dev.parent = musb->controller; | ||
1897 | musb->g.dev.dma_mask = musb->controller->dma_mask; | ||
1898 | musb->g.dev.release = musb_gadget_release; | ||
1899 | musb->g.name = musb_driver_name; | 1783 | musb->g.name = musb_driver_name; |
1900 | |||
1901 | musb->g.is_otg = 1; | 1784 | musb->g.is_otg = 1; |
1902 | 1785 | ||
1903 | musb_g_init_endpoints(musb); | 1786 | musb_g_init_endpoints(musb); |
@@ -1905,11 +1788,6 @@ int musb_gadget_setup(struct musb *musb) | |||
1905 | musb->is_active = 0; | 1788 | musb->is_active = 0; |
1906 | musb_platform_try_idle(musb, 0); | 1789 | musb_platform_try_idle(musb, 0); |
1907 | 1790 | ||
1908 | status = device_register(&musb->g.dev); | ||
1909 | if (status != 0) { | ||
1910 | put_device(&musb->g.dev); | ||
1911 | return status; | ||
1912 | } | ||
1913 | status = usb_add_gadget_udc(musb->controller, &musb->g); | 1791 | status = usb_add_gadget_udc(musb->controller, &musb->g); |
1914 | if (status) | 1792 | if (status) |
1915 | goto err; | 1793 | goto err; |
@@ -1924,8 +1802,6 @@ err: | |||
1924 | void musb_gadget_cleanup(struct musb *musb) | 1802 | void musb_gadget_cleanup(struct musb *musb) |
1925 | { | 1803 | { |
1926 | usb_del_gadget_udc(&musb->g); | 1804 | usb_del_gadget_udc(&musb->g); |
1927 | if (musb->g.dev.parent) | ||
1928 | device_unregister(&musb->g.dev); | ||
1929 | } | 1805 | } |
1930 | 1806 | ||
1931 | /* | 1807 | /* |
@@ -1977,9 +1853,8 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
1977 | goto err; | 1853 | goto err; |
1978 | } | 1854 | } |
1979 | 1855 | ||
1980 | if ((musb->xceiv->last_event == USB_EVENT_ID) | 1856 | if (musb->xceiv->last_event == USB_EVENT_ID) |
1981 | && otg->set_vbus) | 1857 | musb_platform_set_vbus(musb, 1); |
1982 | otg_set_vbus(otg, 1); | ||
1983 | 1858 | ||
1984 | hcd->self.uses_pio_for_control = 1; | 1859 | hcd->self.uses_pio_for_control = 1; |
1985 | 1860 | ||
@@ -2063,6 +1938,7 @@ static int musb_gadget_stop(struct usb_gadget *g, | |||
2063 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); | 1938 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); |
2064 | 1939 | ||
2065 | musb->is_active = 0; | 1940 | musb->is_active = 0; |
1941 | musb->gadget_driver = NULL; | ||
2066 | musb_platform_try_idle(musb, 0); | 1942 | musb_platform_try_idle(musb, 0); |
2067 | spin_unlock_irqrestore(&musb->lock, flags); | 1943 | spin_unlock_irqrestore(&musb->lock, flags); |
2068 | 1944 | ||
@@ -2099,7 +1975,7 @@ void musb_g_resume(struct musb *musb) | |||
2099 | break; | 1975 | break; |
2100 | default: | 1976 | default: |
2101 | WARNING("unhandled RESUME transition (%s)\n", | 1977 | WARNING("unhandled RESUME transition (%s)\n", |
2102 | otg_state_string(musb->xceiv->state)); | 1978 | usb_otg_state_string(musb->xceiv->state)); |
2103 | } | 1979 | } |
2104 | } | 1980 | } |
2105 | 1981 | ||
@@ -2129,7 +2005,7 @@ void musb_g_suspend(struct musb *musb) | |||
2129 | * A_PERIPHERAL may need care too | 2005 | * A_PERIPHERAL may need care too |
2130 | */ | 2006 | */ |
2131 | WARNING("unhandled SUSPEND transition (%s)\n", | 2007 | WARNING("unhandled SUSPEND transition (%s)\n", |
2132 | otg_state_string(musb->xceiv->state)); | 2008 | usb_otg_state_string(musb->xceiv->state)); |
2133 | } | 2009 | } |
2134 | } | 2010 | } |
2135 | 2011 | ||
@@ -2163,7 +2039,7 @@ void musb_g_disconnect(struct musb *musb) | |||
2163 | switch (musb->xceiv->state) { | 2039 | switch (musb->xceiv->state) { |
2164 | default: | 2040 | default: |
2165 | dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", | 2041 | dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", |
2166 | otg_state_string(musb->xceiv->state)); | 2042 | usb_otg_state_string(musb->xceiv->state)); |
2167 | musb->xceiv->state = OTG_STATE_A_IDLE; | 2043 | musb->xceiv->state = OTG_STATE_A_IDLE; |
2168 | MUSB_HST_MODE(musb); | 2044 | MUSB_HST_MODE(musb); |
2169 | break; | 2045 | break; |