diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-01 12:20:28 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-01 12:20:28 -0500 |
commit | f9b0f5170918695891f42645737682ccb452ee13 (patch) | |
tree | 75eaab0ff54f8aadaa6375df140cc9d685f78d95 | |
parent | 8062d94a545457a83d5291bd62c3bfd14200bba0 (diff) | |
parent | 6440093f5eae9842feb06e40d41c3bd569b6b461 (diff) |
Merge tag 'gadget-for-v3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
USB: Gadget: changes for 3.4
This merge is rather big. Here's what it contains:
For am5536udc we have just simple coding style fixes. Nothing that has any
potential to cause any issues going forward.
With mv_udc, there's only one single change removing an unneeded NULL check.
at91_udc also only saw a single change this merge window, and that's only
removing a duplicated header.
The Renesas controller has a few more involved changes. Support for SUDMAC was
added, there's now a special handling of IRQ resources for when the IRQ line is
shared between Renesas controller and SUDMAC, we also had a bug fix where
Renesas controller would sleep in atomic context while doing DMA transfers from
a tasklet. There were also a set of minor cleanups.
The FSL UDC also had a scheduling in atomic context bug fix, but that's all.
Thanks to Sebastian, the dummy_hcd now works better than ever with support for
scatterlists and streams. Sebastian also added SuperSpeed descriptors to the
serial gadgets.
The highlight on this merge is the addition of a generic API for mapping and
unmapping usb_requests. This will avoid code duplication on all UDC controllers
and also kills all the defines for DMA_ADDR_INVALID which UDC controllers
sprinkled around. A few of the UDC controllers were already converted to use
this new API.
Conflicts:
drivers/usb/dwc3/gadget.c
52 files changed, 2734 insertions, 687 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 9e57f8e9bf17..a72f42ffbbee 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -572,7 +572,6 @@ struct dwc3_request { | |||
572 | * @ctrl_req_addr: dma address of ctrl_req | 572 | * @ctrl_req_addr: dma address of ctrl_req |
573 | * @ep0_trb: dma address of ep0_trb | 573 | * @ep0_trb: dma address of ep0_trb |
574 | * @ep0_usb_req: dummy req used while handling STD USB requests | 574 | * @ep0_usb_req: dummy req used while handling STD USB requests |
575 | * @setup_buf_addr: dma address of setup_buf | ||
576 | * @ep0_bounce_addr: dma address of ep0_bounce | 575 | * @ep0_bounce_addr: dma address of ep0_bounce |
577 | * @lock: for synchronizing | 576 | * @lock: for synchronizing |
578 | * @dev: pointer to our struct device | 577 | * @dev: pointer to our struct device |
@@ -609,7 +608,6 @@ struct dwc3 { | |||
609 | u8 *setup_buf; | 608 | u8 *setup_buf; |
610 | dma_addr_t ctrl_req_addr; | 609 | dma_addr_t ctrl_req_addr; |
611 | dma_addr_t ep0_trb_addr; | 610 | dma_addr_t ep0_trb_addr; |
612 | dma_addr_t setup_buf_addr; | ||
613 | dma_addr_t ep0_bounce_addr; | 611 | dma_addr_t ep0_bounce_addr; |
614 | struct dwc3_request ep0_usb_req; | 612 | struct dwc3_request ep0_usb_req; |
615 | /* device lock */ | 613 | /* device lock */ |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index c8df1dd967ef..d5c568e91874 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -302,7 +302,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, | |||
302 | dep = dwc->eps[0]; | 302 | dep = dwc->eps[0]; |
303 | dwc->ep0_usb_req.dep = dep; | 303 | dwc->ep0_usb_req.dep = dep; |
304 | dwc->ep0_usb_req.request.length = sizeof(*response_pkt); | 304 | dwc->ep0_usb_req.request.length = sizeof(*response_pkt); |
305 | dwc->ep0_usb_req.request.dma = dwc->setup_buf_addr; | 305 | dwc->ep0_usb_req.request.buf = dwc->setup_buf; |
306 | dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl; | 306 | dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl; |
307 | 307 | ||
308 | return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); | 308 | return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); |
@@ -679,7 +679,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
679 | DWC3_TRBCTL_CONTROL_DATA); | 679 | DWC3_TRBCTL_CONTROL_DATA); |
680 | } else if ((req->request.length % dep->endpoint.maxpacket) | 680 | } else if ((req->request.length % dep->endpoint.maxpacket) |
681 | && (event->endpoint_number == 0)) { | 681 | && (event->endpoint_number == 0)) { |
682 | dwc3_map_buffer_to_dma(req); | 682 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
683 | event->endpoint_number); | ||
684 | if (ret) { | ||
685 | dev_dbg(dwc->dev, "failed to map request\n"); | ||
686 | return; | ||
687 | } | ||
683 | 688 | ||
684 | WARN_ON(req->request.length > dep->endpoint.maxpacket); | 689 | WARN_ON(req->request.length > dep->endpoint.maxpacket); |
685 | 690 | ||
@@ -694,7 +699,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
694 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, | 699 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, |
695 | DWC3_TRBCTL_CONTROL_DATA); | 700 | DWC3_TRBCTL_CONTROL_DATA); |
696 | } else { | 701 | } else { |
697 | dwc3_map_buffer_to_dma(req); | 702 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
703 | event->endpoint_number); | ||
704 | if (ret) { | ||
705 | dev_dbg(dwc->dev, "failed to map request\n"); | ||
706 | return; | ||
707 | } | ||
698 | 708 | ||
699 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | 709 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, |
700 | req->request.dma, req->request.length, | 710 | req->request.dma, req->request.length, |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 064b6e2cd411..1009e7e47a24 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -54,70 +54,6 @@ | |||
54 | #include "gadget.h" | 54 | #include "gadget.h" |
55 | #include "io.h" | 55 | #include "io.h" |
56 | 56 | ||
57 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
58 | |||
59 | void dwc3_map_buffer_to_dma(struct dwc3_request *req) | ||
60 | { | ||
61 | struct dwc3 *dwc = req->dep->dwc; | ||
62 | |||
63 | if (req->request.length == 0) { | ||
64 | /* req->request.dma = dwc->setup_buf_addr; */ | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | if (req->request.num_sgs) { | ||
69 | int mapped; | ||
70 | |||
71 | mapped = dma_map_sg(dwc->dev, req->request.sg, | ||
72 | req->request.num_sgs, | ||
73 | req->direction ? DMA_TO_DEVICE | ||
74 | : DMA_FROM_DEVICE); | ||
75 | if (mapped < 0) { | ||
76 | dev_err(dwc->dev, "failed to map SGs\n"); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | req->request.num_mapped_sgs = mapped; | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | if (req->request.dma == DMA_ADDR_INVALID) { | ||
85 | req->request.dma = dma_map_single(dwc->dev, req->request.buf, | ||
86 | req->request.length, req->direction | ||
87 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
88 | req->mapped = true; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void dwc3_unmap_buffer_from_dma(struct dwc3_request *req) | ||
93 | { | ||
94 | struct dwc3 *dwc = req->dep->dwc; | ||
95 | |||
96 | if (req->request.length == 0) { | ||
97 | req->request.dma = DMA_ADDR_INVALID; | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | if (req->request.num_mapped_sgs) { | ||
102 | req->request.dma = DMA_ADDR_INVALID; | ||
103 | dma_unmap_sg(dwc->dev, req->request.sg, | ||
104 | req->request.num_mapped_sgs, | ||
105 | req->direction ? DMA_TO_DEVICE | ||
106 | : DMA_FROM_DEVICE); | ||
107 | |||
108 | req->request.num_mapped_sgs = 0; | ||
109 | return; | ||
110 | } | ||
111 | |||
112 | if (req->mapped) { | ||
113 | dma_unmap_single(dwc->dev, req->request.dma, | ||
114 | req->request.length, req->direction | ||
115 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
116 | req->mapped = 0; | ||
117 | req->request.dma = DMA_ADDR_INVALID; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | 57 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, |
122 | int status) | 58 | int status) |
123 | { | 59 | { |
@@ -144,14 +80,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
144 | if (req->request.status == -EINPROGRESS) | 80 | if (req->request.status == -EINPROGRESS) |
145 | req->request.status = status; | 81 | req->request.status = status; |
146 | 82 | ||
147 | dwc3_unmap_buffer_from_dma(req); | 83 | usb_gadget_unmap_request(&dwc->gadget, &req->request, |
84 | req->direction); | ||
148 | 85 | ||
149 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 86 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", |
150 | req, dep->name, req->request.actual, | 87 | req, dep->name, req->request.actual, |
151 | req->request.length, status); | 88 | req->request.length, status); |
152 | 89 | ||
153 | spin_unlock(&dwc->lock); | 90 | spin_unlock(&dwc->lock); |
154 | req->request.complete(&req->dep->endpoint, &req->request); | 91 | req->request.complete(&dep->endpoint, &req->request); |
155 | spin_lock(&dwc->lock); | 92 | spin_lock(&dwc->lock); |
156 | } | 93 | } |
157 | 94 | ||
@@ -440,6 +377,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) | |||
440 | 377 | ||
441 | dep->stream_capable = false; | 378 | dep->stream_capable = false; |
442 | dep->desc = NULL; | 379 | dep->desc = NULL; |
380 | dep->endpoint.desc = NULL; | ||
443 | dep->comp_desc = NULL; | 381 | dep->comp_desc = NULL; |
444 | dep->type = 0; | 382 | dep->type = 0; |
445 | dep->flags = 0; | 383 | dep->flags = 0; |
@@ -562,7 +500,6 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, | |||
562 | 500 | ||
563 | req->epnum = dep->number; | 501 | req->epnum = dep->number; |
564 | req->dep = dep; | 502 | req->dep = dep; |
565 | req->request.dma = DMA_ADDR_INVALID; | ||
566 | 503 | ||
567 | return &req->request; | 504 | return &req->request; |
568 | } | 505 | } |
@@ -821,7 +758,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
821 | * here and stop, unmap, free and del each of the linked | 758 | * here and stop, unmap, free and del each of the linked |
822 | * requests instead of we do now. | 759 | * requests instead of we do now. |
823 | */ | 760 | */ |
824 | dwc3_unmap_buffer_from_dma(req); | 761 | usb_gadget_unmap_request(&dwc->gadget, &req->request, |
762 | req->direction); | ||
825 | list_del(&req->list); | 763 | list_del(&req->list); |
826 | return ret; | 764 | return ret; |
827 | } | 765 | } |
@@ -837,6 +775,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
837 | 775 | ||
838 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | 776 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) |
839 | { | 777 | { |
778 | struct dwc3 *dwc = dep->dwc; | ||
779 | int ret; | ||
780 | |||
840 | req->request.actual = 0; | 781 | req->request.actual = 0; |
841 | req->request.status = -EINPROGRESS; | 782 | req->request.status = -EINPROGRESS; |
842 | req->direction = dep->direction; | 783 | req->direction = dep->direction; |
@@ -854,7 +795,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
854 | * This will also avoid Host cancelling URBs due to too | 795 | * This will also avoid Host cancelling URBs due to too |
855 | * many NACKs. | 796 | * many NACKs. |
856 | */ | 797 | */ |
857 | dwc3_map_buffer_to_dma(req); | 798 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
799 | dep->direction); | ||
800 | if (ret) | ||
801 | return ret; | ||
802 | |||
858 | list_add_tail(&req->list, &dep->request_list); | 803 | list_add_tail(&req->list, &dep->request_list); |
859 | 804 | ||
860 | /* | 805 | /* |
@@ -2149,9 +2094,8 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) | |||
2149 | goto err1; | 2094 | goto err1; |
2150 | } | 2095 | } |
2151 | 2096 | ||
2152 | dwc->setup_buf = dma_alloc_coherent(dwc->dev, | 2097 | dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2, |
2153 | sizeof(*dwc->setup_buf) * 2, | 2098 | GFP_KERNEL); |
2154 | &dwc->setup_buf_addr, GFP_KERNEL); | ||
2155 | if (!dwc->setup_buf) { | 2099 | if (!dwc->setup_buf) { |
2156 | dev_err(dwc->dev, "failed to allocate setup buffer\n"); | 2100 | dev_err(dwc->dev, "failed to allocate setup buffer\n"); |
2157 | ret = -ENOMEM; | 2101 | ret = -ENOMEM; |
@@ -2242,8 +2186,7 @@ err4: | |||
2242 | dwc->ep0_bounce_addr); | 2186 | dwc->ep0_bounce_addr); |
2243 | 2187 | ||
2244 | err3: | 2188 | err3: |
2245 | dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, | 2189 | kfree(dwc->setup_buf); |
2246 | dwc->setup_buf, dwc->setup_buf_addr); | ||
2247 | 2190 | ||
2248 | err2: | 2191 | err2: |
2249 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 2192 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), |
@@ -2272,8 +2215,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) | |||
2272 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, | 2215 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, |
2273 | dwc->ep0_bounce_addr); | 2216 | dwc->ep0_bounce_addr); |
2274 | 2217 | ||
2275 | dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, | 2218 | kfree(dwc->setup_buf); |
2276 | dwc->setup_buf, dwc->setup_buf_addr); | ||
2277 | 2219 | ||
2278 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 2220 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), |
2279 | dwc->ep0_trb, dwc->ep0_trb_addr); | 2221 | dwc->ep0_trb, dwc->ep0_trb_addr); |
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index d97f467d41cc..12f1e104977f 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h | |||
@@ -108,8 +108,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | |||
108 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); | 108 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); |
109 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | 109 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, |
110 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); | 110 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); |
111 | void dwc3_map_buffer_to_dma(struct dwc3_request *req); | ||
112 | void dwc3_unmap_buffer_from_dma(struct dwc3_request *req); | ||
113 | 111 | ||
114 | /** | 112 | /** |
115 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW | 113 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7ecb68a67411..1623b5204da4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -599,16 +599,29 @@ config USB_AUDIO | |||
599 | depends on SND | 599 | depends on SND |
600 | select SND_PCM | 600 | select SND_PCM |
601 | help | 601 | help |
602 | Gadget Audio is compatible with USB Audio Class specification 1.0. | 602 | This Gadget Audio driver is compatible with USB Audio Class |
603 | It will include at least one AudioControl interface, zero or more | 603 | specification 2.0. It implements 1 AudioControl interface, |
604 | AudioStream interface and zero or more MIDIStream interface. | 604 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. |
605 | 605 | Number of channels, sample rate and sample size can be | |
606 | Gadget Audio will use on-board ALSA (CONFIG_SND) audio card to | 606 | specified as module parameters. |
607 | playback or capture audio stream. | 607 | This driver doesn't expect any real Audio codec to be present |
608 | on the device - the audio streams are simply sinked to and | ||
609 | sourced from a virtual ALSA sound card created. The user-space | ||
610 | application may choose to do whatever it wants with the data | ||
611 | received from the USB Host and choose to provide whatever it | ||
612 | wants as audio data to the USB Host. | ||
608 | 613 | ||
609 | Say "y" to link the driver statically, or "m" to build a | 614 | Say "y" to link the driver statically, or "m" to build a |
610 | dynamically linked module called "g_audio". | 615 | dynamically linked module called "g_audio". |
611 | 616 | ||
617 | config GADGET_UAC1 | ||
618 | bool "UAC 1.0 (Legacy)" | ||
619 | depends on USB_AUDIO | ||
620 | help | ||
621 | If you instead want older UAC Spec-1.0 driver that also has audio | ||
622 | paths hardwired to the Audio codec chip on-board and doesn't work | ||
623 | without one. | ||
624 | |||
612 | config USB_ETH | 625 | config USB_ETH |
613 | tristate "Ethernet Gadget (with CDC Ethernet support)" | 626 | tristate "Ethernet Gadget (with CDC Ethernet support)" |
614 | depends on NET | 627 | depends on NET |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index c16ff55a74e8..2204a4c68d85 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | /* Driver strings */ | 30 | /* Driver strings */ |
31 | #define UDC_MOD_DESCRIPTION "AMD 5536 UDC - USB Device Controller" | 31 | #define UDC_MOD_DESCRIPTION "AMD 5536 UDC - USB Device Controller" |
32 | #define UDC_DRIVER_VERSION_STRING "01.00.0206 - $Revision: #3 $" | 32 | #define UDC_DRIVER_VERSION_STRING "01.00.0206" |
33 | 33 | ||
34 | /* system */ | 34 | /* system */ |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
@@ -140,7 +140,7 @@ static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, | |||
140 | 140 | ||
141 | /* endpoint names used for print */ | 141 | /* endpoint names used for print */ |
142 | static const char ep0_string[] = "ep0in"; | 142 | static const char ep0_string[] = "ep0in"; |
143 | static const char *ep_string[] = { | 143 | static const char *const ep_string[] = { |
144 | ep0_string, | 144 | ep0_string, |
145 | "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", | 145 | "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", |
146 | "ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk", | 146 | "ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk", |
@@ -204,9 +204,8 @@ static void print_regs(struct udc *dev) | |||
204 | DBG(dev, "DMA mode = BF (buffer fill mode)\n"); | 204 | DBG(dev, "DMA mode = BF (buffer fill mode)\n"); |
205 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF"); | 205 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF"); |
206 | } | 206 | } |
207 | if (!use_dma) { | 207 | if (!use_dma) |
208 | dev_info(&dev->pdev->dev, "FIFO mode\n"); | 208 | dev_info(&dev->pdev->dev, "FIFO mode\n"); |
209 | } | ||
210 | DBG(dev, "-------------------------------------------------------\n"); | 209 | DBG(dev, "-------------------------------------------------------\n"); |
211 | } | 210 | } |
212 | 211 | ||
@@ -445,6 +444,7 @@ static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep) | |||
445 | 444 | ||
446 | VDBG(ep->dev, "ep-%d reset\n", ep->num); | 445 | VDBG(ep->dev, "ep-%d reset\n", ep->num); |
447 | ep->desc = NULL; | 446 | ep->desc = NULL; |
447 | ep->ep.desc = NULL; | ||
448 | ep->ep.ops = &udc_ep_ops; | 448 | ep->ep.ops = &udc_ep_ops; |
449 | INIT_LIST_HEAD(&ep->queue); | 449 | INIT_LIST_HEAD(&ep->queue); |
450 | 450 | ||
@@ -569,9 +569,8 @@ udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) | |||
569 | VDBG(ep->dev, "req->td_data=%p\n", req->td_data); | 569 | VDBG(ep->dev, "req->td_data=%p\n", req->td_data); |
570 | 570 | ||
571 | /* free dma chain if created */ | 571 | /* free dma chain if created */ |
572 | if (req->chain_len > 1) { | 572 | if (req->chain_len > 1) |
573 | udc_free_dma_chain(ep->dev, req); | 573 | udc_free_dma_chain(ep->dev, req); |
574 | } | ||
575 | 574 | ||
576 | pci_pool_free(ep->dev->data_requests, req->td_data, | 575 | pci_pool_free(ep->dev->data_requests, req->td_data, |
577 | req->td_phys); | 576 | req->td_phys); |
@@ -639,9 +638,8 @@ udc_txfifo_write(struct udc_ep *ep, struct usb_request *req) | |||
639 | bytes = remaining; | 638 | bytes = remaining; |
640 | 639 | ||
641 | /* dwords first */ | 640 | /* dwords first */ |
642 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { | 641 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) |
643 | writel(*(buf + i), ep->txfifo); | 642 | writel(*(buf + i), ep->txfifo); |
644 | } | ||
645 | 643 | ||
646 | /* remaining bytes must be written by byte access */ | 644 | /* remaining bytes must be written by byte access */ |
647 | for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { | 645 | for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { |
@@ -660,9 +658,8 @@ static int udc_rxfifo_read_dwords(struct udc *dev, u32 *buf, int dwords) | |||
660 | 658 | ||
661 | VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords); | 659 | VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords); |
662 | 660 | ||
663 | for (i = 0; i < dwords; i++) { | 661 | for (i = 0; i < dwords; i++) |
664 | *(buf + i) = readl(dev->rxfifo); | 662 | *(buf + i) = readl(dev->rxfifo); |
665 | } | ||
666 | return 0; | 663 | return 0; |
667 | } | 664 | } |
668 | 665 | ||
@@ -675,9 +672,8 @@ static int udc_rxfifo_read_bytes(struct udc *dev, u8 *buf, int bytes) | |||
675 | VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes); | 672 | VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes); |
676 | 673 | ||
677 | /* dwords first */ | 674 | /* dwords first */ |
678 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { | 675 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) |
679 | *((u32 *)(buf + (i<<2))) = readl(dev->rxfifo); | 676 | *((u32 *)(buf + (i<<2))) = readl(dev->rxfifo); |
680 | } | ||
681 | 677 | ||
682 | /* remaining bytes must be read by byte access */ | 678 | /* remaining bytes must be read by byte access */ |
683 | if (bytes % UDC_DWORD_BYTES) { | 679 | if (bytes % UDC_DWORD_BYTES) { |
@@ -831,20 +827,8 @@ __acquires(ep->dev->lock) | |||
831 | 827 | ||
832 | dev = ep->dev; | 828 | dev = ep->dev; |
833 | /* unmap DMA */ | 829 | /* unmap DMA */ |
834 | if (req->dma_mapping) { | 830 | if (ep->dma) |
835 | if (ep->in) | 831 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->in); |
836 | pci_unmap_single(dev->pdev, | ||
837 | req->req.dma, | ||
838 | req->req.length, | ||
839 | PCI_DMA_TODEVICE); | ||
840 | else | ||
841 | pci_unmap_single(dev->pdev, | ||
842 | req->req.dma, | ||
843 | req->req.length, | ||
844 | PCI_DMA_FROMDEVICE); | ||
845 | req->dma_mapping = 0; | ||
846 | req->req.dma = DMA_DONT_USE; | ||
847 | } | ||
848 | 832 | ||
849 | halted = ep->halted; | 833 | halted = ep->halted; |
850 | ep->halted = 1; | 834 | ep->halted = 1; |
@@ -897,9 +881,8 @@ static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) | |||
897 | struct udc_data_dma *td; | 881 | struct udc_data_dma *td; |
898 | 882 | ||
899 | td = req->td_data; | 883 | td = req->td_data; |
900 | while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { | 884 | while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) |
901 | td = phys_to_virt(td->next); | 885 | td = phys_to_virt(td->next); |
902 | } | ||
903 | 886 | ||
904 | return td; | 887 | return td; |
905 | 888 | ||
@@ -949,21 +932,18 @@ static int udc_create_dma_chain( | |||
949 | dma_addr = DMA_DONT_USE; | 932 | dma_addr = DMA_DONT_USE; |
950 | 933 | ||
951 | /* unset L bit in first desc for OUT */ | 934 | /* unset L bit in first desc for OUT */ |
952 | if (!ep->in) { | 935 | if (!ep->in) |
953 | req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); | 936 | req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); |
954 | } | ||
955 | 937 | ||
956 | /* alloc only new desc's if not already available */ | 938 | /* alloc only new desc's if not already available */ |
957 | len = req->req.length / ep->ep.maxpacket; | 939 | len = req->req.length / ep->ep.maxpacket; |
958 | if (req->req.length % ep->ep.maxpacket) { | 940 | if (req->req.length % ep->ep.maxpacket) |
959 | len++; | 941 | len++; |
960 | } | ||
961 | 942 | ||
962 | if (len > req->chain_len) { | 943 | if (len > req->chain_len) { |
963 | /* shorter chain already allocated before */ | 944 | /* shorter chain already allocated before */ |
964 | if (req->chain_len > 1) { | 945 | if (req->chain_len > 1) |
965 | udc_free_dma_chain(ep->dev, req); | 946 | udc_free_dma_chain(ep->dev, req); |
966 | } | ||
967 | req->chain_len = len; | 947 | req->chain_len = len; |
968 | create_new_chain = 1; | 948 | create_new_chain = 1; |
969 | } | 949 | } |
@@ -1006,11 +986,12 @@ static int udc_create_dma_chain( | |||
1006 | 986 | ||
1007 | /* link td and assign tx bytes */ | 987 | /* link td and assign tx bytes */ |
1008 | if (i == buf_len) { | 988 | if (i == buf_len) { |
1009 | if (create_new_chain) { | 989 | if (create_new_chain) |
1010 | req->td_data->next = dma_addr; | 990 | req->td_data->next = dma_addr; |
1011 | } else { | 991 | /* |
1012 | /* req->td_data->next = virt_to_phys(td); */ | 992 | else |
1013 | } | 993 | req->td_data->next = virt_to_phys(td); |
994 | */ | ||
1014 | /* write tx bytes */ | 995 | /* write tx bytes */ |
1015 | if (ep->in) { | 996 | if (ep->in) { |
1016 | /* first desc */ | 997 | /* first desc */ |
@@ -1024,11 +1005,12 @@ static int udc_create_dma_chain( | |||
1024 | UDC_DMA_IN_STS_TXBYTES); | 1005 | UDC_DMA_IN_STS_TXBYTES); |
1025 | } | 1006 | } |
1026 | } else { | 1007 | } else { |
1027 | if (create_new_chain) { | 1008 | if (create_new_chain) |
1028 | last->next = dma_addr; | 1009 | last->next = dma_addr; |
1029 | } else { | 1010 | /* |
1030 | /* last->next = virt_to_phys(td); */ | 1011 | else |
1031 | } | 1012 | last->next = virt_to_phys(td); |
1013 | */ | ||
1032 | if (ep->in) { | 1014 | if (ep->in) { |
1033 | /* write tx bytes */ | 1015 | /* write tx bytes */ |
1034 | td->status = AMD_ADDBITS(td->status, | 1016 | td->status = AMD_ADDBITS(td->status, |
@@ -1095,20 +1077,11 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) | |||
1095 | return -ESHUTDOWN; | 1077 | return -ESHUTDOWN; |
1096 | 1078 | ||
1097 | /* map dma (usually done before) */ | 1079 | /* map dma (usually done before) */ |
1098 | if (ep->dma && usbreq->length != 0 | 1080 | if (ep->dma) { |
1099 | && (usbreq->dma == DMA_DONT_USE || usbreq->dma == 0)) { | ||
1100 | VDBG(dev, "DMA map req %p\n", req); | 1081 | VDBG(dev, "DMA map req %p\n", req); |
1101 | if (ep->in) | 1082 | retval = usb_gadget_map_request(&udc->gadget, usbreq, ep->in); |
1102 | usbreq->dma = pci_map_single(dev->pdev, | 1083 | if (retval) |
1103 | usbreq->buf, | 1084 | return retval; |
1104 | usbreq->length, | ||
1105 | PCI_DMA_TODEVICE); | ||
1106 | else | ||
1107 | usbreq->dma = pci_map_single(dev->pdev, | ||
1108 | usbreq->buf, | ||
1109 | usbreq->length, | ||
1110 | PCI_DMA_FROMDEVICE); | ||
1111 | req->dma_mapping = 1; | ||
1112 | } | 1085 | } |
1113 | 1086 | ||
1114 | VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n", | 1087 | VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n", |
@@ -1479,11 +1452,10 @@ static int startup_registers(struct udc *dev) | |||
1479 | 1452 | ||
1480 | /* program speed */ | 1453 | /* program speed */ |
1481 | tmp = readl(&dev->regs->cfg); | 1454 | tmp = readl(&dev->regs->cfg); |
1482 | if (use_fullspeed) { | 1455 | if (use_fullspeed) |
1483 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); | 1456 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); |
1484 | } else { | 1457 | else |
1485 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); | 1458 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); |
1486 | } | ||
1487 | writel(tmp, &dev->regs->cfg); | 1459 | writel(tmp, &dev->regs->cfg); |
1488 | 1460 | ||
1489 | return 0; | 1461 | return 0; |
@@ -1504,9 +1476,8 @@ static void udc_basic_init(struct udc *dev) | |||
1504 | mod_timer(&udc_timer, jiffies - 1); | 1476 | mod_timer(&udc_timer, jiffies - 1); |
1505 | } | 1477 | } |
1506 | /* stop poll stall timer */ | 1478 | /* stop poll stall timer */ |
1507 | if (timer_pending(&udc_pollstall_timer)) { | 1479 | if (timer_pending(&udc_pollstall_timer)) |
1508 | mod_timer(&udc_pollstall_timer, jiffies - 1); | 1480 | mod_timer(&udc_pollstall_timer, jiffies - 1); |
1509 | } | ||
1510 | /* disable DMA */ | 1481 | /* disable DMA */ |
1511 | tmp = readl(&dev->regs->ctl); | 1482 | tmp = readl(&dev->regs->ctl); |
1512 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); | 1483 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); |
@@ -1540,11 +1511,10 @@ static void udc_setup_endpoints(struct udc *dev) | |||
1540 | /* read enum speed */ | 1511 | /* read enum speed */ |
1541 | tmp = readl(&dev->regs->sts); | 1512 | tmp = readl(&dev->regs->sts); |
1542 | tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED); | 1513 | tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED); |
1543 | if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH) { | 1514 | if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH) |
1544 | dev->gadget.speed = USB_SPEED_HIGH; | 1515 | dev->gadget.speed = USB_SPEED_HIGH; |
1545 | } else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL) { | 1516 | else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL) |
1546 | dev->gadget.speed = USB_SPEED_FULL; | 1517 | dev->gadget.speed = USB_SPEED_FULL; |
1547 | } | ||
1548 | 1518 | ||
1549 | /* set basic ep parameters */ | 1519 | /* set basic ep parameters */ |
1550 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | 1520 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { |
@@ -1570,9 +1540,8 @@ static void udc_setup_endpoints(struct udc *dev) | |||
1570 | * disabling ep interrupts when ENUM interrupt occurs but ep is | 1540 | * disabling ep interrupts when ENUM interrupt occurs but ep is |
1571 | * not enabled by gadget driver | 1541 | * not enabled by gadget driver |
1572 | */ | 1542 | */ |
1573 | if (!ep->desc) { | 1543 | if (!ep->desc) |
1574 | ep_init(dev->regs, ep); | 1544 | ep_init(dev->regs, ep); |
1575 | } | ||
1576 | 1545 | ||
1577 | if (use_dma) { | 1546 | if (use_dma) { |
1578 | /* | 1547 | /* |
@@ -1670,9 +1639,8 @@ static void udc_tasklet_disconnect(unsigned long par) | |||
1670 | spin_lock(&dev->lock); | 1639 | spin_lock(&dev->lock); |
1671 | 1640 | ||
1672 | /* empty queues */ | 1641 | /* empty queues */ |
1673 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | 1642 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) |
1674 | empty_req_queue(&dev->ep[tmp]); | 1643 | empty_req_queue(&dev->ep[tmp]); |
1675 | } | ||
1676 | 1644 | ||
1677 | } | 1645 | } |
1678 | 1646 | ||
@@ -1746,9 +1714,8 @@ static void udc_timer_function(unsigned long v) | |||
1746 | * open the fifo | 1714 | * open the fifo |
1747 | */ | 1715 | */ |
1748 | udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV; | 1716 | udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV; |
1749 | if (!stop_timer) { | 1717 | if (!stop_timer) |
1750 | add_timer(&udc_timer); | 1718 | add_timer(&udc_timer); |
1751 | } | ||
1752 | } else { | 1719 | } else { |
1753 | /* | 1720 | /* |
1754 | * fifo contains data now, setup timer for opening | 1721 | * fifo contains data now, setup timer for opening |
@@ -1760,9 +1727,8 @@ static void udc_timer_function(unsigned long v) | |||
1760 | set_rde++; | 1727 | set_rde++; |
1761 | /* debug: lhadmot_timer_start = 221070 */ | 1728 | /* debug: lhadmot_timer_start = 221070 */ |
1762 | udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS; | 1729 | udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS; |
1763 | if (!stop_timer) { | 1730 | if (!stop_timer) |
1764 | add_timer(&udc_timer); | 1731 | add_timer(&udc_timer); |
1765 | } | ||
1766 | } | 1732 | } |
1767 | 1733 | ||
1768 | } else | 1734 | } else |
@@ -1907,19 +1873,17 @@ static void activate_control_endpoints(struct udc *dev) | |||
1907 | mod_timer(&udc_timer, jiffies - 1); | 1873 | mod_timer(&udc_timer, jiffies - 1); |
1908 | } | 1874 | } |
1909 | /* stop pollstall timer */ | 1875 | /* stop pollstall timer */ |
1910 | if (timer_pending(&udc_pollstall_timer)) { | 1876 | if (timer_pending(&udc_pollstall_timer)) |
1911 | mod_timer(&udc_pollstall_timer, jiffies - 1); | 1877 | mod_timer(&udc_pollstall_timer, jiffies - 1); |
1912 | } | ||
1913 | /* enable DMA */ | 1878 | /* enable DMA */ |
1914 | tmp = readl(&dev->regs->ctl); | 1879 | tmp = readl(&dev->regs->ctl); |
1915 | tmp |= AMD_BIT(UDC_DEVCTL_MODE) | 1880 | tmp |= AMD_BIT(UDC_DEVCTL_MODE) |
1916 | | AMD_BIT(UDC_DEVCTL_RDE) | 1881 | | AMD_BIT(UDC_DEVCTL_RDE) |
1917 | | AMD_BIT(UDC_DEVCTL_TDE); | 1882 | | AMD_BIT(UDC_DEVCTL_TDE); |
1918 | if (use_dma_bufferfill_mode) { | 1883 | if (use_dma_bufferfill_mode) |
1919 | tmp |= AMD_BIT(UDC_DEVCTL_BF); | 1884 | tmp |= AMD_BIT(UDC_DEVCTL_BF); |
1920 | } else if (use_dma_ppb_du) { | 1885 | else if (use_dma_ppb_du) |
1921 | tmp |= AMD_BIT(UDC_DEVCTL_DU); | 1886 | tmp |= AMD_BIT(UDC_DEVCTL_DU); |
1922 | } | ||
1923 | writel(tmp, &dev->regs->ctl); | 1887 | writel(tmp, &dev->regs->ctl); |
1924 | } | 1888 | } |
1925 | 1889 | ||
@@ -2104,9 +2068,8 @@ static void udc_ep0_set_rde(struct udc *dev) | |||
2104 | udc_timer.expires = | 2068 | udc_timer.expires = |
2105 | jiffies + HZ/UDC_RDE_TIMER_DIV; | 2069 | jiffies + HZ/UDC_RDE_TIMER_DIV; |
2106 | set_rde = 1; | 2070 | set_rde = 1; |
2107 | if (!stop_timer) { | 2071 | if (!stop_timer) |
2108 | add_timer(&udc_timer); | 2072 | add_timer(&udc_timer); |
2109 | } | ||
2110 | } | 2073 | } |
2111 | } | 2074 | } |
2112 | } | 2075 | } |
@@ -2131,7 +2094,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) | |||
2131 | if (use_dma) { | 2094 | if (use_dma) { |
2132 | /* BNA event ? */ | 2095 | /* BNA event ? */ |
2133 | if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { | 2096 | if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { |
2134 | DBG(dev, "BNA ep%dout occurred - DESPTR = %x \n", | 2097 | DBG(dev, "BNA ep%dout occurred - DESPTR = %x\n", |
2135 | ep->num, readl(&ep->regs->desptr)); | 2098 | ep->num, readl(&ep->regs->desptr)); |
2136 | /* clear BNA */ | 2099 | /* clear BNA */ |
2137 | writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); | 2100 | writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); |
@@ -2294,9 +2257,8 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) | |||
2294 | jiffies | 2257 | jiffies |
2295 | + HZ*UDC_RDE_TIMER_SECONDS; | 2258 | + HZ*UDC_RDE_TIMER_SECONDS; |
2296 | set_rde = 1; | 2259 | set_rde = 1; |
2297 | if (!stop_timer) { | 2260 | if (!stop_timer) |
2298 | add_timer(&udc_timer); | 2261 | add_timer(&udc_timer); |
2299 | } | ||
2300 | } | 2262 | } |
2301 | if (ep->num != UDC_EP0OUT_IX) | 2263 | if (ep->num != UDC_EP0OUT_IX) |
2302 | dev->data_ep_queued = 0; | 2264 | dev->data_ep_queued = 0; |
@@ -2318,9 +2280,8 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) | |||
2318 | /* check pending CNAKS */ | 2280 | /* check pending CNAKS */ |
2319 | if (cnak_pending) { | 2281 | if (cnak_pending) { |
2320 | /* CNAk processing when rxfifo empty only */ | 2282 | /* CNAk processing when rxfifo empty only */ |
2321 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | 2283 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) |
2322 | udc_process_cnak_queue(dev); | 2284 | udc_process_cnak_queue(dev); |
2323 | } | ||
2324 | } | 2285 | } |
2325 | 2286 | ||
2326 | /* clear OUT bits in ep status */ | 2287 | /* clear OUT bits in ep status */ |
@@ -2348,7 +2309,7 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) | |||
2348 | /* BNA ? */ | 2309 | /* BNA ? */ |
2349 | if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { | 2310 | if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { |
2350 | dev_err(&dev->pdev->dev, | 2311 | dev_err(&dev->pdev->dev, |
2351 | "BNA ep%din occurred - DESPTR = %08lx \n", | 2312 | "BNA ep%din occurred - DESPTR = %08lx\n", |
2352 | ep->num, | 2313 | ep->num, |
2353 | (unsigned long) readl(&ep->regs->desptr)); | 2314 | (unsigned long) readl(&ep->regs->desptr)); |
2354 | 2315 | ||
@@ -2361,7 +2322,7 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) | |||
2361 | /* HE event ? */ | 2322 | /* HE event ? */ |
2362 | if (epsts & AMD_BIT(UDC_EPSTS_HE)) { | 2323 | if (epsts & AMD_BIT(UDC_EPSTS_HE)) { |
2363 | dev_err(&dev->pdev->dev, | 2324 | dev_err(&dev->pdev->dev, |
2364 | "HE ep%dn occurred - DESPTR = %08lx \n", | 2325 | "HE ep%dn occurred - DESPTR = %08lx\n", |
2365 | ep->num, (unsigned long) readl(&ep->regs->desptr)); | 2326 | ep->num, (unsigned long) readl(&ep->regs->desptr)); |
2366 | 2327 | ||
2367 | /* clear HE */ | 2328 | /* clear HE */ |
@@ -2427,9 +2388,9 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) | |||
2427 | /* write fifo */ | 2388 | /* write fifo */ |
2428 | udc_txfifo_write(ep, &req->req); | 2389 | udc_txfifo_write(ep, &req->req); |
2429 | len = req->req.length - req->req.actual; | 2390 | len = req->req.length - req->req.actual; |
2430 | if (len > ep->ep.maxpacket) | 2391 | if (len > ep->ep.maxpacket) |
2431 | len = ep->ep.maxpacket; | 2392 | len = ep->ep.maxpacket; |
2432 | req->req.actual += len; | 2393 | req->req.actual += len; |
2433 | if (req->req.actual == req->req.length | 2394 | if (req->req.actual == req->req.length |
2434 | || (len != ep->ep.maxpacket)) { | 2395 | || (len != ep->ep.maxpacket)) { |
2435 | /* complete req */ | 2396 | /* complete req */ |
@@ -2581,9 +2542,8 @@ __acquires(dev->lock) | |||
2581 | if (!timer_pending(&udc_timer)) { | 2542 | if (!timer_pending(&udc_timer)) { |
2582 | udc_timer.expires = jiffies + | 2543 | udc_timer.expires = jiffies + |
2583 | HZ/UDC_RDE_TIMER_DIV; | 2544 | HZ/UDC_RDE_TIMER_DIV; |
2584 | if (!stop_timer) { | 2545 | if (!stop_timer) |
2585 | add_timer(&udc_timer); | 2546 | add_timer(&udc_timer); |
2586 | } | ||
2587 | } | 2547 | } |
2588 | } | 2548 | } |
2589 | 2549 | ||
@@ -2697,9 +2657,8 @@ __acquires(dev->lock) | |||
2697 | /* check pending CNAKS */ | 2657 | /* check pending CNAKS */ |
2698 | if (cnak_pending) { | 2658 | if (cnak_pending) { |
2699 | /* CNAk processing when rxfifo empty only */ | 2659 | /* CNAk processing when rxfifo empty only */ |
2700 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | 2660 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) |
2701 | udc_process_cnak_queue(dev); | 2661 | udc_process_cnak_queue(dev); |
2702 | } | ||
2703 | } | 2662 | } |
2704 | 2663 | ||
2705 | finished: | 2664 | finished: |
@@ -2723,7 +2682,7 @@ static irqreturn_t udc_control_in_isr(struct udc *dev) | |||
2723 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts); | 2682 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts); |
2724 | /* DMA completion */ | 2683 | /* DMA completion */ |
2725 | if (tmp & AMD_BIT(UDC_EPSTS_TDC)) { | 2684 | if (tmp & AMD_BIT(UDC_EPSTS_TDC)) { |
2726 | VDBG(dev, "isr: TDC clear \n"); | 2685 | VDBG(dev, "isr: TDC clear\n"); |
2727 | ret_val = IRQ_HANDLED; | 2686 | ret_val = IRQ_HANDLED; |
2728 | 2687 | ||
2729 | /* clear TDC bit */ | 2688 | /* clear TDC bit */ |
@@ -3426,7 +3385,7 @@ static int udc_remote_wakeup(struct udc *dev) | |||
3426 | } | 3385 | } |
3427 | 3386 | ||
3428 | /* PCI device parameters */ | 3387 | /* PCI device parameters */ |
3429 | static const struct pci_device_id pci_id[] = { | 3388 | static DEFINE_PCI_DEVICE_TABLE(pci_id) = { |
3430 | { | 3389 | { |
3431 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), | 3390 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), |
3432 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | 3391 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 143a7256b598..15a8cdb2ded5 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
30 | #include <linux/usb/ch9.h> | 30 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb/gadget.h> | 31 | #include <linux/usb/gadget.h> |
32 | #include <linux/prefetch.h> | ||
33 | 32 | ||
34 | #include <asm/byteorder.h> | 33 | #include <asm/byteorder.h> |
35 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
@@ -558,6 +557,7 @@ static int at91_ep_disable (struct usb_ep * _ep) | |||
558 | 557 | ||
559 | /* restore the endpoint's pristine config */ | 558 | /* restore the endpoint's pristine config */ |
560 | ep->desc = NULL; | 559 | ep->desc = NULL; |
560 | ep->ep.desc = NULL; | ||
561 | ep->ep.maxpacket = ep->maxpacket; | 561 | ep->ep.maxpacket = ep->maxpacket; |
562 | 562 | ||
563 | /* reset fifos and endpoint */ | 563 | /* reset fifos and endpoint */ |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e2fb6d583bd9..5e10f651ad63 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -659,6 +659,7 @@ static int usba_ep_disable(struct usb_ep *_ep) | |||
659 | return -EINVAL; | 659 | return -EINVAL; |
660 | } | 660 | } |
661 | ep->desc = NULL; | 661 | ep->desc = NULL; |
662 | ep->ep.desc = NULL; | ||
662 | 663 | ||
663 | list_splice_init(&ep->queue, &req_list); | 664 | list_splice_init(&ep->queue, &req_list); |
664 | if (ep->can_dma) { | 665 | if (ep->can_dma) { |
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 9d89ae4765a9..98899244860e 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c | |||
@@ -14,10 +14,8 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/utsname.h> | 15 | #include <linux/utsname.h> |
16 | 16 | ||
17 | #include "u_audio.h" | ||
18 | |||
19 | #define DRIVER_DESC "Linux USB Audio Gadget" | 17 | #define DRIVER_DESC "Linux USB Audio Gadget" |
20 | #define DRIVER_VERSION "Dec 18, 2008" | 18 | #define DRIVER_VERSION "Feb 2, 2012" |
21 | 19 | ||
22 | /*-------------------------------------------------------------------------*/ | 20 | /*-------------------------------------------------------------------------*/ |
23 | 21 | ||
@@ -33,8 +31,36 @@ | |||
33 | #include "config.c" | 31 | #include "config.c" |
34 | #include "epautoconf.c" | 32 | #include "epautoconf.c" |
35 | 33 | ||
36 | #include "u_audio.c" | 34 | /* string IDs are assigned dynamically */ |
37 | #include "f_audio.c" | 35 | |
36 | #define STRING_MANUFACTURER_IDX 0 | ||
37 | #define STRING_PRODUCT_IDX 1 | ||
38 | |||
39 | static char manufacturer[50]; | ||
40 | |||
41 | static struct usb_string strings_dev[] = { | ||
42 | [STRING_MANUFACTURER_IDX].s = manufacturer, | ||
43 | [STRING_PRODUCT_IDX].s = DRIVER_DESC, | ||
44 | { } /* end of list */ | ||
45 | }; | ||
46 | |||
47 | static struct usb_gadget_strings stringtab_dev = { | ||
48 | .language = 0x0409, /* en-us */ | ||
49 | .strings = strings_dev, | ||
50 | }; | ||
51 | |||
52 | static struct usb_gadget_strings *audio_strings[] = { | ||
53 | &stringtab_dev, | ||
54 | NULL, | ||
55 | }; | ||
56 | |||
57 | #ifdef CONFIG_GADGET_UAC1 | ||
58 | #include "u_uac1.h" | ||
59 | #include "u_uac1.c" | ||
60 | #include "f_uac1.c" | ||
61 | #else | ||
62 | #include "f_uac2.c" | ||
63 | #endif | ||
38 | 64 | ||
39 | /*-------------------------------------------------------------------------*/ | 65 | /*-------------------------------------------------------------------------*/ |
40 | 66 | ||
@@ -54,9 +80,15 @@ static struct usb_device_descriptor device_desc = { | |||
54 | 80 | ||
55 | .bcdUSB = __constant_cpu_to_le16(0x200), | 81 | .bcdUSB = __constant_cpu_to_le16(0x200), |
56 | 82 | ||
83 | #ifdef CONFIG_GADGET_UAC1 | ||
57 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 84 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
58 | .bDeviceSubClass = 0, | 85 | .bDeviceSubClass = 0, |
59 | .bDeviceProtocol = 0, | 86 | .bDeviceProtocol = 0, |
87 | #else | ||
88 | .bDeviceClass = USB_CLASS_MISC, | ||
89 | .bDeviceSubClass = 0x02, | ||
90 | .bDeviceProtocol = 0x01, | ||
91 | #endif | ||
60 | /* .bMaxPacketSize0 = f(hardware) */ | 92 | /* .bMaxPacketSize0 = f(hardware) */ |
61 | 93 | ||
62 | /* Vendor and product id defaults change according to what configs | 94 | /* Vendor and product id defaults change according to what configs |
@@ -108,6 +140,9 @@ static struct usb_configuration audio_config_driver = { | |||
108 | .bConfigurationValue = 1, | 140 | .bConfigurationValue = 1, |
109 | /* .iConfiguration = DYNAMIC */ | 141 | /* .iConfiguration = DYNAMIC */ |
110 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | 142 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, |
143 | #ifndef CONFIG_GADGET_UAC1 | ||
144 | .unbind = uac2_unbind_config, | ||
145 | #endif | ||
111 | }; | 146 | }; |
112 | 147 | ||
113 | /*-------------------------------------------------------------------------*/ | 148 | /*-------------------------------------------------------------------------*/ |
@@ -157,7 +192,9 @@ fail: | |||
157 | 192 | ||
158 | static int __exit audio_unbind(struct usb_composite_dev *cdev) | 193 | static int __exit audio_unbind(struct usb_composite_dev *cdev) |
159 | { | 194 | { |
195 | #ifdef CONFIG_GADGET_UAC1 | ||
160 | gaudio_cleanup(); | 196 | gaudio_cleanup(); |
197 | #endif | ||
161 | return 0; | 198 | return 0; |
162 | } | 199 | } |
163 | 200 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index b27cb0b0077b..243ef1adf969 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -2181,6 +2181,7 @@ static int ep_disable(struct usb_ep *ep) | |||
2181 | } while (mEp->dir != direction); | 2181 | } while (mEp->dir != direction); |
2182 | 2182 | ||
2183 | mEp->desc = NULL; | 2183 | mEp->desc = NULL; |
2184 | mEp->ep.desc = NULL; | ||
2184 | 2185 | ||
2185 | spin_unlock_irqrestore(mEp->lock, flags); | 2186 | spin_unlock_irqrestore(mEp->lock, flags); |
2186 | return retval; | 2187 | return retval; |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index db815c2da7ed..8cc1a88d21e7 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -39,27 +39,27 @@ | |||
39 | #include <linux/usb.h> | 39 | #include <linux/usb.h> |
40 | #include <linux/usb/gadget.h> | 40 | #include <linux/usb/gadget.h> |
41 | #include <linux/usb/hcd.h> | 41 | #include <linux/usb/hcd.h> |
42 | #include <linux/scatterlist.h> | ||
42 | 43 | ||
43 | #include <asm/byteorder.h> | 44 | #include <asm/byteorder.h> |
44 | #include <asm/io.h> | 45 | #include <linux/io.h> |
45 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
46 | #include <asm/system.h> | 47 | #include <asm/system.h> |
47 | #include <asm/unaligned.h> | 48 | #include <asm/unaligned.h> |
48 | 49 | ||
49 | |||
50 | #define DRIVER_DESC "USB Host+Gadget Emulator" | 50 | #define DRIVER_DESC "USB Host+Gadget Emulator" |
51 | #define DRIVER_VERSION "02 May 2005" | 51 | #define DRIVER_VERSION "02 May 2005" |
52 | 52 | ||
53 | #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ | 53 | #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ |
54 | 54 | ||
55 | static const char driver_name [] = "dummy_hcd"; | 55 | static const char driver_name[] = "dummy_hcd"; |
56 | static const char driver_desc [] = "USB Host+Gadget Emulator"; | 56 | static const char driver_desc[] = "USB Host+Gadget Emulator"; |
57 | 57 | ||
58 | static const char gadget_name [] = "dummy_udc"; | 58 | static const char gadget_name[] = "dummy_udc"; |
59 | 59 | ||
60 | MODULE_DESCRIPTION (DRIVER_DESC); | 60 | MODULE_DESCRIPTION(DRIVER_DESC); |
61 | MODULE_AUTHOR ("David Brownell"); | 61 | MODULE_AUTHOR("David Brownell"); |
62 | MODULE_LICENSE ("GPL"); | 62 | MODULE_LICENSE("GPL"); |
63 | 63 | ||
64 | struct dummy_hcd_module_parameters { | 64 | struct dummy_hcd_module_parameters { |
65 | bool is_super_speed; | 65 | bool is_super_speed; |
@@ -83,10 +83,11 @@ struct dummy_ep { | |||
83 | struct usb_gadget *gadget; | 83 | struct usb_gadget *gadget; |
84 | const struct usb_endpoint_descriptor *desc; | 84 | const struct usb_endpoint_descriptor *desc; |
85 | struct usb_ep ep; | 85 | struct usb_ep ep; |
86 | unsigned halted : 1; | 86 | unsigned halted:1; |
87 | unsigned wedged : 1; | 87 | unsigned wedged:1; |
88 | unsigned already_seen : 1; | 88 | unsigned already_seen:1; |
89 | unsigned setup_stage : 1; | 89 | unsigned setup_stage:1; |
90 | unsigned stream_en:1; | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | struct dummy_request { | 93 | struct dummy_request { |
@@ -94,15 +95,15 @@ struct dummy_request { | |||
94 | struct usb_request req; | 95 | struct usb_request req; |
95 | }; | 96 | }; |
96 | 97 | ||
97 | static inline struct dummy_ep *usb_ep_to_dummy_ep (struct usb_ep *_ep) | 98 | static inline struct dummy_ep *usb_ep_to_dummy_ep(struct usb_ep *_ep) |
98 | { | 99 | { |
99 | return container_of (_ep, struct dummy_ep, ep); | 100 | return container_of(_ep, struct dummy_ep, ep); |
100 | } | 101 | } |
101 | 102 | ||
102 | static inline struct dummy_request *usb_request_to_dummy_request | 103 | static inline struct dummy_request *usb_request_to_dummy_request |
103 | (struct usb_request *_req) | 104 | (struct usb_request *_req) |
104 | { | 105 | { |
105 | return container_of (_req, struct dummy_request, req); | 106 | return container_of(_req, struct dummy_request, req); |
106 | } | 107 | } |
107 | 108 | ||
108 | /*-------------------------------------------------------------------------*/ | 109 | /*-------------------------------------------------------------------------*/ |
@@ -121,9 +122,9 @@ static inline struct dummy_request *usb_request_to_dummy_request | |||
121 | * configurations, illegal or unsupported packet lengths, and so on. | 122 | * configurations, illegal or unsupported packet lengths, and so on. |
122 | */ | 123 | */ |
123 | 124 | ||
124 | static const char ep0name [] = "ep0"; | 125 | static const char ep0name[] = "ep0"; |
125 | 126 | ||
126 | static const char *const ep_name [] = { | 127 | static const char *const ep_name[] = { |
127 | ep0name, /* everyone has ep0 */ | 128 | ep0name, /* everyone has ep0 */ |
128 | 129 | ||
129 | /* act like a net2280: high speed, six configurable endpoints */ | 130 | /* act like a net2280: high speed, six configurable endpoints */ |
@@ -147,6 +148,8 @@ static const char *const ep_name [] = { | |||
147 | struct urbp { | 148 | struct urbp { |
148 | struct urb *urb; | 149 | struct urb *urb; |
149 | struct list_head urbp_list; | 150 | struct list_head urbp_list; |
151 | struct sg_mapping_iter miter; | ||
152 | u32 miter_started; | ||
150 | }; | 153 | }; |
151 | 154 | ||
152 | 155 | ||
@@ -166,6 +169,8 @@ struct dummy_hcd { | |||
166 | 169 | ||
167 | struct usb_device *udev; | 170 | struct usb_device *udev; |
168 | struct list_head urbp_list; | 171 | struct list_head urbp_list; |
172 | u32 stream_en_ep; | ||
173 | u8 num_stream[30 / 2]; | ||
169 | 174 | ||
170 | unsigned active:1; | 175 | unsigned active:1; |
171 | unsigned old_active:1; | 176 | unsigned old_active:1; |
@@ -178,12 +183,12 @@ struct dummy { | |||
178 | /* | 183 | /* |
179 | * SLAVE/GADGET side support | 184 | * SLAVE/GADGET side support |
180 | */ | 185 | */ |
181 | struct dummy_ep ep [DUMMY_ENDPOINTS]; | 186 | struct dummy_ep ep[DUMMY_ENDPOINTS]; |
182 | int address; | 187 | int address; |
183 | struct usb_gadget gadget; | 188 | struct usb_gadget gadget; |
184 | struct usb_gadget_driver *driver; | 189 | struct usb_gadget_driver *driver; |
185 | struct dummy_request fifo_req; | 190 | struct dummy_request fifo_req; |
186 | u8 fifo_buf [FIFO_SIZE]; | 191 | u8 fifo_buf[FIFO_SIZE]; |
187 | u16 devstatus; | 192 | u16 devstatus; |
188 | unsigned udc_suspended:1; | 193 | unsigned udc_suspended:1; |
189 | unsigned pullup:1; | 194 | unsigned pullup:1; |
@@ -210,14 +215,14 @@ static inline struct device *dummy_dev(struct dummy_hcd *dum) | |||
210 | return dummy_hcd_to_hcd(dum)->self.controller; | 215 | return dummy_hcd_to_hcd(dum)->self.controller; |
211 | } | 216 | } |
212 | 217 | ||
213 | static inline struct device *udc_dev (struct dummy *dum) | 218 | static inline struct device *udc_dev(struct dummy *dum) |
214 | { | 219 | { |
215 | return dum->gadget.dev.parent; | 220 | return dum->gadget.dev.parent; |
216 | } | 221 | } |
217 | 222 | ||
218 | static inline struct dummy *ep_to_dummy (struct dummy_ep *ep) | 223 | static inline struct dummy *ep_to_dummy(struct dummy_ep *ep) |
219 | { | 224 | { |
220 | return container_of (ep->gadget, struct dummy, gadget); | 225 | return container_of(ep->gadget, struct dummy, gadget); |
221 | } | 226 | } |
222 | 227 | ||
223 | static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) | 228 | static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) |
@@ -229,9 +234,9 @@ static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) | |||
229 | return dum->hs_hcd; | 234 | return dum->hs_hcd; |
230 | } | 235 | } |
231 | 236 | ||
232 | static inline struct dummy *gadget_dev_to_dummy (struct device *dev) | 237 | static inline struct dummy *gadget_dev_to_dummy(struct device *dev) |
233 | { | 238 | { |
234 | return container_of (dev, struct dummy, gadget.dev); | 239 | return container_of(dev, struct dummy, gadget.dev); |
235 | } | 240 | } |
236 | 241 | ||
237 | static struct dummy the_controller; | 242 | static struct dummy the_controller; |
@@ -241,24 +246,23 @@ static struct dummy the_controller; | |||
241 | /* SLAVE/GADGET SIDE UTILITY ROUTINES */ | 246 | /* SLAVE/GADGET SIDE UTILITY ROUTINES */ |
242 | 247 | ||
243 | /* called with spinlock held */ | 248 | /* called with spinlock held */ |
244 | static void nuke (struct dummy *dum, struct dummy_ep *ep) | 249 | static void nuke(struct dummy *dum, struct dummy_ep *ep) |
245 | { | 250 | { |
246 | while (!list_empty (&ep->queue)) { | 251 | while (!list_empty(&ep->queue)) { |
247 | struct dummy_request *req; | 252 | struct dummy_request *req; |
248 | 253 | ||
249 | req = list_entry (ep->queue.next, struct dummy_request, queue); | 254 | req = list_entry(ep->queue.next, struct dummy_request, queue); |
250 | list_del_init (&req->queue); | 255 | list_del_init(&req->queue); |
251 | req->req.status = -ESHUTDOWN; | 256 | req->req.status = -ESHUTDOWN; |
252 | 257 | ||
253 | spin_unlock (&dum->lock); | 258 | spin_unlock(&dum->lock); |
254 | req->req.complete (&ep->ep, &req->req); | 259 | req->req.complete(&ep->ep, &req->req); |
255 | spin_lock (&dum->lock); | 260 | spin_lock(&dum->lock); |
256 | } | 261 | } |
257 | } | 262 | } |
258 | 263 | ||
259 | /* caller must hold lock */ | 264 | /* caller must hold lock */ |
260 | static void | 265 | static void stop_activity(struct dummy *dum) |
261 | stop_activity (struct dummy *dum) | ||
262 | { | 266 | { |
263 | struct dummy_ep *ep; | 267 | struct dummy_ep *ep; |
264 | 268 | ||
@@ -268,8 +272,8 @@ stop_activity (struct dummy *dum) | |||
268 | /* The timer is left running so that outstanding URBs can fail */ | 272 | /* The timer is left running so that outstanding URBs can fail */ |
269 | 273 | ||
270 | /* nuke any pending requests first, so driver i/o is quiesced */ | 274 | /* nuke any pending requests first, so driver i/o is quiesced */ |
271 | list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list) | 275 | list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list) |
272 | nuke (dum, ep); | 276 | nuke(dum, ep); |
273 | 277 | ||
274 | /* driver now does any non-usb quiescing necessary */ | 278 | /* driver now does any non-usb quiescing necessary */ |
275 | } | 279 | } |
@@ -404,8 +408,8 @@ static void set_link_state(struct dummy_hcd *dum_hcd) | |||
404 | #define is_enabled(dum) \ | 408 | #define is_enabled(dum) \ |
405 | (dum->port_status & USB_PORT_STAT_ENABLE) | 409 | (dum->port_status & USB_PORT_STAT_ENABLE) |
406 | 410 | ||
407 | static int | 411 | static int dummy_enable(struct usb_ep *_ep, |
408 | dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | 412 | const struct usb_endpoint_descriptor *desc) |
409 | { | 413 | { |
410 | struct dummy *dum; | 414 | struct dummy *dum; |
411 | struct dummy_hcd *dum_hcd; | 415 | struct dummy_hcd *dum_hcd; |
@@ -413,11 +417,11 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
413 | unsigned max; | 417 | unsigned max; |
414 | int retval; | 418 | int retval; |
415 | 419 | ||
416 | ep = usb_ep_to_dummy_ep (_ep); | 420 | ep = usb_ep_to_dummy_ep(_ep); |
417 | if (!_ep || !desc || ep->desc || _ep->name == ep0name | 421 | if (!_ep || !desc || ep->desc || _ep->name == ep0name |
418 | || desc->bDescriptorType != USB_DT_ENDPOINT) | 422 | || desc->bDescriptorType != USB_DT_ENDPOINT) |
419 | return -EINVAL; | 423 | return -EINVAL; |
420 | dum = ep_to_dummy (ep); | 424 | dum = ep_to_dummy(ep); |
421 | if (!dum->driver) | 425 | if (!dum->driver) |
422 | return -ESHUTDOWN; | 426 | return -ESHUTDOWN; |
423 | 427 | ||
@@ -441,10 +445,10 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
441 | * especially for "ep9out" style fixed function ones.) | 445 | * especially for "ep9out" style fixed function ones.) |
442 | */ | 446 | */ |
443 | retval = -EINVAL; | 447 | retval = -EINVAL; |
444 | switch (desc->bmAttributes & 0x03) { | 448 | switch (usb_endpoint_type(desc)) { |
445 | case USB_ENDPOINT_XFER_BULK: | 449 | case USB_ENDPOINT_XFER_BULK: |
446 | if (strstr (ep->ep.name, "-iso") | 450 | if (strstr(ep->ep.name, "-iso") |
447 | || strstr (ep->ep.name, "-int")) { | 451 | || strstr(ep->ep.name, "-int")) { |
448 | goto done; | 452 | goto done; |
449 | } | 453 | } |
450 | switch (dum->gadget.speed) { | 454 | switch (dum->gadget.speed) { |
@@ -466,7 +470,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
466 | } | 470 | } |
467 | break; | 471 | break; |
468 | case USB_ENDPOINT_XFER_INT: | 472 | case USB_ENDPOINT_XFER_INT: |
469 | if (strstr (ep->ep.name, "-iso")) /* bulk is ok */ | 473 | if (strstr(ep->ep.name, "-iso")) /* bulk is ok */ |
470 | goto done; | 474 | goto done; |
471 | /* real hardware might not handle all packet sizes */ | 475 | /* real hardware might not handle all packet sizes */ |
472 | switch (dum->gadget.speed) { | 476 | switch (dum->gadget.speed) { |
@@ -486,8 +490,8 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
486 | } | 490 | } |
487 | break; | 491 | break; |
488 | case USB_ENDPOINT_XFER_ISOC: | 492 | case USB_ENDPOINT_XFER_ISOC: |
489 | if (strstr (ep->ep.name, "-bulk") | 493 | if (strstr(ep->ep.name, "-bulk") |
490 | || strstr (ep->ep.name, "-int")) | 494 | || strstr(ep->ep.name, "-int")) |
491 | goto done; | 495 | goto done; |
492 | /* real hardware might not handle all packet sizes */ | 496 | /* real hardware might not handle all packet sizes */ |
493 | switch (dum->gadget.speed) { | 497 | switch (dum->gadget.speed) { |
@@ -510,14 +514,22 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
510 | } | 514 | } |
511 | 515 | ||
512 | _ep->maxpacket = max; | 516 | _ep->maxpacket = max; |
517 | if (usb_ss_max_streams(_ep->comp_desc)) { | ||
518 | if (!usb_endpoint_xfer_bulk(desc)) { | ||
519 | dev_err(udc_dev(dum), "Can't enable stream support on " | ||
520 | "non-bulk ep %s\n", _ep->name); | ||
521 | return -EINVAL; | ||
522 | } | ||
523 | ep->stream_en = 1; | ||
524 | } | ||
513 | ep->desc = desc; | 525 | ep->desc = desc; |
514 | 526 | ||
515 | dev_dbg (udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n", | 527 | dev_dbg(udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d stream %s\n", |
516 | _ep->name, | 528 | _ep->name, |
517 | desc->bEndpointAddress & 0x0f, | 529 | desc->bEndpointAddress & 0x0f, |
518 | (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", | 530 | (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", |
519 | ({ char *val; | 531 | ({ char *val; |
520 | switch (desc->bmAttributes & 0x03) { | 532 | switch (usb_endpoint_type(desc)) { |
521 | case USB_ENDPOINT_XFER_BULK: | 533 | case USB_ENDPOINT_XFER_BULK: |
522 | val = "bulk"; | 534 | val = "bulk"; |
523 | break; | 535 | break; |
@@ -531,7 +543,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
531 | val = "ctrl"; | 543 | val = "ctrl"; |
532 | break; | 544 | break; |
533 | }; val; }), | 545 | }; val; }), |
534 | max); | 546 | max, ep->stream_en ? "enabled" : "disabled"); |
535 | 547 | ||
536 | /* at this point real hardware should be NAKing transfers | 548 | /* at this point real hardware should be NAKing transfers |
537 | * to that endpoint, until a buffer is queued to it. | 549 | * to that endpoint, until a buffer is queued to it. |
@@ -542,67 +554,67 @@ done: | |||
542 | return retval; | 554 | return retval; |
543 | } | 555 | } |
544 | 556 | ||
545 | static int dummy_disable (struct usb_ep *_ep) | 557 | static int dummy_disable(struct usb_ep *_ep) |
546 | { | 558 | { |
547 | struct dummy_ep *ep; | 559 | struct dummy_ep *ep; |
548 | struct dummy *dum; | 560 | struct dummy *dum; |
549 | unsigned long flags; | 561 | unsigned long flags; |
550 | int retval; | 562 | int retval; |
551 | 563 | ||
552 | ep = usb_ep_to_dummy_ep (_ep); | 564 | ep = usb_ep_to_dummy_ep(_ep); |
553 | if (!_ep || !ep->desc || _ep->name == ep0name) | 565 | if (!_ep || !ep->desc || _ep->name == ep0name) |
554 | return -EINVAL; | 566 | return -EINVAL; |
555 | dum = ep_to_dummy (ep); | 567 | dum = ep_to_dummy(ep); |
556 | 568 | ||
557 | spin_lock_irqsave (&dum->lock, flags); | 569 | spin_lock_irqsave(&dum->lock, flags); |
558 | ep->desc = NULL; | 570 | ep->desc = NULL; |
571 | ep->stream_en = 0; | ||
559 | retval = 0; | 572 | retval = 0; |
560 | nuke (dum, ep); | 573 | nuke(dum, ep); |
561 | spin_unlock_irqrestore (&dum->lock, flags); | 574 | spin_unlock_irqrestore(&dum->lock, flags); |
562 | 575 | ||
563 | dev_dbg (udc_dev(dum), "disabled %s\n", _ep->name); | 576 | dev_dbg(udc_dev(dum), "disabled %s\n", _ep->name); |
564 | return retval; | 577 | return retval; |
565 | } | 578 | } |
566 | 579 | ||
567 | static struct usb_request * | 580 | static struct usb_request *dummy_alloc_request(struct usb_ep *_ep, |
568 | dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags) | 581 | gfp_t mem_flags) |
569 | { | 582 | { |
570 | struct dummy_ep *ep; | 583 | struct dummy_ep *ep; |
571 | struct dummy_request *req; | 584 | struct dummy_request *req; |
572 | 585 | ||
573 | if (!_ep) | 586 | if (!_ep) |
574 | return NULL; | 587 | return NULL; |
575 | ep = usb_ep_to_dummy_ep (_ep); | 588 | ep = usb_ep_to_dummy_ep(_ep); |
576 | 589 | ||
577 | req = kzalloc(sizeof(*req), mem_flags); | 590 | req = kzalloc(sizeof(*req), mem_flags); |
578 | if (!req) | 591 | if (!req) |
579 | return NULL; | 592 | return NULL; |
580 | INIT_LIST_HEAD (&req->queue); | 593 | INIT_LIST_HEAD(&req->queue); |
581 | return &req->req; | 594 | return &req->req; |
582 | } | 595 | } |
583 | 596 | ||
584 | static void | 597 | static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req) |
585 | dummy_free_request (struct usb_ep *_ep, struct usb_request *_req) | ||
586 | { | 598 | { |
587 | struct dummy_ep *ep; | 599 | struct dummy_ep *ep; |
588 | struct dummy_request *req; | 600 | struct dummy_request *req; |
589 | 601 | ||
590 | ep = usb_ep_to_dummy_ep (_ep); | 602 | if (!_ep || !_req) |
591 | if (!ep || !_req || (!ep->desc && _ep->name != ep0name)) | 603 | return; |
604 | ep = usb_ep_to_dummy_ep(_ep); | ||
605 | if (!ep->desc && _ep->name != ep0name) | ||
592 | return; | 606 | return; |
593 | 607 | ||
594 | req = usb_request_to_dummy_request (_req); | 608 | req = usb_request_to_dummy_request(_req); |
595 | WARN_ON (!list_empty (&req->queue)); | 609 | WARN_ON(!list_empty(&req->queue)); |
596 | kfree (req); | 610 | kfree(req); |
597 | } | 611 | } |
598 | 612 | ||
599 | static void | 613 | static void fifo_complete(struct usb_ep *ep, struct usb_request *req) |
600 | fifo_complete (struct usb_ep *ep, struct usb_request *req) | ||
601 | { | 614 | { |
602 | } | 615 | } |
603 | 616 | ||
604 | static int | 617 | static int dummy_queue(struct usb_ep *_ep, struct usb_request *_req, |
605 | dummy_queue (struct usb_ep *_ep, struct usb_request *_req, | ||
606 | gfp_t mem_flags) | 618 | gfp_t mem_flags) |
607 | { | 619 | { |
608 | struct dummy_ep *ep; | 620 | struct dummy_ep *ep; |
@@ -611,49 +623,48 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, | |||
611 | struct dummy_hcd *dum_hcd; | 623 | struct dummy_hcd *dum_hcd; |
612 | unsigned long flags; | 624 | unsigned long flags; |
613 | 625 | ||
614 | req = usb_request_to_dummy_request (_req); | 626 | req = usb_request_to_dummy_request(_req); |
615 | if (!_req || !list_empty (&req->queue) || !_req->complete) | 627 | if (!_req || !list_empty(&req->queue) || !_req->complete) |
616 | return -EINVAL; | 628 | return -EINVAL; |
617 | 629 | ||
618 | ep = usb_ep_to_dummy_ep (_ep); | 630 | ep = usb_ep_to_dummy_ep(_ep); |
619 | if (!_ep || (!ep->desc && _ep->name != ep0name)) | 631 | if (!_ep || (!ep->desc && _ep->name != ep0name)) |
620 | return -EINVAL; | 632 | return -EINVAL; |
621 | 633 | ||
622 | dum = ep_to_dummy (ep); | 634 | dum = ep_to_dummy(ep); |
623 | dum_hcd = gadget_to_dummy_hcd(&dum->gadget); | 635 | dum_hcd = gadget_to_dummy_hcd(&dum->gadget); |
624 | if (!dum->driver || !is_enabled(dum_hcd)) | 636 | if (!dum->driver || !is_enabled(dum_hcd)) |
625 | return -ESHUTDOWN; | 637 | return -ESHUTDOWN; |
626 | 638 | ||
627 | #if 0 | 639 | #if 0 |
628 | dev_dbg (udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", | 640 | dev_dbg(udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", |
629 | ep, _req, _ep->name, _req->length, _req->buf); | 641 | ep, _req, _ep->name, _req->length, _req->buf); |
630 | #endif | 642 | #endif |
631 | |||
632 | _req->status = -EINPROGRESS; | 643 | _req->status = -EINPROGRESS; |
633 | _req->actual = 0; | 644 | _req->actual = 0; |
634 | spin_lock_irqsave (&dum->lock, flags); | 645 | spin_lock_irqsave(&dum->lock, flags); |
635 | 646 | ||
636 | /* implement an emulated single-request FIFO */ | 647 | /* implement an emulated single-request FIFO */ |
637 | if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && | 648 | if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && |
638 | list_empty (&dum->fifo_req.queue) && | 649 | list_empty(&dum->fifo_req.queue) && |
639 | list_empty (&ep->queue) && | 650 | list_empty(&ep->queue) && |
640 | _req->length <= FIFO_SIZE) { | 651 | _req->length <= FIFO_SIZE) { |
641 | req = &dum->fifo_req; | 652 | req = &dum->fifo_req; |
642 | req->req = *_req; | 653 | req->req = *_req; |
643 | req->req.buf = dum->fifo_buf; | 654 | req->req.buf = dum->fifo_buf; |
644 | memcpy (dum->fifo_buf, _req->buf, _req->length); | 655 | memcpy(dum->fifo_buf, _req->buf, _req->length); |
645 | req->req.context = dum; | 656 | req->req.context = dum; |
646 | req->req.complete = fifo_complete; | 657 | req->req.complete = fifo_complete; |
647 | 658 | ||
648 | list_add_tail(&req->queue, &ep->queue); | 659 | list_add_tail(&req->queue, &ep->queue); |
649 | spin_unlock (&dum->lock); | 660 | spin_unlock(&dum->lock); |
650 | _req->actual = _req->length; | 661 | _req->actual = _req->length; |
651 | _req->status = 0; | 662 | _req->status = 0; |
652 | _req->complete (_ep, _req); | 663 | _req->complete(_ep, _req); |
653 | spin_lock (&dum->lock); | 664 | spin_lock(&dum->lock); |
654 | } else | 665 | } else |
655 | list_add_tail(&req->queue, &ep->queue); | 666 | list_add_tail(&req->queue, &ep->queue); |
656 | spin_unlock_irqrestore (&dum->lock, flags); | 667 | spin_unlock_irqrestore(&dum->lock, flags); |
657 | 668 | ||
658 | /* real hardware would likely enable transfers here, in case | 669 | /* real hardware would likely enable transfers here, in case |
659 | * it'd been left NAKing. | 670 | * it'd been left NAKing. |
@@ -661,7 +672,7 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, | |||
661 | return 0; | 672 | return 0; |
662 | } | 673 | } |
663 | 674 | ||
664 | static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) | 675 | static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req) |
665 | { | 676 | { |
666 | struct dummy_ep *ep; | 677 | struct dummy_ep *ep; |
667 | struct dummy *dum; | 678 | struct dummy *dum; |
@@ -671,31 +682,31 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) | |||
671 | 682 | ||
672 | if (!_ep || !_req) | 683 | if (!_ep || !_req) |
673 | return retval; | 684 | return retval; |
674 | ep = usb_ep_to_dummy_ep (_ep); | 685 | ep = usb_ep_to_dummy_ep(_ep); |
675 | dum = ep_to_dummy (ep); | 686 | dum = ep_to_dummy(ep); |
676 | 687 | ||
677 | if (!dum->driver) | 688 | if (!dum->driver) |
678 | return -ESHUTDOWN; | 689 | return -ESHUTDOWN; |
679 | 690 | ||
680 | local_irq_save (flags); | 691 | local_irq_save(flags); |
681 | spin_lock (&dum->lock); | 692 | spin_lock(&dum->lock); |
682 | list_for_each_entry (req, &ep->queue, queue) { | 693 | list_for_each_entry(req, &ep->queue, queue) { |
683 | if (&req->req == _req) { | 694 | if (&req->req == _req) { |
684 | list_del_init (&req->queue); | 695 | list_del_init(&req->queue); |
685 | _req->status = -ECONNRESET; | 696 | _req->status = -ECONNRESET; |
686 | retval = 0; | 697 | retval = 0; |
687 | break; | 698 | break; |
688 | } | 699 | } |
689 | } | 700 | } |
690 | spin_unlock (&dum->lock); | 701 | spin_unlock(&dum->lock); |
691 | 702 | ||
692 | if (retval == 0) { | 703 | if (retval == 0) { |
693 | dev_dbg (udc_dev(dum), | 704 | dev_dbg(udc_dev(dum), |
694 | "dequeued req %p from %s, len %d buf %p\n", | 705 | "dequeued req %p from %s, len %d buf %p\n", |
695 | req, _ep->name, _req->length, _req->buf); | 706 | req, _ep->name, _req->length, _req->buf); |
696 | _req->complete (_ep, _req); | 707 | _req->complete(_ep, _req); |
697 | } | 708 | } |
698 | local_irq_restore (flags); | 709 | local_irq_restore(flags); |
699 | return retval; | 710 | return retval; |
700 | } | 711 | } |
701 | 712 | ||
@@ -707,14 +718,14 @@ dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | |||
707 | 718 | ||
708 | if (!_ep) | 719 | if (!_ep) |
709 | return -EINVAL; | 720 | return -EINVAL; |
710 | ep = usb_ep_to_dummy_ep (_ep); | 721 | ep = usb_ep_to_dummy_ep(_ep); |
711 | dum = ep_to_dummy (ep); | 722 | dum = ep_to_dummy(ep); |
712 | if (!dum->driver) | 723 | if (!dum->driver) |
713 | return -ESHUTDOWN; | 724 | return -ESHUTDOWN; |
714 | if (!value) | 725 | if (!value) |
715 | ep->halted = ep->wedged = 0; | 726 | ep->halted = ep->wedged = 0; |
716 | else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && | 727 | else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && |
717 | !list_empty (&ep->queue)) | 728 | !list_empty(&ep->queue)) |
718 | return -EAGAIN; | 729 | return -EAGAIN; |
719 | else { | 730 | else { |
720 | ep->halted = 1; | 731 | ep->halted = 1; |
@@ -755,15 +766,15 @@ static const struct usb_ep_ops dummy_ep_ops = { | |||
755 | /*-------------------------------------------------------------------------*/ | 766 | /*-------------------------------------------------------------------------*/ |
756 | 767 | ||
757 | /* there are both host and device side versions of this call ... */ | 768 | /* there are both host and device side versions of this call ... */ |
758 | static int dummy_g_get_frame (struct usb_gadget *_gadget) | 769 | static int dummy_g_get_frame(struct usb_gadget *_gadget) |
759 | { | 770 | { |
760 | struct timeval tv; | 771 | struct timeval tv; |
761 | 772 | ||
762 | do_gettimeofday (&tv); | 773 | do_gettimeofday(&tv); |
763 | return tv.tv_usec / 1000; | 774 | return tv.tv_usec / 1000; |
764 | } | 775 | } |
765 | 776 | ||
766 | static int dummy_wakeup (struct usb_gadget *_gadget) | 777 | static int dummy_wakeup(struct usb_gadget *_gadget) |
767 | { | 778 | { |
768 | struct dummy_hcd *dum_hcd; | 779 | struct dummy_hcd *dum_hcd; |
769 | 780 | ||
@@ -786,11 +797,11 @@ static int dummy_wakeup (struct usb_gadget *_gadget) | |||
786 | return 0; | 797 | return 0; |
787 | } | 798 | } |
788 | 799 | ||
789 | static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) | 800 | static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value) |
790 | { | 801 | { |
791 | struct dummy *dum; | 802 | struct dummy *dum; |
792 | 803 | ||
793 | dum = (gadget_to_dummy_hcd(_gadget))->dum; | 804 | dum = gadget_to_dummy_hcd(_gadget)->dum; |
794 | if (value) | 805 | if (value) |
795 | dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); | 806 | dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); |
796 | else | 807 | else |
@@ -798,22 +809,15 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) | |||
798 | return 0; | 809 | return 0; |
799 | } | 810 | } |
800 | 811 | ||
801 | static void dummy_udc_udpate_ep0(struct dummy *dum) | 812 | static void dummy_udc_update_ep0(struct dummy *dum) |
802 | { | 813 | { |
803 | u32 i; | 814 | if (dum->gadget.speed == USB_SPEED_SUPER) |
804 | |||
805 | if (dum->gadget.speed == USB_SPEED_SUPER) { | ||
806 | for (i = 0; i < DUMMY_ENDPOINTS; i++) | ||
807 | dum->ep[i].ep.max_streams = 0x10; | ||
808 | dum->ep[0].ep.maxpacket = 9; | 815 | dum->ep[0].ep.maxpacket = 9; |
809 | } else { | 816 | else |
810 | for (i = 0; i < DUMMY_ENDPOINTS; i++) | ||
811 | dum->ep[i].ep.max_streams = 0; | ||
812 | dum->ep[0].ep.maxpacket = 64; | 817 | dum->ep[0].ep.maxpacket = 64; |
813 | } | ||
814 | } | 818 | } |
815 | 819 | ||
816 | static int dummy_pullup (struct usb_gadget *_gadget, int value) | 820 | static int dummy_pullup(struct usb_gadget *_gadget, int value) |
817 | { | 821 | { |
818 | struct dummy_hcd *dum_hcd; | 822 | struct dummy_hcd *dum_hcd; |
819 | struct dummy *dum; | 823 | struct dummy *dum; |
@@ -829,7 +833,7 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) | |||
829 | dum->driver->max_speed); | 833 | dum->driver->max_speed); |
830 | else | 834 | else |
831 | dum->gadget.speed = USB_SPEED_FULL; | 835 | dum->gadget.speed = USB_SPEED_FULL; |
832 | dummy_udc_udpate_ep0(dum); | 836 | dummy_udc_update_ep0(dum); |
833 | 837 | ||
834 | if (dum->gadget.speed < dum->driver->max_speed) | 838 | if (dum->gadget.speed < dum->driver->max_speed) |
835 | dev_dbg(udc_dev(dum), "This device can perform faster" | 839 | dev_dbg(udc_dev(dum), "This device can perform faster" |
@@ -838,10 +842,10 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) | |||
838 | } | 842 | } |
839 | dum_hcd = gadget_to_dummy_hcd(_gadget); | 843 | dum_hcd = gadget_to_dummy_hcd(_gadget); |
840 | 844 | ||
841 | spin_lock_irqsave (&dum->lock, flags); | 845 | spin_lock_irqsave(&dum->lock, flags); |
842 | dum->pullup = (value != 0); | 846 | dum->pullup = (value != 0); |
843 | set_link_state(dum_hcd); | 847 | set_link_state(dum_hcd); |
844 | spin_unlock_irqrestore (&dum->lock, flags); | 848 | spin_unlock_irqrestore(&dum->lock, flags); |
845 | 849 | ||
846 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); | 850 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); |
847 | return 0; | 851 | return 0; |
@@ -864,16 +868,16 @@ static const struct usb_gadget_ops dummy_ops = { | |||
864 | /*-------------------------------------------------------------------------*/ | 868 | /*-------------------------------------------------------------------------*/ |
865 | 869 | ||
866 | /* "function" sysfs attribute */ | 870 | /* "function" sysfs attribute */ |
867 | static ssize_t | 871 | static ssize_t show_function(struct device *dev, struct device_attribute *attr, |
868 | show_function (struct device *dev, struct device_attribute *attr, char *buf) | 872 | char *buf) |
869 | { | 873 | { |
870 | struct dummy *dum = gadget_dev_to_dummy (dev); | 874 | struct dummy *dum = gadget_dev_to_dummy(dev); |
871 | 875 | ||
872 | if (!dum->driver || !dum->driver->function) | 876 | if (!dum->driver || !dum->driver->function) |
873 | return 0; | 877 | return 0; |
874 | return scnprintf (buf, PAGE_SIZE, "%s\n", dum->driver->function); | 878 | return scnprintf(buf, PAGE_SIZE, "%s\n", dum->driver->function); |
875 | } | 879 | } |
876 | static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); | 880 | static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); |
877 | 881 | ||
878 | /*-------------------------------------------------------------------------*/ | 882 | /*-------------------------------------------------------------------------*/ |
879 | 883 | ||
@@ -908,7 +912,7 @@ static int dummy_udc_start(struct usb_gadget *g, | |||
908 | dum->devstatus = 0; | 912 | dum->devstatus = 0; |
909 | 913 | ||
910 | dum->driver = driver; | 914 | dum->driver = driver; |
911 | dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", | 915 | dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", |
912 | driver->driver.name); | 916 | driver->driver.name); |
913 | return 0; | 917 | return 0; |
914 | } | 918 | } |
@@ -919,7 +923,7 @@ static int dummy_udc_stop(struct usb_gadget *g, | |||
919 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); | 923 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); |
920 | struct dummy *dum = dum_hcd->dum; | 924 | struct dummy *dum = dum_hcd->dum; |
921 | 925 | ||
922 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", | 926 | dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", |
923 | driver->driver.name); | 927 | driver->driver.name); |
924 | 928 | ||
925 | dum->driver = NULL; | 929 | dum->driver = NULL; |
@@ -932,8 +936,7 @@ static int dummy_udc_stop(struct usb_gadget *g, | |||
932 | 936 | ||
933 | /* The gadget structure is stored inside the hcd structure and will be | 937 | /* The gadget structure is stored inside the hcd structure and will be |
934 | * released along with it. */ | 938 | * released along with it. */ |
935 | static void | 939 | static void dummy_gadget_release(struct device *dev) |
936 | dummy_gadget_release (struct device *dev) | ||
937 | { | 940 | { |
938 | return; | 941 | return; |
939 | } | 942 | } |
@@ -954,6 +957,7 @@ static void init_dummy_udc_hw(struct dummy *dum) | |||
954 | ep->halted = ep->wedged = ep->already_seen = | 957 | ep->halted = ep->wedged = ep->already_seen = |
955 | ep->setup_stage = 0; | 958 | ep->setup_stage = 0; |
956 | ep->ep.maxpacket = ~0; | 959 | ep->ep.maxpacket = ~0; |
960 | ep->ep.max_streams = 16; | ||
957 | ep->last_io = jiffies; | 961 | ep->last_io = jiffies; |
958 | ep->gadget = &dum->gadget; | 962 | ep->gadget = &dum->gadget; |
959 | ep->desc = NULL; | 963 | ep->desc = NULL; |
@@ -969,7 +973,7 @@ static void init_dummy_udc_hw(struct dummy *dum) | |||
969 | #endif | 973 | #endif |
970 | } | 974 | } |
971 | 975 | ||
972 | static int dummy_udc_probe (struct platform_device *pdev) | 976 | static int dummy_udc_probe(struct platform_device *pdev) |
973 | { | 977 | { |
974 | struct dummy *dum = &the_controller; | 978 | struct dummy *dum = &the_controller; |
975 | int rc; | 979 | int rc; |
@@ -981,7 +985,7 @@ static int dummy_udc_probe (struct platform_device *pdev) | |||
981 | dev_set_name(&dum->gadget.dev, "gadget"); | 985 | dev_set_name(&dum->gadget.dev, "gadget"); |
982 | dum->gadget.dev.parent = &pdev->dev; | 986 | dum->gadget.dev.parent = &pdev->dev; |
983 | dum->gadget.dev.release = dummy_gadget_release; | 987 | dum->gadget.dev.release = dummy_gadget_release; |
984 | rc = device_register (&dum->gadget.dev); | 988 | rc = device_register(&dum->gadget.dev); |
985 | if (rc < 0) { | 989 | if (rc < 0) { |
986 | put_device(&dum->gadget.dev); | 990 | put_device(&dum->gadget.dev); |
987 | return rc; | 991 | return rc; |
@@ -993,7 +997,7 @@ static int dummy_udc_probe (struct platform_device *pdev) | |||
993 | if (rc < 0) | 997 | if (rc < 0) |
994 | goto err_udc; | 998 | goto err_udc; |
995 | 999 | ||
996 | rc = device_create_file (&dum->gadget.dev, &dev_attr_function); | 1000 | rc = device_create_file(&dum->gadget.dev, &dev_attr_function); |
997 | if (rc < 0) | 1001 | if (rc < 0) |
998 | goto err_dev; | 1002 | goto err_dev; |
999 | platform_set_drvdata(pdev, dum); | 1003 | platform_set_drvdata(pdev, dum); |
@@ -1006,14 +1010,14 @@ err_udc: | |||
1006 | return rc; | 1010 | return rc; |
1007 | } | 1011 | } |
1008 | 1012 | ||
1009 | static int dummy_udc_remove (struct platform_device *pdev) | 1013 | static int dummy_udc_remove(struct platform_device *pdev) |
1010 | { | 1014 | { |
1011 | struct dummy *dum = platform_get_drvdata (pdev); | 1015 | struct dummy *dum = platform_get_drvdata(pdev); |
1012 | 1016 | ||
1013 | usb_del_gadget_udc(&dum->gadget); | 1017 | usb_del_gadget_udc(&dum->gadget); |
1014 | platform_set_drvdata (pdev, NULL); | 1018 | platform_set_drvdata(pdev, NULL); |
1015 | device_remove_file (&dum->gadget.dev, &dev_attr_function); | 1019 | device_remove_file(&dum->gadget.dev, &dev_attr_function); |
1016 | device_unregister (&dum->gadget.dev); | 1020 | device_unregister(&dum->gadget.dev); |
1017 | return 0; | 1021 | return 0; |
1018 | } | 1022 | } |
1019 | 1023 | ||
@@ -1061,6 +1065,16 @@ static struct platform_driver dummy_udc_driver = { | |||
1061 | 1065 | ||
1062 | /*-------------------------------------------------------------------------*/ | 1066 | /*-------------------------------------------------------------------------*/ |
1063 | 1067 | ||
1068 | static unsigned int dummy_get_ep_idx(const struct usb_endpoint_descriptor *desc) | ||
1069 | { | ||
1070 | unsigned int index; | ||
1071 | |||
1072 | index = usb_endpoint_num(desc) << 1; | ||
1073 | if (usb_endpoint_dir_in(desc)) | ||
1074 | index |= 1; | ||
1075 | return index; | ||
1076 | } | ||
1077 | |||
1064 | /* MASTER/HOST SIDE DRIVER | 1078 | /* MASTER/HOST SIDE DRIVER |
1065 | * | 1079 | * |
1066 | * this uses the hcd framework to hook up to host side drivers. | 1080 | * this uses the hcd framework to hook up to host side drivers. |
@@ -1073,7 +1087,82 @@ static struct platform_driver dummy_udc_driver = { | |||
1073 | * usb 2.0 rules. | 1087 | * usb 2.0 rules. |
1074 | */ | 1088 | */ |
1075 | 1089 | ||
1076 | static int dummy_urb_enqueue ( | 1090 | static int dummy_ep_stream_en(struct dummy_hcd *dum_hcd, struct urb *urb) |
1091 | { | ||
1092 | const struct usb_endpoint_descriptor *desc = &urb->ep->desc; | ||
1093 | u32 index; | ||
1094 | |||
1095 | if (!usb_endpoint_xfer_bulk(desc)) | ||
1096 | return 0; | ||
1097 | |||
1098 | index = dummy_get_ep_idx(desc); | ||
1099 | return (1 << index) & dum_hcd->stream_en_ep; | ||
1100 | } | ||
1101 | |||
1102 | /* | ||
1103 | * The max stream number is saved as a nibble so for the 30 possible endpoints | ||
1104 | * we only 15 bytes of memory. Therefore we are limited to max 16 streams (0 | ||
1105 | * means we use only 1 stream). The maximum according to the spec is 16bit so | ||
1106 | * if the 16 stream limit is about to go, the array size should be incremented | ||
1107 | * to 30 elements of type u16. | ||
1108 | */ | ||
1109 | static int get_max_streams_for_pipe(struct dummy_hcd *dum_hcd, | ||
1110 | unsigned int pipe) | ||
1111 | { | ||
1112 | int max_streams; | ||
1113 | |||
1114 | max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)]; | ||
1115 | if (usb_pipeout(pipe)) | ||
1116 | max_streams >>= 4; | ||
1117 | else | ||
1118 | max_streams &= 0xf; | ||
1119 | max_streams++; | ||
1120 | return max_streams; | ||
1121 | } | ||
1122 | |||
1123 | static void set_max_streams_for_pipe(struct dummy_hcd *dum_hcd, | ||
1124 | unsigned int pipe, unsigned int streams) | ||
1125 | { | ||
1126 | int max_streams; | ||
1127 | |||
1128 | streams--; | ||
1129 | max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)]; | ||
1130 | if (usb_pipeout(pipe)) { | ||
1131 | streams <<= 4; | ||
1132 | max_streams &= 0xf; | ||
1133 | } else { | ||
1134 | max_streams &= 0xf0; | ||
1135 | } | ||
1136 | max_streams |= streams; | ||
1137 | dum_hcd->num_stream[usb_pipeendpoint(pipe)] = max_streams; | ||
1138 | } | ||
1139 | |||
1140 | static int dummy_validate_stream(struct dummy_hcd *dum_hcd, struct urb *urb) | ||
1141 | { | ||
1142 | unsigned int max_streams; | ||
1143 | int enabled; | ||
1144 | |||
1145 | enabled = dummy_ep_stream_en(dum_hcd, urb); | ||
1146 | if (!urb->stream_id) { | ||
1147 | if (enabled) | ||
1148 | return -EINVAL; | ||
1149 | return 0; | ||
1150 | } | ||
1151 | if (!enabled) | ||
1152 | return -EINVAL; | ||
1153 | |||
1154 | max_streams = get_max_streams_for_pipe(dum_hcd, | ||
1155 | usb_pipeendpoint(urb->pipe)); | ||
1156 | if (urb->stream_id > max_streams) { | ||
1157 | dev_err(dummy_dev(dum_hcd), "Stream id %d is out of range.\n", | ||
1158 | urb->stream_id); | ||
1159 | BUG(); | ||
1160 | return -EINVAL; | ||
1161 | } | ||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | static int dummy_urb_enqueue( | ||
1077 | struct usb_hcd *hcd, | 1166 | struct usb_hcd *hcd, |
1078 | struct urb *urb, | 1167 | struct urb *urb, |
1079 | gfp_t mem_flags | 1168 | gfp_t mem_flags |
@@ -1083,16 +1172,21 @@ static int dummy_urb_enqueue ( | |||
1083 | unsigned long flags; | 1172 | unsigned long flags; |
1084 | int rc; | 1173 | int rc; |
1085 | 1174 | ||
1086 | if (!urb->transfer_buffer && urb->transfer_buffer_length) | 1175 | urbp = kmalloc(sizeof *urbp, mem_flags); |
1087 | return -EINVAL; | ||
1088 | |||
1089 | urbp = kmalloc (sizeof *urbp, mem_flags); | ||
1090 | if (!urbp) | 1176 | if (!urbp) |
1091 | return -ENOMEM; | 1177 | return -ENOMEM; |
1092 | urbp->urb = urb; | 1178 | urbp->urb = urb; |
1179 | urbp->miter_started = 0; | ||
1093 | 1180 | ||
1094 | dum_hcd = hcd_to_dummy_hcd(hcd); | 1181 | dum_hcd = hcd_to_dummy_hcd(hcd); |
1095 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); | 1182 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
1183 | |||
1184 | rc = dummy_validate_stream(dum_hcd, urb); | ||
1185 | if (rc) { | ||
1186 | kfree(urbp); | ||
1187 | goto done; | ||
1188 | } | ||
1189 | |||
1096 | rc = usb_hcd_link_urb_to_ep(hcd, urb); | 1190 | rc = usb_hcd_link_urb_to_ep(hcd, urb); |
1097 | if (rc) { | 1191 | if (rc) { |
1098 | kfree(urbp); | 1192 | kfree(urbp); |
@@ -1107,7 +1201,7 @@ static int dummy_urb_enqueue ( | |||
1107 | 1201 | ||
1108 | list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); | 1202 | list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); |
1109 | urb->hcpriv = urbp; | 1203 | urb->hcpriv = urbp; |
1110 | if (usb_pipetype (urb->pipe) == PIPE_CONTROL) | 1204 | if (usb_pipetype(urb->pipe) == PIPE_CONTROL) |
1111 | urb->error_count = 1; /* mark as a new urb */ | 1205 | urb->error_count = 1; /* mark as a new urb */ |
1112 | 1206 | ||
1113 | /* kick the scheduler, it'll do the rest */ | 1207 | /* kick the scheduler, it'll do the rest */ |
@@ -1139,20 +1233,91 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1139 | return rc; | 1233 | return rc; |
1140 | } | 1234 | } |
1141 | 1235 | ||
1236 | static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, | ||
1237 | u32 len) | ||
1238 | { | ||
1239 | void *ubuf, *rbuf; | ||
1240 | struct urbp *urbp = urb->hcpriv; | ||
1241 | int to_host; | ||
1242 | struct sg_mapping_iter *miter = &urbp->miter; | ||
1243 | u32 trans = 0; | ||
1244 | u32 this_sg; | ||
1245 | bool next_sg; | ||
1246 | |||
1247 | to_host = usb_pipein(urb->pipe); | ||
1248 | rbuf = req->req.buf + req->req.actual; | ||
1249 | |||
1250 | if (!urb->num_sgs) { | ||
1251 | ubuf = urb->transfer_buffer + urb->actual_length; | ||
1252 | if (to_host) | ||
1253 | memcpy(ubuf, rbuf, len); | ||
1254 | else | ||
1255 | memcpy(rbuf, ubuf, len); | ||
1256 | return len; | ||
1257 | } | ||
1258 | |||
1259 | if (!urbp->miter_started) { | ||
1260 | u32 flags = SG_MITER_ATOMIC; | ||
1261 | |||
1262 | if (to_host) | ||
1263 | flags |= SG_MITER_TO_SG; | ||
1264 | else | ||
1265 | flags |= SG_MITER_FROM_SG; | ||
1266 | |||
1267 | sg_miter_start(miter, urb->sg, urb->num_sgs, flags); | ||
1268 | urbp->miter_started = 1; | ||
1269 | } | ||
1270 | next_sg = sg_miter_next(miter); | ||
1271 | if (next_sg == false) { | ||
1272 | WARN_ON_ONCE(1); | ||
1273 | return -EINVAL; | ||
1274 | } | ||
1275 | do { | ||
1276 | ubuf = miter->addr; | ||
1277 | this_sg = min_t(u32, len, miter->length); | ||
1278 | miter->consumed = this_sg; | ||
1279 | trans += this_sg; | ||
1280 | |||
1281 | if (to_host) | ||
1282 | memcpy(ubuf, rbuf, this_sg); | ||
1283 | else | ||
1284 | memcpy(rbuf, ubuf, this_sg); | ||
1285 | len -= this_sg; | ||
1286 | |||
1287 | if (!len) | ||
1288 | break; | ||
1289 | next_sg = sg_miter_next(miter); | ||
1290 | if (next_sg == false) { | ||
1291 | WARN_ON_ONCE(1); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | |||
1295 | rbuf += this_sg; | ||
1296 | } while (1); | ||
1297 | |||
1298 | sg_miter_stop(miter); | ||
1299 | return trans; | ||
1300 | } | ||
1301 | |||
1142 | /* transfer up to a frame's worth; caller must own lock */ | 1302 | /* transfer up to a frame's worth; caller must own lock */ |
1143 | static int | 1303 | static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb, |
1144 | transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, | 1304 | struct dummy_ep *ep, int limit, int *status) |
1145 | int *status) | ||
1146 | { | 1305 | { |
1306 | struct dummy *dum = dum_hcd->dum; | ||
1147 | struct dummy_request *req; | 1307 | struct dummy_request *req; |
1148 | 1308 | ||
1149 | top: | 1309 | top: |
1150 | /* if there's no request queued, the device is NAKing; return */ | 1310 | /* if there's no request queued, the device is NAKing; return */ |
1151 | list_for_each_entry (req, &ep->queue, queue) { | 1311 | list_for_each_entry(req, &ep->queue, queue) { |
1152 | unsigned host_len, dev_len, len; | 1312 | unsigned host_len, dev_len, len; |
1153 | int is_short, to_host; | 1313 | int is_short, to_host; |
1154 | int rescan = 0; | 1314 | int rescan = 0; |
1155 | 1315 | ||
1316 | if (dummy_ep_stream_en(dum_hcd, urb)) { | ||
1317 | if ((urb->stream_id != req->req.stream_id)) | ||
1318 | continue; | ||
1319 | } | ||
1320 | |||
1156 | /* 1..N packets of ep->ep.maxpacket each ... the last one | 1321 | /* 1..N packets of ep->ep.maxpacket each ... the last one |
1157 | * may be short (including zero length). | 1322 | * may be short (including zero length). |
1158 | * | 1323 | * |
@@ -1162,20 +1327,18 @@ top: | |||
1162 | */ | 1327 | */ |
1163 | host_len = urb->transfer_buffer_length - urb->actual_length; | 1328 | host_len = urb->transfer_buffer_length - urb->actual_length; |
1164 | dev_len = req->req.length - req->req.actual; | 1329 | dev_len = req->req.length - req->req.actual; |
1165 | len = min (host_len, dev_len); | 1330 | len = min(host_len, dev_len); |
1166 | 1331 | ||
1167 | /* FIXME update emulated data toggle too */ | 1332 | /* FIXME update emulated data toggle too */ |
1168 | 1333 | ||
1169 | to_host = usb_pipein (urb->pipe); | 1334 | to_host = usb_pipein(urb->pipe); |
1170 | if (unlikely (len == 0)) | 1335 | if (unlikely(len == 0)) |
1171 | is_short = 1; | 1336 | is_short = 1; |
1172 | else { | 1337 | else { |
1173 | char *ubuf, *rbuf; | ||
1174 | |||
1175 | /* not enough bandwidth left? */ | 1338 | /* not enough bandwidth left? */ |
1176 | if (limit < ep->ep.maxpacket && limit < len) | 1339 | if (limit < ep->ep.maxpacket && limit < len) |
1177 | break; | 1340 | break; |
1178 | len = min (len, (unsigned) limit); | 1341 | len = min_t(unsigned, len, limit); |
1179 | if (len == 0) | 1342 | if (len == 0) |
1180 | break; | 1343 | break; |
1181 | 1344 | ||
@@ -1186,18 +1349,16 @@ top: | |||
1186 | } | 1349 | } |
1187 | is_short = (len % ep->ep.maxpacket) != 0; | 1350 | is_short = (len % ep->ep.maxpacket) != 0; |
1188 | 1351 | ||
1189 | /* else transfer packet(s) */ | 1352 | len = dummy_perform_transfer(urb, req, len); |
1190 | ubuf = urb->transfer_buffer + urb->actual_length; | ||
1191 | rbuf = req->req.buf + req->req.actual; | ||
1192 | if (to_host) | ||
1193 | memcpy (ubuf, rbuf, len); | ||
1194 | else | ||
1195 | memcpy (rbuf, ubuf, len); | ||
1196 | ep->last_io = jiffies; | ||
1197 | 1353 | ||
1198 | limit -= len; | 1354 | ep->last_io = jiffies; |
1199 | urb->actual_length += len; | 1355 | if (len < 0) { |
1200 | req->req.actual += len; | 1356 | req->req.status = len; |
1357 | } else { | ||
1358 | limit -= len; | ||
1359 | urb->actual_length += len; | ||
1360 | req->req.actual += len; | ||
1361 | } | ||
1201 | } | 1362 | } |
1202 | 1363 | ||
1203 | /* short packets terminate, maybe with overflow/underflow. | 1364 | /* short packets terminate, maybe with overflow/underflow. |
@@ -1238,11 +1399,11 @@ top: | |||
1238 | 1399 | ||
1239 | /* device side completion --> continuable */ | 1400 | /* device side completion --> continuable */ |
1240 | if (req->req.status != -EINPROGRESS) { | 1401 | if (req->req.status != -EINPROGRESS) { |
1241 | list_del_init (&req->queue); | 1402 | list_del_init(&req->queue); |
1242 | 1403 | ||
1243 | spin_unlock (&dum->lock); | 1404 | spin_unlock(&dum->lock); |
1244 | req->req.complete (&ep->ep, &req->req); | 1405 | req->req.complete(&ep->ep, &req->req); |
1245 | spin_lock (&dum->lock); | 1406 | spin_lock(&dum->lock); |
1246 | 1407 | ||
1247 | /* requests might have been unlinked... */ | 1408 | /* requests might have been unlinked... */ |
1248 | rescan = 1; | 1409 | rescan = 1; |
@@ -1259,7 +1420,7 @@ top: | |||
1259 | return limit; | 1420 | return limit; |
1260 | } | 1421 | } |
1261 | 1422 | ||
1262 | static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) | 1423 | static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep) |
1263 | { | 1424 | { |
1264 | int limit = ep->ep.maxpacket; | 1425 | int limit = ep->ep.maxpacket; |
1265 | 1426 | ||
@@ -1273,7 +1434,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) | |||
1273 | limit += limit * tmp; | 1434 | limit += limit * tmp; |
1274 | } | 1435 | } |
1275 | if (dum->gadget.speed == USB_SPEED_SUPER) { | 1436 | if (dum->gadget.speed == USB_SPEED_SUPER) { |
1276 | switch (ep->desc->bmAttributes & 0x03) { | 1437 | switch (usb_endpoint_type(ep->desc)) { |
1277 | case USB_ENDPOINT_XFER_ISOC: | 1438 | case USB_ENDPOINT_XFER_ISOC: |
1278 | /* Sec. 4.4.8.2 USB3.0 Spec */ | 1439 | /* Sec. 4.4.8.2 USB3.0 Spec */ |
1279 | limit = 3 * 16 * 1024 * 8; | 1440 | limit = 3 * 16 * 1024 * 8; |
@@ -1295,7 +1456,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) | |||
1295 | USB_PORT_STAT_SUSPEND)) \ | 1456 | USB_PORT_STAT_SUSPEND)) \ |
1296 | == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) | 1457 | == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) |
1297 | 1458 | ||
1298 | static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) | 1459 | static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) |
1299 | { | 1460 | { |
1300 | int i; | 1461 | int i; |
1301 | 1462 | ||
@@ -1303,9 +1464,9 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) | |||
1303 | dum->ss_hcd : dum->hs_hcd))) | 1464 | dum->ss_hcd : dum->hs_hcd))) |
1304 | return NULL; | 1465 | return NULL; |
1305 | if ((address & ~USB_DIR_IN) == 0) | 1466 | if ((address & ~USB_DIR_IN) == 0) |
1306 | return &dum->ep [0]; | 1467 | return &dum->ep[0]; |
1307 | for (i = 1; i < DUMMY_ENDPOINTS; i++) { | 1468 | for (i = 1; i < DUMMY_ENDPOINTS; i++) { |
1308 | struct dummy_ep *ep = &dum->ep [i]; | 1469 | struct dummy_ep *ep = &dum->ep[i]; |
1309 | 1470 | ||
1310 | if (!ep->desc) | 1471 | if (!ep->desc) |
1311 | continue; | 1472 | continue; |
@@ -1535,19 +1696,19 @@ static void dummy_timer(unsigned long _dum_hcd) | |||
1535 | /* FIXME if HZ != 1000 this will probably misbehave ... */ | 1696 | /* FIXME if HZ != 1000 this will probably misbehave ... */ |
1536 | 1697 | ||
1537 | /* look at each urb queued by the host side driver */ | 1698 | /* look at each urb queued by the host side driver */ |
1538 | spin_lock_irqsave (&dum->lock, flags); | 1699 | spin_lock_irqsave(&dum->lock, flags); |
1539 | 1700 | ||
1540 | if (!dum_hcd->udev) { | 1701 | if (!dum_hcd->udev) { |
1541 | dev_err(dummy_dev(dum_hcd), | 1702 | dev_err(dummy_dev(dum_hcd), |
1542 | "timer fired with no URBs pending?\n"); | 1703 | "timer fired with no URBs pending?\n"); |
1543 | spin_unlock_irqrestore (&dum->lock, flags); | 1704 | spin_unlock_irqrestore(&dum->lock, flags); |
1544 | return; | 1705 | return; |
1545 | } | 1706 | } |
1546 | 1707 | ||
1547 | for (i = 0; i < DUMMY_ENDPOINTS; i++) { | 1708 | for (i = 0; i < DUMMY_ENDPOINTS; i++) { |
1548 | if (!ep_name [i]) | 1709 | if (!ep_name[i]) |
1549 | break; | 1710 | break; |
1550 | dum->ep [i].already_seen = 0; | 1711 | dum->ep[i].already_seen = 0; |
1551 | } | 1712 | } |
1552 | 1713 | ||
1553 | restart: | 1714 | restart: |
@@ -1564,7 +1725,7 @@ restart: | |||
1564 | goto return_urb; | 1725 | goto return_urb; |
1565 | else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) | 1726 | else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) |
1566 | continue; | 1727 | continue; |
1567 | type = usb_pipetype (urb->pipe); | 1728 | type = usb_pipetype(urb->pipe); |
1568 | 1729 | ||
1569 | /* used up this frame's non-periodic bandwidth? | 1730 | /* used up this frame's non-periodic bandwidth? |
1570 | * FIXME there's infinite bandwidth for control and | 1731 | * FIXME there's infinite bandwidth for control and |
@@ -1575,7 +1736,7 @@ restart: | |||
1575 | 1736 | ||
1576 | /* find the gadget's ep for this request (if configured) */ | 1737 | /* find the gadget's ep for this request (if configured) */ |
1577 | address = usb_pipeendpoint (urb->pipe); | 1738 | address = usb_pipeendpoint (urb->pipe); |
1578 | if (usb_pipein (urb->pipe)) | 1739 | if (usb_pipein(urb->pipe)) |
1579 | address |= USB_DIR_IN; | 1740 | address |= USB_DIR_IN; |
1580 | ep = find_endpoint(dum, address); | 1741 | ep = find_endpoint(dum, address); |
1581 | if (!ep) { | 1742 | if (!ep) { |
@@ -1590,7 +1751,7 @@ restart: | |||
1590 | if (ep->already_seen) | 1751 | if (ep->already_seen) |
1591 | continue; | 1752 | continue; |
1592 | ep->already_seen = 1; | 1753 | ep->already_seen = 1; |
1593 | if (ep == &dum->ep [0] && urb->error_count) { | 1754 | if (ep == &dum->ep[0] && urb->error_count) { |
1594 | ep->setup_stage = 1; /* a new urb */ | 1755 | ep->setup_stage = 1; /* a new urb */ |
1595 | urb->error_count = 0; | 1756 | urb->error_count = 0; |
1596 | } | 1757 | } |
@@ -1604,21 +1765,21 @@ restart: | |||
1604 | /* FIXME make sure both ends agree on maxpacket */ | 1765 | /* FIXME make sure both ends agree on maxpacket */ |
1605 | 1766 | ||
1606 | /* handle control requests */ | 1767 | /* handle control requests */ |
1607 | if (ep == &dum->ep [0] && ep->setup_stage) { | 1768 | if (ep == &dum->ep[0] && ep->setup_stage) { |
1608 | struct usb_ctrlrequest setup; | 1769 | struct usb_ctrlrequest setup; |
1609 | int value = 1; | 1770 | int value = 1; |
1610 | 1771 | ||
1611 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; | 1772 | setup = *(struct usb_ctrlrequest *) urb->setup_packet; |
1612 | /* paranoia, in case of stale queued data */ | 1773 | /* paranoia, in case of stale queued data */ |
1613 | list_for_each_entry (req, &ep->queue, queue) { | 1774 | list_for_each_entry(req, &ep->queue, queue) { |
1614 | list_del_init (&req->queue); | 1775 | list_del_init(&req->queue); |
1615 | req->req.status = -EOVERFLOW; | 1776 | req->req.status = -EOVERFLOW; |
1616 | dev_dbg (udc_dev(dum), "stale req = %p\n", | 1777 | dev_dbg(udc_dev(dum), "stale req = %p\n", |
1617 | req); | 1778 | req); |
1618 | 1779 | ||
1619 | spin_unlock (&dum->lock); | 1780 | spin_unlock(&dum->lock); |
1620 | req->req.complete (&ep->ep, &req->req); | 1781 | req->req.complete(&ep->ep, &req->req); |
1621 | spin_lock (&dum->lock); | 1782 | spin_lock(&dum->lock); |
1622 | ep->already_seen = 0; | 1783 | ep->already_seen = 0; |
1623 | goto restart; | 1784 | goto restart; |
1624 | } | 1785 | } |
@@ -1638,10 +1799,10 @@ restart: | |||
1638 | * until setup() returns; no reentrancy issues etc. | 1799 | * until setup() returns; no reentrancy issues etc. |
1639 | */ | 1800 | */ |
1640 | if (value > 0) { | 1801 | if (value > 0) { |
1641 | spin_unlock (&dum->lock); | 1802 | spin_unlock(&dum->lock); |
1642 | value = dum->driver->setup (&dum->gadget, | 1803 | value = dum->driver->setup(&dum->gadget, |
1643 | &setup); | 1804 | &setup); |
1644 | spin_lock (&dum->lock); | 1805 | spin_lock(&dum->lock); |
1645 | 1806 | ||
1646 | if (value >= 0) { | 1807 | if (value >= 0) { |
1647 | /* no delays (max 64KB data stage) */ | 1808 | /* no delays (max 64KB data stage) */ |
@@ -1653,7 +1814,7 @@ restart: | |||
1653 | 1814 | ||
1654 | if (value < 0) { | 1815 | if (value < 0) { |
1655 | if (value != -EOPNOTSUPP) | 1816 | if (value != -EOPNOTSUPP) |
1656 | dev_dbg (udc_dev(dum), | 1817 | dev_dbg(udc_dev(dum), |
1657 | "setup --> %d\n", | 1818 | "setup --> %d\n", |
1658 | value); | 1819 | value); |
1659 | status = -EPIPE; | 1820 | status = -EPIPE; |
@@ -1665,14 +1826,14 @@ restart: | |||
1665 | 1826 | ||
1666 | /* non-control requests */ | 1827 | /* non-control requests */ |
1667 | limit = total; | 1828 | limit = total; |
1668 | switch (usb_pipetype (urb->pipe)) { | 1829 | switch (usb_pipetype(urb->pipe)) { |
1669 | case PIPE_ISOCHRONOUS: | 1830 | case PIPE_ISOCHRONOUS: |
1670 | /* FIXME is it urb->interval since the last xfer? | 1831 | /* FIXME is it urb->interval since the last xfer? |
1671 | * use urb->iso_frame_desc[i]. | 1832 | * use urb->iso_frame_desc[i]. |
1672 | * complete whether or not ep has requests queued. | 1833 | * complete whether or not ep has requests queued. |
1673 | * report random errors, to debug drivers. | 1834 | * report random errors, to debug drivers. |
1674 | */ | 1835 | */ |
1675 | limit = max (limit, periodic_bytes (dum, ep)); | 1836 | limit = max(limit, periodic_bytes(dum, ep)); |
1676 | status = -ENOSYS; | 1837 | status = -ENOSYS; |
1677 | break; | 1838 | break; |
1678 | 1839 | ||
@@ -1680,14 +1841,13 @@ restart: | |||
1680 | /* FIXME is it urb->interval since the last xfer? | 1841 | /* FIXME is it urb->interval since the last xfer? |
1681 | * this almost certainly polls too fast. | 1842 | * this almost certainly polls too fast. |
1682 | */ | 1843 | */ |
1683 | limit = max (limit, periodic_bytes (dum, ep)); | 1844 | limit = max(limit, periodic_bytes(dum, ep)); |
1684 | /* FALLTHROUGH */ | 1845 | /* FALLTHROUGH */ |
1685 | 1846 | ||
1686 | // case PIPE_BULK: case PIPE_CONTROL: | ||
1687 | default: | 1847 | default: |
1688 | treat_control_like_bulk: | 1848 | treat_control_like_bulk: |
1689 | ep->last_io = jiffies; | 1849 | ep->last_io = jiffies; |
1690 | total = transfer(dum, urb, ep, limit, &status); | 1850 | total = transfer(dum_hcd, urb, ep, limit, &status); |
1691 | break; | 1851 | break; |
1692 | } | 1852 | } |
1693 | 1853 | ||
@@ -1696,15 +1856,15 @@ restart: | |||
1696 | continue; | 1856 | continue; |
1697 | 1857 | ||
1698 | return_urb: | 1858 | return_urb: |
1699 | list_del (&urbp->urbp_list); | 1859 | list_del(&urbp->urbp_list); |
1700 | kfree (urbp); | 1860 | kfree(urbp); |
1701 | if (ep) | 1861 | if (ep) |
1702 | ep->already_seen = ep->setup_stage = 0; | 1862 | ep->already_seen = ep->setup_stage = 0; |
1703 | 1863 | ||
1704 | usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb); | 1864 | usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb); |
1705 | spin_unlock (&dum->lock); | 1865 | spin_unlock(&dum->lock); |
1706 | usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status); | 1866 | usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status); |
1707 | spin_lock (&dum->lock); | 1867 | spin_lock(&dum->lock); |
1708 | 1868 | ||
1709 | goto restart; | 1869 | goto restart; |
1710 | } | 1870 | } |
@@ -1717,7 +1877,7 @@ return_urb: | |||
1717 | mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1)); | 1877 | mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1)); |
1718 | } | 1878 | } |
1719 | 1879 | ||
1720 | spin_unlock_irqrestore (&dum->lock, flags); | 1880 | spin_unlock_irqrestore(&dum->lock, flags); |
1721 | } | 1881 | } |
1722 | 1882 | ||
1723 | /*-------------------------------------------------------------------------*/ | 1883 | /*-------------------------------------------------------------------------*/ |
@@ -1729,7 +1889,7 @@ return_urb: | |||
1729 | | USB_PORT_STAT_C_OVERCURRENT \ | 1889 | | USB_PORT_STAT_C_OVERCURRENT \ |
1730 | | USB_PORT_STAT_C_RESET) << 16) | 1890 | | USB_PORT_STAT_C_RESET) << 16) |
1731 | 1891 | ||
1732 | static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | 1892 | static int dummy_hub_status(struct usb_hcd *hcd, char *buf) |
1733 | { | 1893 | { |
1734 | struct dummy_hcd *dum_hcd; | 1894 | struct dummy_hcd *dum_hcd; |
1735 | unsigned long flags; | 1895 | unsigned long flags; |
@@ -1753,7 +1913,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | |||
1753 | dum_hcd->port_status); | 1913 | dum_hcd->port_status); |
1754 | retval = 1; | 1914 | retval = 1; |
1755 | if (dum_hcd->rh_state == DUMMY_RH_SUSPENDED) | 1915 | if (dum_hcd->rh_state == DUMMY_RH_SUSPENDED) |
1756 | usb_hcd_resume_root_hub (hcd); | 1916 | usb_hcd_resume_root_hub(hcd); |
1757 | } | 1917 | } |
1758 | done: | 1918 | done: |
1759 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | 1919 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
@@ -1772,10 +1932,9 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc) | |||
1772 | desc->u.ss.DeviceRemovable = 0xffff; | 1932 | desc->u.ss.DeviceRemovable = 0xffff; |
1773 | } | 1933 | } |
1774 | 1934 | ||
1775 | static inline void | 1935 | static inline void hub_descriptor(struct usb_hub_descriptor *desc) |
1776 | hub_descriptor (struct usb_hub_descriptor *desc) | ||
1777 | { | 1936 | { |
1778 | memset (desc, 0, sizeof *desc); | 1937 | memset(desc, 0, sizeof *desc); |
1779 | desc->bDescriptorType = 0x29; | 1938 | desc->bDescriptorType = 0x29; |
1780 | desc->bDescLength = 9; | 1939 | desc->bDescLength = 9; |
1781 | desc->wHubCharacteristics = cpu_to_le16(0x0001); | 1940 | desc->wHubCharacteristics = cpu_to_le16(0x0001); |
@@ -1784,7 +1943,7 @@ hub_descriptor (struct usb_hub_descriptor *desc) | |||
1784 | desc->u.hs.DeviceRemovable[1] = 0xff; | 1943 | desc->u.hs.DeviceRemovable[1] = 0xff; |
1785 | } | 1944 | } |
1786 | 1945 | ||
1787 | static int dummy_hub_control ( | 1946 | static int dummy_hub_control( |
1788 | struct usb_hcd *hcd, | 1947 | struct usb_hcd *hcd, |
1789 | u16 typeReq, | 1948 | u16 typeReq, |
1790 | u16 wValue, | 1949 | u16 wValue, |
@@ -1852,7 +2011,7 @@ static int dummy_hub_control ( | |||
1852 | hub_descriptor((struct usb_hub_descriptor *) buf); | 2011 | hub_descriptor((struct usb_hub_descriptor *) buf); |
1853 | break; | 2012 | break; |
1854 | case GetHubStatus: | 2013 | case GetHubStatus: |
1855 | *(__le32 *) buf = cpu_to_le32 (0); | 2014 | *(__le32 *) buf = cpu_to_le32(0); |
1856 | break; | 2015 | break; |
1857 | case GetPortStatus: | 2016 | case GetPortStatus: |
1858 | if (wIndex != 1) | 2017 | if (wIndex != 1) |
@@ -1894,8 +2053,8 @@ static int dummy_hub_control ( | |||
1894 | } | 2053 | } |
1895 | } | 2054 | } |
1896 | set_link_state(dum_hcd); | 2055 | set_link_state(dum_hcd); |
1897 | ((__le16 *) buf)[0] = cpu_to_le16 (dum_hcd->port_status); | 2056 | ((__le16 *) buf)[0] = cpu_to_le16(dum_hcd->port_status); |
1898 | ((__le16 *) buf)[1] = cpu_to_le16 (dum_hcd->port_status >> 16); | 2057 | ((__le16 *) buf)[1] = cpu_to_le16(dum_hcd->port_status >> 16); |
1899 | break; | 2058 | break; |
1900 | case SetHubFeature: | 2059 | case SetHubFeature: |
1901 | retval = -EPIPE; | 2060 | retval = -EPIPE; |
@@ -2029,15 +2188,15 @@ error: | |||
2029 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | 2188 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
2030 | 2189 | ||
2031 | if ((dum_hcd->port_status & PORT_C_MASK) != 0) | 2190 | if ((dum_hcd->port_status & PORT_C_MASK) != 0) |
2032 | usb_hcd_poll_rh_status (hcd); | 2191 | usb_hcd_poll_rh_status(hcd); |
2033 | return retval; | 2192 | return retval; |
2034 | } | 2193 | } |
2035 | 2194 | ||
2036 | static int dummy_bus_suspend (struct usb_hcd *hcd) | 2195 | static int dummy_bus_suspend(struct usb_hcd *hcd) |
2037 | { | 2196 | { |
2038 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); | 2197 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
2039 | 2198 | ||
2040 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); | 2199 | dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); |
2041 | 2200 | ||
2042 | spin_lock_irq(&dum_hcd->dum->lock); | 2201 | spin_lock_irq(&dum_hcd->dum->lock); |
2043 | dum_hcd->rh_state = DUMMY_RH_SUSPENDED; | 2202 | dum_hcd->rh_state = DUMMY_RH_SUSPENDED; |
@@ -2047,12 +2206,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
2047 | return 0; | 2206 | return 0; |
2048 | } | 2207 | } |
2049 | 2208 | ||
2050 | static int dummy_bus_resume (struct usb_hcd *hcd) | 2209 | static int dummy_bus_resume(struct usb_hcd *hcd) |
2051 | { | 2210 | { |
2052 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); | 2211 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
2053 | int rc = 0; | 2212 | int rc = 0; |
2054 | 2213 | ||
2055 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); | 2214 | dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); |
2056 | 2215 | ||
2057 | spin_lock_irq(&dum_hcd->dum->lock); | 2216 | spin_lock_irq(&dum_hcd->dum->lock); |
2058 | if (!HCD_HW_ACCESSIBLE(hcd)) { | 2217 | if (!HCD_HW_ACCESSIBLE(hcd)) { |
@@ -2070,55 +2229,54 @@ static int dummy_bus_resume (struct usb_hcd *hcd) | |||
2070 | 2229 | ||
2071 | /*-------------------------------------------------------------------------*/ | 2230 | /*-------------------------------------------------------------------------*/ |
2072 | 2231 | ||
2073 | static inline ssize_t | 2232 | static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb) |
2074 | show_urb (char *buf, size_t size, struct urb *urb) | ||
2075 | { | 2233 | { |
2076 | int ep = usb_pipeendpoint (urb->pipe); | 2234 | int ep = usb_pipeendpoint(urb->pipe); |
2077 | 2235 | ||
2078 | return snprintf (buf, size, | 2236 | return snprintf(buf, size, |
2079 | "urb/%p %s ep%d%s%s len %d/%d\n", | 2237 | "urb/%p %s ep%d%s%s len %d/%d\n", |
2080 | urb, | 2238 | urb, |
2081 | ({ char *s; | 2239 | ({ char *s; |
2082 | switch (urb->dev->speed) { | 2240 | switch (urb->dev->speed) { |
2083 | case USB_SPEED_LOW: | 2241 | case USB_SPEED_LOW: |
2084 | s = "ls"; | 2242 | s = "ls"; |
2085 | break; | 2243 | break; |
2086 | case USB_SPEED_FULL: | 2244 | case USB_SPEED_FULL: |
2087 | s = "fs"; | 2245 | s = "fs"; |
2088 | break; | 2246 | break; |
2089 | case USB_SPEED_HIGH: | 2247 | case USB_SPEED_HIGH: |
2090 | s = "hs"; | 2248 | s = "hs"; |
2091 | break; | 2249 | break; |
2092 | case USB_SPEED_SUPER: | 2250 | case USB_SPEED_SUPER: |
2093 | s = "ss"; | 2251 | s = "ss"; |
2094 | break; | 2252 | break; |
2095 | default: | 2253 | default: |
2096 | s = "?"; | 2254 | s = "?"; |
2097 | break; | 2255 | break; |
2098 | }; s; }), | 2256 | }; s; }), |
2099 | ep, ep ? (usb_pipein (urb->pipe) ? "in" : "out") : "", | 2257 | ep, ep ? (usb_pipein(urb->pipe) ? "in" : "out") : "", |
2100 | ({ char *s; \ | 2258 | ({ char *s; \ |
2101 | switch (usb_pipetype (urb->pipe)) { \ | 2259 | switch (usb_pipetype(urb->pipe)) { \ |
2102 | case PIPE_CONTROL: \ | 2260 | case PIPE_CONTROL: \ |
2103 | s = ""; \ | 2261 | s = ""; \ |
2104 | break; \ | 2262 | break; \ |
2105 | case PIPE_BULK: \ | 2263 | case PIPE_BULK: \ |
2106 | s = "-bulk"; \ | 2264 | s = "-bulk"; \ |
2107 | break; \ | 2265 | break; \ |
2108 | case PIPE_INTERRUPT: \ | 2266 | case PIPE_INTERRUPT: \ |
2109 | s = "-int"; \ | 2267 | s = "-int"; \ |
2110 | break; \ | 2268 | break; \ |
2111 | default: \ | 2269 | default: \ |
2112 | s = "-iso"; \ | 2270 | s = "-iso"; \ |
2113 | break; \ | 2271 | break; \ |
2114 | }; s;}), | 2272 | }; s; }), |
2115 | urb->actual_length, urb->transfer_buffer_length); | 2273 | urb->actual_length, urb->transfer_buffer_length); |
2116 | } | 2274 | } |
2117 | 2275 | ||
2118 | static ssize_t | 2276 | static ssize_t show_urbs(struct device *dev, struct device_attribute *attr, |
2119 | show_urbs (struct device *dev, struct device_attribute *attr, char *buf) | 2277 | char *buf) |
2120 | { | 2278 | { |
2121 | struct usb_hcd *hcd = dev_get_drvdata (dev); | 2279 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
2122 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); | 2280 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
2123 | struct urbp *urbp; | 2281 | struct urbp *urbp; |
2124 | size_t size = 0; | 2282 | size_t size = 0; |
@@ -2128,7 +2286,7 @@ show_urbs (struct device *dev, struct device_attribute *attr, char *buf) | |||
2128 | list_for_each_entry(urbp, &dum_hcd->urbp_list, urbp_list) { | 2286 | list_for_each_entry(urbp, &dum_hcd->urbp_list, urbp_list) { |
2129 | size_t temp; | 2287 | size_t temp; |
2130 | 2288 | ||
2131 | temp = show_urb (buf, PAGE_SIZE - size, urbp->urb); | 2289 | temp = show_urb(buf, PAGE_SIZE - size, urbp->urb); |
2132 | buf += temp; | 2290 | buf += temp; |
2133 | size += temp; | 2291 | size += temp; |
2134 | } | 2292 | } |
@@ -2136,7 +2294,7 @@ show_urbs (struct device *dev, struct device_attribute *attr, char *buf) | |||
2136 | 2294 | ||
2137 | return size; | 2295 | return size; |
2138 | } | 2296 | } |
2139 | static DEVICE_ATTR (urbs, S_IRUGO, show_urbs, NULL); | 2297 | static DEVICE_ATTR(urbs, S_IRUGO, show_urbs, NULL); |
2140 | 2298 | ||
2141 | static int dummy_start_ss(struct dummy_hcd *dum_hcd) | 2299 | static int dummy_start_ss(struct dummy_hcd *dum_hcd) |
2142 | { | 2300 | { |
@@ -2144,6 +2302,7 @@ static int dummy_start_ss(struct dummy_hcd *dum_hcd) | |||
2144 | dum_hcd->timer.function = dummy_timer; | 2302 | dum_hcd->timer.function = dummy_timer; |
2145 | dum_hcd->timer.data = (unsigned long)dum_hcd; | 2303 | dum_hcd->timer.data = (unsigned long)dum_hcd; |
2146 | dum_hcd->rh_state = DUMMY_RH_RUNNING; | 2304 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
2305 | dum_hcd->stream_en_ep = 0; | ||
2147 | INIT_LIST_HEAD(&dum_hcd->urbp_list); | 2306 | INIT_LIST_HEAD(&dum_hcd->urbp_list); |
2148 | dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET; | 2307 | dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET; |
2149 | dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING; | 2308 | dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING; |
@@ -2189,11 +2348,11 @@ static int dummy_start(struct usb_hcd *hcd) | |||
2189 | return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs); | 2348 | return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs); |
2190 | } | 2349 | } |
2191 | 2350 | ||
2192 | static void dummy_stop (struct usb_hcd *hcd) | 2351 | static void dummy_stop(struct usb_hcd *hcd) |
2193 | { | 2352 | { |
2194 | struct dummy *dum; | 2353 | struct dummy *dum; |
2195 | 2354 | ||
2196 | dum = (hcd_to_dummy_hcd(hcd))->dum; | 2355 | dum = hcd_to_dummy_hcd(hcd)->dum; |
2197 | device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); | 2356 | device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); |
2198 | usb_gadget_unregister_driver(dum->driver); | 2357 | usb_gadget_unregister_driver(dum->driver); |
2199 | dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); | 2358 | dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); |
@@ -2201,13 +2360,14 @@ static void dummy_stop (struct usb_hcd *hcd) | |||
2201 | 2360 | ||
2202 | /*-------------------------------------------------------------------------*/ | 2361 | /*-------------------------------------------------------------------------*/ |
2203 | 2362 | ||
2204 | static int dummy_h_get_frame (struct usb_hcd *hcd) | 2363 | static int dummy_h_get_frame(struct usb_hcd *hcd) |
2205 | { | 2364 | { |
2206 | return dummy_g_get_frame (NULL); | 2365 | return dummy_g_get_frame(NULL); |
2207 | } | 2366 | } |
2208 | 2367 | ||
2209 | static int dummy_setup(struct usb_hcd *hcd) | 2368 | static int dummy_setup(struct usb_hcd *hcd) |
2210 | { | 2369 | { |
2370 | hcd->self.sg_tablesize = ~0; | ||
2211 | if (usb_hcd_is_primary_hcd(hcd)) { | 2371 | if (usb_hcd_is_primary_hcd(hcd)) { |
2212 | the_controller.hs_hcd = hcd_to_dummy_hcd(hcd); | 2372 | the_controller.hs_hcd = hcd_to_dummy_hcd(hcd); |
2213 | the_controller.hs_hcd->dum = &the_controller; | 2373 | the_controller.hs_hcd->dum = &the_controller; |
@@ -2228,27 +2388,82 @@ static int dummy_setup(struct usb_hcd *hcd) | |||
2228 | } | 2388 | } |
2229 | 2389 | ||
2230 | /* Change a group of bulk endpoints to support multiple stream IDs */ | 2390 | /* Change a group of bulk endpoints to support multiple stream IDs */ |
2231 | int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, | 2391 | static int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, |
2232 | struct usb_host_endpoint **eps, unsigned int num_eps, | 2392 | struct usb_host_endpoint **eps, unsigned int num_eps, |
2233 | unsigned int num_streams, gfp_t mem_flags) | 2393 | unsigned int num_streams, gfp_t mem_flags) |
2234 | { | 2394 | { |
2235 | if (hcd->speed != HCD_USB3) | 2395 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
2236 | dev_dbg(dummy_dev(hcd_to_dummy_hcd(hcd)), | 2396 | unsigned long flags; |
2237 | "%s() - ERROR! Not supported for USB2.0 roothub\n", | 2397 | int max_stream; |
2238 | __func__); | 2398 | int ret_streams = num_streams; |
2239 | return 0; | 2399 | unsigned int index; |
2400 | unsigned int i; | ||
2401 | |||
2402 | if (!num_eps) | ||
2403 | return -EINVAL; | ||
2404 | |||
2405 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); | ||
2406 | for (i = 0; i < num_eps; i++) { | ||
2407 | index = dummy_get_ep_idx(&eps[i]->desc); | ||
2408 | if ((1 << index) & dum_hcd->stream_en_ep) { | ||
2409 | ret_streams = -EINVAL; | ||
2410 | goto out; | ||
2411 | } | ||
2412 | max_stream = usb_ss_max_streams(&eps[i]->ss_ep_comp); | ||
2413 | if (!max_stream) { | ||
2414 | ret_streams = -EINVAL; | ||
2415 | goto out; | ||
2416 | } | ||
2417 | if (max_stream < ret_streams) { | ||
2418 | dev_dbg(dummy_dev(dum_hcd), "Ep 0x%x only supports %u " | ||
2419 | "stream IDs.\n", | ||
2420 | eps[i]->desc.bEndpointAddress, | ||
2421 | max_stream); | ||
2422 | ret_streams = max_stream; | ||
2423 | } | ||
2424 | } | ||
2425 | |||
2426 | for (i = 0; i < num_eps; i++) { | ||
2427 | index = dummy_get_ep_idx(&eps[i]->desc); | ||
2428 | dum_hcd->stream_en_ep |= 1 << index; | ||
2429 | set_max_streams_for_pipe(dum_hcd, | ||
2430 | usb_endpoint_num(&eps[i]->desc), ret_streams); | ||
2431 | } | ||
2432 | out: | ||
2433 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | ||
2434 | return ret_streams; | ||
2240 | } | 2435 | } |
2241 | 2436 | ||
2242 | /* Reverts a group of bulk endpoints back to not using stream IDs. */ | 2437 | /* Reverts a group of bulk endpoints back to not using stream IDs. */ |
2243 | int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | 2438 | static int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, |
2244 | struct usb_host_endpoint **eps, unsigned int num_eps, | 2439 | struct usb_host_endpoint **eps, unsigned int num_eps, |
2245 | gfp_t mem_flags) | 2440 | gfp_t mem_flags) |
2246 | { | 2441 | { |
2247 | if (hcd->speed != HCD_USB3) | 2442 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
2248 | dev_dbg(dummy_dev(hcd_to_dummy_hcd(hcd)), | 2443 | unsigned long flags; |
2249 | "%s() - ERROR! Not supported for USB2.0 roothub\n", | 2444 | int ret; |
2250 | __func__); | 2445 | unsigned int index; |
2251 | return 0; | 2446 | unsigned int i; |
2447 | |||
2448 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); | ||
2449 | for (i = 0; i < num_eps; i++) { | ||
2450 | index = dummy_get_ep_idx(&eps[i]->desc); | ||
2451 | if (!((1 << index) & dum_hcd->stream_en_ep)) { | ||
2452 | ret = -EINVAL; | ||
2453 | goto out; | ||
2454 | } | ||
2455 | } | ||
2456 | |||
2457 | for (i = 0; i < num_eps; i++) { | ||
2458 | index = dummy_get_ep_idx(&eps[i]->desc); | ||
2459 | dum_hcd->stream_en_ep &= ~(1 << index); | ||
2460 | set_max_streams_for_pipe(dum_hcd, | ||
2461 | usb_endpoint_num(&eps[i]->desc), 0); | ||
2462 | } | ||
2463 | ret = 0; | ||
2464 | out: | ||
2465 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | ||
2466 | return ret; | ||
2252 | } | 2467 | } |
2253 | 2468 | ||
2254 | static struct hc_driver dummy_hcd = { | 2469 | static struct hc_driver dummy_hcd = { |
@@ -2262,13 +2477,13 @@ static struct hc_driver dummy_hcd = { | |||
2262 | .start = dummy_start, | 2477 | .start = dummy_start, |
2263 | .stop = dummy_stop, | 2478 | .stop = dummy_stop, |
2264 | 2479 | ||
2265 | .urb_enqueue = dummy_urb_enqueue, | 2480 | .urb_enqueue = dummy_urb_enqueue, |
2266 | .urb_dequeue = dummy_urb_dequeue, | 2481 | .urb_dequeue = dummy_urb_dequeue, |
2267 | 2482 | ||
2268 | .get_frame_number = dummy_h_get_frame, | 2483 | .get_frame_number = dummy_h_get_frame, |
2269 | 2484 | ||
2270 | .hub_status_data = dummy_hub_status, | 2485 | .hub_status_data = dummy_hub_status, |
2271 | .hub_control = dummy_hub_control, | 2486 | .hub_control = dummy_hub_control, |
2272 | .bus_suspend = dummy_bus_suspend, | 2487 | .bus_suspend = dummy_bus_suspend, |
2273 | .bus_resume = dummy_bus_resume, | 2488 | .bus_resume = dummy_bus_resume, |
2274 | 2489 | ||
@@ -2323,7 +2538,7 @@ static int dummy_hcd_remove(struct platform_device *pdev) | |||
2323 | { | 2538 | { |
2324 | struct dummy *dum; | 2539 | struct dummy *dum; |
2325 | 2540 | ||
2326 | dum = (hcd_to_dummy_hcd(platform_get_drvdata(pdev)))->dum; | 2541 | dum = hcd_to_dummy_hcd(platform_get_drvdata(pdev))->dum; |
2327 | 2542 | ||
2328 | if (dum->ss_hcd) { | 2543 | if (dum->ss_hcd) { |
2329 | usb_remove_hcd(dummy_hcd_to_hcd(dum->ss_hcd)); | 2544 | usb_remove_hcd(dummy_hcd_to_hcd(dum->ss_hcd)); |
@@ -2339,15 +2554,15 @@ static int dummy_hcd_remove(struct platform_device *pdev) | |||
2339 | return 0; | 2554 | return 0; |
2340 | } | 2555 | } |
2341 | 2556 | ||
2342 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) | 2557 | static int dummy_hcd_suspend(struct platform_device *pdev, pm_message_t state) |
2343 | { | 2558 | { |
2344 | struct usb_hcd *hcd; | 2559 | struct usb_hcd *hcd; |
2345 | struct dummy_hcd *dum_hcd; | 2560 | struct dummy_hcd *dum_hcd; |
2346 | int rc = 0; | 2561 | int rc = 0; |
2347 | 2562 | ||
2348 | dev_dbg (&pdev->dev, "%s\n", __func__); | 2563 | dev_dbg(&pdev->dev, "%s\n", __func__); |
2349 | 2564 | ||
2350 | hcd = platform_get_drvdata (pdev); | 2565 | hcd = platform_get_drvdata(pdev); |
2351 | dum_hcd = hcd_to_dummy_hcd(hcd); | 2566 | dum_hcd = hcd_to_dummy_hcd(hcd); |
2352 | if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { | 2567 | if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { |
2353 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); | 2568 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); |
@@ -2357,15 +2572,15 @@ static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) | |||
2357 | return rc; | 2572 | return rc; |
2358 | } | 2573 | } |
2359 | 2574 | ||
2360 | static int dummy_hcd_resume (struct platform_device *pdev) | 2575 | static int dummy_hcd_resume(struct platform_device *pdev) |
2361 | { | 2576 | { |
2362 | struct usb_hcd *hcd; | 2577 | struct usb_hcd *hcd; |
2363 | 2578 | ||
2364 | dev_dbg (&pdev->dev, "%s\n", __func__); | 2579 | dev_dbg(&pdev->dev, "%s\n", __func__); |
2365 | 2580 | ||
2366 | hcd = platform_get_drvdata (pdev); | 2581 | hcd = platform_get_drvdata(pdev); |
2367 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 2582 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
2368 | usb_hcd_poll_rh_status (hcd); | 2583 | usb_hcd_poll_rh_status(hcd); |
2369 | return 0; | 2584 | return 0; |
2370 | } | 2585 | } |
2371 | 2586 | ||
@@ -2385,11 +2600,11 @@ static struct platform_driver dummy_hcd_driver = { | |||
2385 | static struct platform_device *the_udc_pdev; | 2600 | static struct platform_device *the_udc_pdev; |
2386 | static struct platform_device *the_hcd_pdev; | 2601 | static struct platform_device *the_hcd_pdev; |
2387 | 2602 | ||
2388 | static int __init init (void) | 2603 | static int __init init(void) |
2389 | { | 2604 | { |
2390 | int retval = -ENOMEM; | 2605 | int retval = -ENOMEM; |
2391 | 2606 | ||
2392 | if (usb_disabled ()) | 2607 | if (usb_disabled()) |
2393 | return -ENODEV; | 2608 | return -ENODEV; |
2394 | 2609 | ||
2395 | if (!mod_data.is_high_speed && mod_data.is_super_speed) | 2610 | if (!mod_data.is_high_speed && mod_data.is_super_speed) |
@@ -2448,13 +2663,13 @@ err_alloc_udc: | |||
2448 | platform_device_put(the_hcd_pdev); | 2663 | platform_device_put(the_hcd_pdev); |
2449 | return retval; | 2664 | return retval; |
2450 | } | 2665 | } |
2451 | module_init (init); | 2666 | module_init(init); |
2452 | 2667 | ||
2453 | static void __exit cleanup (void) | 2668 | static void __exit cleanup(void) |
2454 | { | 2669 | { |
2455 | platform_device_unregister(the_udc_pdev); | 2670 | platform_device_unregister(the_udc_pdev); |
2456 | platform_device_unregister(the_hcd_pdev); | 2671 | platform_device_unregister(the_hcd_pdev); |
2457 | platform_driver_unregister(&dummy_udc_driver); | 2672 | platform_driver_unregister(&dummy_udc_driver); |
2458 | platform_driver_unregister(&dummy_hcd_driver); | 2673 | platform_driver_unregister(&dummy_hcd_driver); |
2459 | } | 2674 | } |
2460 | module_exit (cleanup); | 2675 | module_exit(cleanup); |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index e0e6375ef5dd..51f3d42f5a64 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -275,24 +275,24 @@ struct usb_ep *usb_ep_autoconfig_ss( | |||
275 | /* ep-e, ep-f are PIO with only 64 byte fifos */ | 275 | /* ep-e, ep-f are PIO with only 64 byte fifos */ |
276 | ep = find_ep (gadget, "ep-e"); | 276 | ep = find_ep (gadget, "ep-e"); |
277 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 277 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
278 | return ep; | 278 | goto found_ep; |
279 | ep = find_ep (gadget, "ep-f"); | 279 | ep = find_ep (gadget, "ep-f"); |
280 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 280 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
281 | return ep; | 281 | goto found_ep; |
282 | 282 | ||
283 | } else if (gadget_is_goku (gadget)) { | 283 | } else if (gadget_is_goku (gadget)) { |
284 | if (USB_ENDPOINT_XFER_INT == type) { | 284 | if (USB_ENDPOINT_XFER_INT == type) { |
285 | /* single buffering is enough */ | 285 | /* single buffering is enough */ |
286 | ep = find_ep(gadget, "ep3-bulk"); | 286 | ep = find_ep(gadget, "ep3-bulk"); |
287 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 287 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
288 | return ep; | 288 | goto found_ep; |
289 | } else if (USB_ENDPOINT_XFER_BULK == type | 289 | } else if (USB_ENDPOINT_XFER_BULK == type |
290 | && (USB_DIR_IN & desc->bEndpointAddress)) { | 290 | && (USB_DIR_IN & desc->bEndpointAddress)) { |
291 | /* DMA may be available */ | 291 | /* DMA may be available */ |
292 | ep = find_ep(gadget, "ep2-bulk"); | 292 | ep = find_ep(gadget, "ep2-bulk"); |
293 | if (ep && ep_matches(gadget, ep, desc, | 293 | if (ep && ep_matches(gadget, ep, desc, |
294 | ep_comp)) | 294 | ep_comp)) |
295 | return ep; | 295 | goto found_ep; |
296 | } | 296 | } |
297 | 297 | ||
298 | #ifdef CONFIG_BLACKFIN | 298 | #ifdef CONFIG_BLACKFIN |
@@ -311,18 +311,22 @@ struct usb_ep *usb_ep_autoconfig_ss( | |||
311 | } else | 311 | } else |
312 | ep = NULL; | 312 | ep = NULL; |
313 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 313 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
314 | return ep; | 314 | goto found_ep; |
315 | #endif | 315 | #endif |
316 | } | 316 | } |
317 | 317 | ||
318 | /* Second, look at endpoints until an unclaimed one looks usable */ | 318 | /* Second, look at endpoints until an unclaimed one looks usable */ |
319 | list_for_each_entry (ep, &gadget->ep_list, ep_list) { | 319 | list_for_each_entry (ep, &gadget->ep_list, ep_list) { |
320 | if (ep_matches(gadget, ep, desc, ep_comp)) | 320 | if (ep_matches(gadget, ep, desc, ep_comp)) |
321 | return ep; | 321 | goto found_ep; |
322 | } | 322 | } |
323 | 323 | ||
324 | /* Fail */ | 324 | /* Fail */ |
325 | return NULL; | 325 | return NULL; |
326 | found_ep: | ||
327 | ep->desc = NULL; | ||
328 | ep->comp_desc = NULL; | ||
329 | return ep; | ||
326 | } | 330 | } |
327 | 331 | ||
328 | /** | 332 | /** |
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 3f8849339ade..d672250a61fa 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Copyright (C) 2008 by David Brownell | 5 | * Copyright (C) 2008 by David Brownell |
6 | * Copyright (C) 2008 by Nokia Corporation | 6 | * Copyright (C) 2008 by Nokia Corporation |
7 | * Copyright (C) 2009 by Samsung Electronics | 7 | * Copyright (C) 2009 by Samsung Electronics |
8 | * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) | 8 | * Author: Michal Nazarewicz (mina86@mina86.com) |
9 | * | 9 | * |
10 | * This software is distributed under the terms of the GNU General | 10 | * This software is distributed under the terms of the GNU General |
11 | * Public License ("GPL") as published by the Free Software Foundation, | 11 | * Public License ("GPL") as published by the Free Software Foundation, |
@@ -237,6 +237,42 @@ static struct usb_descriptor_header *acm_hs_function[] = { | |||
237 | NULL, | 237 | NULL, |
238 | }; | 238 | }; |
239 | 239 | ||
240 | static struct usb_endpoint_descriptor acm_ss_in_desc = { | ||
241 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
242 | .bDescriptorType = USB_DT_ENDPOINT, | ||
243 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
244 | .wMaxPacketSize = cpu_to_le16(1024), | ||
245 | }; | ||
246 | |||
247 | static struct usb_endpoint_descriptor acm_ss_out_desc = { | ||
248 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
249 | .bDescriptorType = USB_DT_ENDPOINT, | ||
250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
251 | .wMaxPacketSize = cpu_to_le16(1024), | ||
252 | }; | ||
253 | |||
254 | static struct usb_ss_ep_comp_descriptor acm_ss_bulk_comp_desc = { | ||
255 | .bLength = sizeof acm_ss_bulk_comp_desc, | ||
256 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
257 | }; | ||
258 | |||
259 | static struct usb_descriptor_header *acm_ss_function[] = { | ||
260 | (struct usb_descriptor_header *) &acm_iad_descriptor, | ||
261 | (struct usb_descriptor_header *) &acm_control_interface_desc, | ||
262 | (struct usb_descriptor_header *) &acm_header_desc, | ||
263 | (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, | ||
264 | (struct usb_descriptor_header *) &acm_descriptor, | ||
265 | (struct usb_descriptor_header *) &acm_union_desc, | ||
266 | (struct usb_descriptor_header *) &acm_hs_notify_desc, | ||
267 | (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, | ||
268 | (struct usb_descriptor_header *) &acm_data_interface_desc, | ||
269 | (struct usb_descriptor_header *) &acm_ss_in_desc, | ||
270 | (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, | ||
271 | (struct usb_descriptor_header *) &acm_ss_out_desc, | ||
272 | (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, | ||
273 | NULL, | ||
274 | }; | ||
275 | |||
240 | /* string descriptors: */ | 276 | /* string descriptors: */ |
241 | 277 | ||
242 | #define ACM_CTRL_IDX 0 | 278 | #define ACM_CTRL_IDX 0 |
@@ -643,9 +679,21 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) | |||
643 | /* copy descriptors */ | 679 | /* copy descriptors */ |
644 | f->hs_descriptors = usb_copy_descriptors(acm_hs_function); | 680 | f->hs_descriptors = usb_copy_descriptors(acm_hs_function); |
645 | } | 681 | } |
682 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
683 | acm_ss_in_desc.bEndpointAddress = | ||
684 | acm_fs_in_desc.bEndpointAddress; | ||
685 | acm_ss_out_desc.bEndpointAddress = | ||
686 | acm_fs_out_desc.bEndpointAddress; | ||
687 | |||
688 | /* copy descriptors, and track endpoint copies */ | ||
689 | f->ss_descriptors = usb_copy_descriptors(acm_ss_function); | ||
690 | if (!f->ss_descriptors) | ||
691 | goto fail; | ||
692 | } | ||
646 | 693 | ||
647 | DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", | 694 | DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", |
648 | acm->port_num, | 695 | acm->port_num, |
696 | gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||
649 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 697 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
650 | acm->port.in->name, acm->port.out->name, | 698 | acm->port.in->name, acm->port.out->name, |
651 | acm->notify->name); | 699 | acm->notify->name); |
@@ -675,6 +723,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) | |||
675 | 723 | ||
676 | if (gadget_is_dualspeed(c->cdev->gadget)) | 724 | if (gadget_is_dualspeed(c->cdev->gadget)) |
677 | usb_free_descriptors(f->hs_descriptors); | 725 | usb_free_descriptors(f->hs_descriptors); |
726 | if (gadget_is_superspeed(c->cdev->gadget)) | ||
727 | usb_free_descriptors(f->ss_descriptors); | ||
678 | usb_free_descriptors(f->descriptors); | 728 | usb_free_descriptors(f->descriptors); |
679 | gs_free_req(acm->notify, acm->notify_req); | 729 | gs_free_req(acm->notify, acm->notify_req); |
680 | kfree(acm); | 730 | kfree(acm); |
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 11c07cb7d337..30b908f2a53d 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c | |||
@@ -97,6 +97,20 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g) | |||
97 | 97 | ||
98 | /* interface descriptor: */ | 98 | /* interface descriptor: */ |
99 | 99 | ||
100 | static struct usb_interface_assoc_descriptor | ||
101 | ecm_iad_descriptor = { | ||
102 | .bLength = sizeof ecm_iad_descriptor, | ||
103 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, | ||
104 | |||
105 | /* .bFirstInterface = DYNAMIC, */ | ||
106 | .bInterfaceCount = 2, /* control + data */ | ||
107 | .bFunctionClass = USB_CLASS_COMM, | ||
108 | .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, | ||
109 | .bFunctionProtocol = USB_CDC_PROTO_NONE, | ||
110 | /* .iFunction = DYNAMIC */ | ||
111 | }; | ||
112 | |||
113 | |||
100 | static struct usb_interface_descriptor ecm_control_intf = { | 114 | static struct usb_interface_descriptor ecm_control_intf = { |
101 | .bLength = sizeof ecm_control_intf, | 115 | .bLength = sizeof ecm_control_intf, |
102 | .bDescriptorType = USB_DT_INTERFACE, | 116 | .bDescriptorType = USB_DT_INTERFACE, |
@@ -199,6 +213,7 @@ static struct usb_endpoint_descriptor fs_ecm_out_desc = { | |||
199 | 213 | ||
200 | static struct usb_descriptor_header *ecm_fs_function[] = { | 214 | static struct usb_descriptor_header *ecm_fs_function[] = { |
201 | /* CDC ECM control descriptors */ | 215 | /* CDC ECM control descriptors */ |
216 | (struct usb_descriptor_header *) &ecm_iad_descriptor, | ||
202 | (struct usb_descriptor_header *) &ecm_control_intf, | 217 | (struct usb_descriptor_header *) &ecm_control_intf, |
203 | (struct usb_descriptor_header *) &ecm_header_desc, | 218 | (struct usb_descriptor_header *) &ecm_header_desc, |
204 | (struct usb_descriptor_header *) &ecm_union_desc, | 219 | (struct usb_descriptor_header *) &ecm_union_desc, |
@@ -247,6 +262,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc = { | |||
247 | 262 | ||
248 | static struct usb_descriptor_header *ecm_hs_function[] = { | 263 | static struct usb_descriptor_header *ecm_hs_function[] = { |
249 | /* CDC ECM control descriptors */ | 264 | /* CDC ECM control descriptors */ |
265 | (struct usb_descriptor_header *) &ecm_iad_descriptor, | ||
250 | (struct usb_descriptor_header *) &ecm_control_intf, | 266 | (struct usb_descriptor_header *) &ecm_control_intf, |
251 | (struct usb_descriptor_header *) &ecm_header_desc, | 267 | (struct usb_descriptor_header *) &ecm_header_desc, |
252 | (struct usb_descriptor_header *) &ecm_union_desc, | 268 | (struct usb_descriptor_header *) &ecm_union_desc, |
@@ -339,6 +355,7 @@ static struct usb_string ecm_string_defs[] = { | |||
339 | [0].s = "CDC Ethernet Control Model (ECM)", | 355 | [0].s = "CDC Ethernet Control Model (ECM)", |
340 | [1].s = NULL /* DYNAMIC */, | 356 | [1].s = NULL /* DYNAMIC */, |
341 | [2].s = "CDC Ethernet Data", | 357 | [2].s = "CDC Ethernet Data", |
358 | [3].s = "CDC ECM", | ||
342 | { } /* end of list */ | 359 | { } /* end of list */ |
343 | }; | 360 | }; |
344 | 361 | ||
@@ -674,6 +691,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) | |||
674 | if (status < 0) | 691 | if (status < 0) |
675 | goto fail; | 692 | goto fail; |
676 | ecm->ctrl_id = status; | 693 | ecm->ctrl_id = status; |
694 | ecm_iad_descriptor.bFirstInterface = status; | ||
677 | 695 | ||
678 | ecm_control_intf.bInterfaceNumber = status; | 696 | ecm_control_intf.bInterfaceNumber = status; |
679 | ecm_union_desc.bMasterInterface0 = status; | 697 | ecm_union_desc.bMasterInterface0 = status; |
@@ -864,6 +882,13 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) | |||
864 | return status; | 882 | return status; |
865 | ecm_string_defs[1].id = status; | 883 | ecm_string_defs[1].id = status; |
866 | ecm_desc.iMACAddress = status; | 884 | ecm_desc.iMACAddress = status; |
885 | |||
886 | /* IAD label */ | ||
887 | status = usb_string_id(c->cdev); | ||
888 | if (status < 0) | ||
889 | return status; | ||
890 | ecm_string_defs[3].id = status; | ||
891 | ecm_iad_descriptor.iFunction = status; | ||
867 | } | 892 | } |
868 | 893 | ||
869 | /* allocate and initialize one new instance */ | 894 | /* allocate and initialize one new instance */ |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index f63dc6c150d2..7e2216f1bbe6 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * f_fs.c -- user mode file system API for USB composite function controllers | 2 | * f_fs.c -- user mode file system API for USB composite function controllers |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics | 4 | * Copyright (C) 2010 Samsung Electronics |
5 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 5 | * Author: Michal Nazarewicz <mina86@mina86.com> |
6 | * | 6 | * |
7 | * Based on inode.c (GadgetFS) which was: | 7 | * Based on inode.c (GadgetFS) which was: |
8 | * Copyright (C) 2003-2004 David Brownell | 8 | * Copyright (C) 2003-2004 David Brownell |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 84e6573ea74e..a371e966425f 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2003-2008 Alan Stern | 4 | * Copyright (C) 2003-2008 Alan Stern |
5 | * Copyright (C) 2009 Samsung Electronics | 5 | * Copyright (C) 2009 Samsung Electronics |
6 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 6 | * Author: Michal Nazarewicz <mina86@mina86.com> |
7 | * All rights reserved. | 7 | * All rights reserved. |
8 | * | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
@@ -304,7 +304,6 @@ | |||
304 | 304 | ||
305 | static const char fsg_string_interface[] = "Mass Storage"; | 305 | static const char fsg_string_interface[] = "Mass Storage"; |
306 | 306 | ||
307 | #define FSG_NO_INTR_EP 1 | ||
308 | #define FSG_NO_DEVICE_STRINGS 1 | 307 | #define FSG_NO_DEVICE_STRINGS 1 |
309 | #define FSG_NO_OTG 1 | 308 | #define FSG_NO_OTG 1 |
310 | #define FSG_NO_INTR_EP 1 | 309 | #define FSG_NO_INTR_EP 1 |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 704d1d94f72a..7b1cf18df5e3 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger | 5 | * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger |
6 | * Copyright (C) 2008 Nokia Corporation | 6 | * Copyright (C) 2008 Nokia Corporation |
7 | * Copyright (C) 2009 Samsung Electronics | 7 | * Copyright (C) 2009 Samsung Electronics |
8 | * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) | 8 | * Author: Michal Nazarewicz (mina86@mina86.com) |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index cf33a8d0fd5d..07197d63d9b1 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c | |||
@@ -99,6 +99,34 @@ static struct usb_descriptor_header *gser_hs_function[] __initdata = { | |||
99 | NULL, | 99 | NULL, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static struct usb_endpoint_descriptor gser_ss_in_desc __initdata = { | ||
103 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
104 | .bDescriptorType = USB_DT_ENDPOINT, | ||
105 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
106 | .wMaxPacketSize = cpu_to_le16(1024), | ||
107 | }; | ||
108 | |||
109 | static struct usb_endpoint_descriptor gser_ss_out_desc __initdata = { | ||
110 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
111 | .bDescriptorType = USB_DT_ENDPOINT, | ||
112 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
113 | .wMaxPacketSize = cpu_to_le16(1024), | ||
114 | }; | ||
115 | |||
116 | static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc __initdata = { | ||
117 | .bLength = sizeof gser_ss_bulk_comp_desc, | ||
118 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
119 | }; | ||
120 | |||
121 | static struct usb_descriptor_header *gser_ss_function[] __initdata = { | ||
122 | (struct usb_descriptor_header *) &gser_interface_desc, | ||
123 | (struct usb_descriptor_header *) &gser_ss_in_desc, | ||
124 | (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc, | ||
125 | (struct usb_descriptor_header *) &gser_ss_out_desc, | ||
126 | (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc, | ||
127 | NULL, | ||
128 | }; | ||
129 | |||
102 | /* string descriptors: */ | 130 | /* string descriptors: */ |
103 | 131 | ||
104 | static struct usb_string gser_string_defs[] = { | 132 | static struct usb_string gser_string_defs[] = { |
@@ -201,9 +229,21 @@ gser_bind(struct usb_configuration *c, struct usb_function *f) | |||
201 | /* copy descriptors, and track endpoint copies */ | 229 | /* copy descriptors, and track endpoint copies */ |
202 | f->hs_descriptors = usb_copy_descriptors(gser_hs_function); | 230 | f->hs_descriptors = usb_copy_descriptors(gser_hs_function); |
203 | } | 231 | } |
232 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
233 | gser_ss_in_desc.bEndpointAddress = | ||
234 | gser_fs_in_desc.bEndpointAddress; | ||
235 | gser_ss_out_desc.bEndpointAddress = | ||
236 | gser_fs_out_desc.bEndpointAddress; | ||
237 | |||
238 | /* copy descriptors, and track endpoint copies */ | ||
239 | f->ss_descriptors = usb_copy_descriptors(gser_ss_function); | ||
240 | if (!f->ss_descriptors) | ||
241 | goto fail; | ||
242 | } | ||
204 | 243 | ||
205 | DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", | 244 | DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", |
206 | gser->port_num, | 245 | gser->port_num, |
246 | gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||
207 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 247 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
208 | gser->port.in->name, gser->port.out->name); | 248 | gser->port.in->name, gser->port.out->name); |
209 | return 0; | 249 | return 0; |
@@ -225,6 +265,8 @@ gser_unbind(struct usb_configuration *c, struct usb_function *f) | |||
225 | { | 265 | { |
226 | if (gadget_is_dualspeed(c->cdev->gadget)) | 266 | if (gadget_is_dualspeed(c->cdev->gadget)) |
227 | usb_free_descriptors(f->hs_descriptors); | 267 | usb_free_descriptors(f->hs_descriptors); |
268 | if (gadget_is_superspeed(c->cdev->gadget)) | ||
269 | usb_free_descriptors(f->ss_descriptors); | ||
228 | usb_free_descriptors(f->descriptors); | 270 | usb_free_descriptors(f->descriptors); |
229 | kfree(func_to_gser(f)); | 271 | kfree(func_to_gser(f)); |
230 | } | 272 | } |
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_uac1.c index ec7ffcd0d0cd..1a5dcd5565e3 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_uac1.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/atomic.h> | 15 | #include <linux/atomic.h> |
16 | 16 | ||
17 | #include "u_audio.h" | 17 | #include "u_uac1.h" |
18 | 18 | ||
19 | #define OUT_EP_MAX_PACKET_SIZE 200 | 19 | #define OUT_EP_MAX_PACKET_SIZE 200 |
20 | static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; | 20 | static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; |
@@ -216,29 +216,6 @@ static struct usb_descriptor_header *f_audio_desc[] __initdata = { | |||
216 | NULL, | 216 | NULL, |
217 | }; | 217 | }; |
218 | 218 | ||
219 | /* string IDs are assigned dynamically */ | ||
220 | |||
221 | #define STRING_MANUFACTURER_IDX 0 | ||
222 | #define STRING_PRODUCT_IDX 1 | ||
223 | |||
224 | static char manufacturer[50]; | ||
225 | |||
226 | static struct usb_string strings_dev[] = { | ||
227 | [STRING_MANUFACTURER_IDX].s = manufacturer, | ||
228 | [STRING_PRODUCT_IDX].s = DRIVER_DESC, | ||
229 | { } /* end of list */ | ||
230 | }; | ||
231 | |||
232 | static struct usb_gadget_strings stringtab_dev = { | ||
233 | .language = 0x0409, /* en-us */ | ||
234 | .strings = strings_dev, | ||
235 | }; | ||
236 | |||
237 | static struct usb_gadget_strings *audio_strings[] = { | ||
238 | &stringtab_dev, | ||
239 | NULL, | ||
240 | }; | ||
241 | |||
242 | /* | 219 | /* |
243 | * This function is an ALSA sound card following USB Audio Class Spec 1.0. | 220 | * This function is an ALSA sound card following USB Audio Class Spec 1.0. |
244 | */ | 221 | */ |
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c new file mode 100644 index 000000000000..e7cc4de93e33 --- /dev/null +++ b/drivers/usb/gadget/f_uac2.c | |||
@@ -0,0 +1,1449 @@ | |||
1 | /* | ||
2 | * f_uac2.c -- USB Audio Class 2.0 Function | ||
3 | * | ||
4 | * Copyright (C) 2011 | ||
5 | * Yadwinder Singh (yadi.brar01@gmail.com) | ||
6 | * Jaswinder Singh (jaswinder.singh@linaro.org) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/usb/audio.h> | ||
15 | #include <linux/usb/audio-v2.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/module.h> | ||
18 | |||
19 | #include <sound/core.h> | ||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/pcm_params.h> | ||
22 | |||
23 | /* Playback(USB-IN) Default Stereo - Fl/Fr */ | ||
24 | static int p_chmask = 0x3; | ||
25 | module_param(p_chmask, uint, S_IRUGO); | ||
26 | MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); | ||
27 | |||
28 | /* Playback Default 48 KHz */ | ||
29 | static int p_srate = 48000; | ||
30 | module_param(p_srate, uint, S_IRUGO); | ||
31 | MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); | ||
32 | |||
33 | /* Playback Default 16bits/sample */ | ||
34 | static int p_ssize = 2; | ||
35 | module_param(p_ssize, uint, S_IRUGO); | ||
36 | MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)"); | ||
37 | |||
38 | /* Capture(USB-OUT) Default Stereo - Fl/Fr */ | ||
39 | static int c_chmask = 0x3; | ||
40 | module_param(c_chmask, uint, S_IRUGO); | ||
41 | MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); | ||
42 | |||
43 | /* Capture Default 64 KHz */ | ||
44 | static int c_srate = 64000; | ||
45 | module_param(c_srate, uint, S_IRUGO); | ||
46 | MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); | ||
47 | |||
48 | /* Capture Default 16bits/sample */ | ||
49 | static int c_ssize = 2; | ||
50 | module_param(c_ssize, uint, S_IRUGO); | ||
51 | MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); | ||
52 | |||
53 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
54 | |||
55 | #define ALT_SET(x, a) do {(x) &= ~0xff; (x) |= (a); } while (0) | ||
56 | #define ALT_GET(x) ((x) & 0xff) | ||
57 | #define INTF_SET(x, i) do {(x) &= 0xff; (x) |= ((i) << 8); } while (0) | ||
58 | #define INTF_GET(x) ((x >> 8) & 0xff) | ||
59 | |||
60 | /* Keep everyone on toes */ | ||
61 | #define USB_XFERS 2 | ||
62 | |||
63 | /* | ||
64 | * The driver implements a simple UAC_2 topology. | ||
65 | * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture | ||
66 | * ALSA_Playback -> IT_2 -> OT_4 -> USB-IN | ||
67 | * Capture and Playback sampling rates are independently | ||
68 | * controlled by two clock sources : | ||
69 | * CLK_5 := c_srate, and CLK_6 := p_srate | ||
70 | */ | ||
71 | #define USB_OUT_IT_ID 1 | ||
72 | #define IO_IN_IT_ID 2 | ||
73 | #define IO_OUT_OT_ID 3 | ||
74 | #define USB_IN_OT_ID 4 | ||
75 | #define USB_OUT_CLK_ID 5 | ||
76 | #define USB_IN_CLK_ID 6 | ||
77 | |||
78 | #define CONTROL_ABSENT 0 | ||
79 | #define CONTROL_RDONLY 1 | ||
80 | #define CONTROL_RDWR 3 | ||
81 | |||
82 | #define CLK_FREQ_CTRL 0 | ||
83 | #define CLK_VLD_CTRL 2 | ||
84 | |||
85 | #define COPY_CTRL 0 | ||
86 | #define CONN_CTRL 2 | ||
87 | #define OVRLD_CTRL 4 | ||
88 | #define CLSTR_CTRL 6 | ||
89 | #define UNFLW_CTRL 8 | ||
90 | #define OVFLW_CTRL 10 | ||
91 | |||
92 | const char *uac2_name = "snd_uac2"; | ||
93 | |||
94 | struct uac2_req { | ||
95 | struct uac2_rtd_params *pp; /* parent param */ | ||
96 | struct usb_request *req; | ||
97 | }; | ||
98 | |||
99 | struct uac2_rtd_params { | ||
100 | bool ep_enabled; /* if the ep is enabled */ | ||
101 | /* Size of the ring buffer */ | ||
102 | size_t dma_bytes; | ||
103 | unsigned char *dma_area; | ||
104 | |||
105 | struct snd_pcm_substream *ss; | ||
106 | |||
107 | /* Ring buffer */ | ||
108 | ssize_t hw_ptr; | ||
109 | |||
110 | void *rbuf; | ||
111 | |||
112 | size_t period_size; | ||
113 | |||
114 | unsigned max_psize; | ||
115 | struct uac2_req ureq[USB_XFERS]; | ||
116 | |||
117 | spinlock_t lock; | ||
118 | }; | ||
119 | |||
120 | struct snd_uac2_chip { | ||
121 | struct platform_device pdev; | ||
122 | struct platform_driver pdrv; | ||
123 | |||
124 | struct uac2_rtd_params p_prm; | ||
125 | struct uac2_rtd_params c_prm; | ||
126 | |||
127 | struct snd_card *card; | ||
128 | struct snd_pcm *pcm; | ||
129 | }; | ||
130 | |||
131 | #define BUFF_SIZE_MAX (PAGE_SIZE * 16) | ||
132 | #define PRD_SIZE_MAX PAGE_SIZE | ||
133 | #define MIN_PERIODS 4 | ||
134 | |||
135 | static struct snd_pcm_hardware uac2_pcm_hardware = { | ||
136 | .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | ||
137 | | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | ||
138 | | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, | ||
139 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | ||
140 | .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, | ||
141 | .buffer_bytes_max = BUFF_SIZE_MAX, | ||
142 | .period_bytes_max = PRD_SIZE_MAX, | ||
143 | .periods_min = MIN_PERIODS, | ||
144 | }; | ||
145 | |||
146 | struct audio_dev { | ||
147 | /* Currently active {Interface[15:8] | AltSettings[7:0]} */ | ||
148 | __u16 ac_alt, as_out_alt, as_in_alt; | ||
149 | |||
150 | struct usb_ep *in_ep, *out_ep; | ||
151 | struct usb_function func; | ||
152 | |||
153 | /* The ALSA Sound Card it represents on the USB-Client side */ | ||
154 | struct snd_uac2_chip uac2; | ||
155 | }; | ||
156 | |||
157 | static struct audio_dev *agdev_g; | ||
158 | |||
159 | static inline | ||
160 | struct audio_dev *func_to_agdev(struct usb_function *f) | ||
161 | { | ||
162 | return container_of(f, struct audio_dev, func); | ||
163 | } | ||
164 | |||
165 | static inline | ||
166 | struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u) | ||
167 | { | ||
168 | return container_of(u, struct audio_dev, uac2); | ||
169 | } | ||
170 | |||
171 | static inline | ||
172 | struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p) | ||
173 | { | ||
174 | return container_of(p, struct snd_uac2_chip, pdev); | ||
175 | } | ||
176 | |||
177 | static inline | ||
178 | struct snd_uac2_chip *prm_to_uac2(struct uac2_rtd_params *r) | ||
179 | { | ||
180 | struct snd_uac2_chip *uac2 = container_of(r, | ||
181 | struct snd_uac2_chip, c_prm); | ||
182 | |||
183 | if (&uac2->c_prm != r) | ||
184 | uac2 = container_of(r, struct snd_uac2_chip, p_prm); | ||
185 | |||
186 | return uac2; | ||
187 | } | ||
188 | |||
189 | static inline | ||
190 | uint num_channels(uint chanmask) | ||
191 | { | ||
192 | uint num = 0; | ||
193 | |||
194 | while (chanmask) { | ||
195 | num += (chanmask & 1); | ||
196 | chanmask >>= 1; | ||
197 | } | ||
198 | |||
199 | return num; | ||
200 | } | ||
201 | |||
202 | static void | ||
203 | agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) | ||
204 | { | ||
205 | unsigned pending; | ||
206 | unsigned long flags; | ||
207 | bool update_alsa = false; | ||
208 | unsigned char *src, *dst; | ||
209 | int status = req->status; | ||
210 | struct uac2_req *ur = req->context; | ||
211 | struct snd_pcm_substream *substream; | ||
212 | struct uac2_rtd_params *prm = ur->pp; | ||
213 | struct snd_uac2_chip *uac2 = prm_to_uac2(prm); | ||
214 | |||
215 | /* i/f shutting down */ | ||
216 | if (!prm->ep_enabled) | ||
217 | return; | ||
218 | |||
219 | /* | ||
220 | * We can't really do much about bad xfers. | ||
221 | * Afterall, the ISOCH xfers could fail legitimately. | ||
222 | */ | ||
223 | if (status) | ||
224 | pr_debug("%s: iso_complete status(%d) %d/%d\n", | ||
225 | __func__, status, req->actual, req->length); | ||
226 | |||
227 | substream = prm->ss; | ||
228 | |||
229 | /* Do nothing if ALSA isn't active */ | ||
230 | if (!substream) | ||
231 | goto exit; | ||
232 | |||
233 | spin_lock_irqsave(&prm->lock, flags); | ||
234 | |||
235 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
236 | src = prm->dma_area + prm->hw_ptr; | ||
237 | req->actual = req->length; | ||
238 | dst = req->buf; | ||
239 | } else { | ||
240 | dst = prm->dma_area + prm->hw_ptr; | ||
241 | src = req->buf; | ||
242 | } | ||
243 | |||
244 | pending = prm->hw_ptr % prm->period_size; | ||
245 | pending += req->actual; | ||
246 | if (pending >= prm->period_size) | ||
247 | update_alsa = true; | ||
248 | |||
249 | prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes; | ||
250 | |||
251 | spin_unlock_irqrestore(&prm->lock, flags); | ||
252 | |||
253 | /* Pack USB load in ALSA ring buffer */ | ||
254 | memcpy(dst, src, req->actual); | ||
255 | exit: | ||
256 | if (usb_ep_queue(ep, req, GFP_ATOMIC)) | ||
257 | dev_err(&uac2->pdev.dev, "%d Error!\n", __LINE__); | ||
258 | |||
259 | if (update_alsa) | ||
260 | snd_pcm_period_elapsed(substream); | ||
261 | |||
262 | return; | ||
263 | } | ||
264 | |||
265 | static int | ||
266 | uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
267 | { | ||
268 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); | ||
269 | struct audio_dev *agdev = uac2_to_agdev(uac2); | ||
270 | struct uac2_rtd_params *prm; | ||
271 | unsigned long flags; | ||
272 | struct usb_ep *ep; | ||
273 | int err = 0; | ||
274 | |||
275 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
276 | ep = agdev->in_ep; | ||
277 | prm = &uac2->p_prm; | ||
278 | } else { | ||
279 | ep = agdev->out_ep; | ||
280 | prm = &uac2->c_prm; | ||
281 | } | ||
282 | |||
283 | spin_lock_irqsave(&prm->lock, flags); | ||
284 | |||
285 | /* Reset */ | ||
286 | prm->hw_ptr = 0; | ||
287 | |||
288 | switch (cmd) { | ||
289 | case SNDRV_PCM_TRIGGER_START: | ||
290 | case SNDRV_PCM_TRIGGER_RESUME: | ||
291 | prm->ss = substream; | ||
292 | break; | ||
293 | case SNDRV_PCM_TRIGGER_STOP: | ||
294 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
295 | prm->ss = NULL; | ||
296 | break; | ||
297 | default: | ||
298 | err = -EINVAL; | ||
299 | } | ||
300 | |||
301 | spin_unlock_irqrestore(&prm->lock, flags); | ||
302 | |||
303 | /* Clear buffer after Play stops */ | ||
304 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss) | ||
305 | memset(prm->rbuf, 0, prm->max_psize * USB_XFERS); | ||
306 | |||
307 | return err; | ||
308 | } | ||
309 | |||
310 | static snd_pcm_uframes_t uac2_pcm_pointer(struct snd_pcm_substream *substream) | ||
311 | { | ||
312 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); | ||
313 | struct uac2_rtd_params *prm; | ||
314 | |||
315 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
316 | prm = &uac2->p_prm; | ||
317 | else | ||
318 | prm = &uac2->c_prm; | ||
319 | |||
320 | return bytes_to_frames(substream->runtime, prm->hw_ptr); | ||
321 | } | ||
322 | |||
323 | static int uac2_pcm_hw_params(struct snd_pcm_substream *substream, | ||
324 | struct snd_pcm_hw_params *hw_params) | ||
325 | { | ||
326 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); | ||
327 | struct uac2_rtd_params *prm; | ||
328 | int err; | ||
329 | |||
330 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
331 | prm = &uac2->p_prm; | ||
332 | else | ||
333 | prm = &uac2->c_prm; | ||
334 | |||
335 | err = snd_pcm_lib_malloc_pages(substream, | ||
336 | params_buffer_bytes(hw_params)); | ||
337 | if (err >= 0) { | ||
338 | prm->dma_bytes = substream->runtime->dma_bytes; | ||
339 | prm->dma_area = substream->runtime->dma_area; | ||
340 | prm->period_size = params_period_bytes(hw_params); | ||
341 | } | ||
342 | |||
343 | return err; | ||
344 | } | ||
345 | |||
346 | static int uac2_pcm_hw_free(struct snd_pcm_substream *substream) | ||
347 | { | ||
348 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); | ||
349 | struct uac2_rtd_params *prm; | ||
350 | |||
351 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
352 | prm = &uac2->p_prm; | ||
353 | else | ||
354 | prm = &uac2->c_prm; | ||
355 | |||
356 | prm->dma_area = NULL; | ||
357 | prm->dma_bytes = 0; | ||
358 | prm->period_size = 0; | ||
359 | |||
360 | return snd_pcm_lib_free_pages(substream); | ||
361 | } | ||
362 | |||
363 | static int uac2_pcm_open(struct snd_pcm_substream *substream) | ||
364 | { | ||
365 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); | ||
366 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
367 | |||
368 | runtime->hw = uac2_pcm_hardware; | ||
369 | |||
370 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
371 | spin_lock_init(&uac2->p_prm.lock); | ||
372 | runtime->hw.rate_min = p_srate; | ||
373 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; /* ! p_ssize ! */ | ||
374 | runtime->hw.channels_min = num_channels(p_chmask); | ||
375 | runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize | ||
376 | / runtime->hw.periods_min; | ||
377 | } else { | ||
378 | spin_lock_init(&uac2->c_prm.lock); | ||
379 | runtime->hw.rate_min = c_srate; | ||
380 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; /* ! c_ssize ! */ | ||
381 | runtime->hw.channels_min = num_channels(c_chmask); | ||
382 | runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize | ||
383 | / runtime->hw.periods_min; | ||
384 | } | ||
385 | |||
386 | runtime->hw.rate_max = runtime->hw.rate_min; | ||
387 | runtime->hw.channels_max = runtime->hw.channels_min; | ||
388 | |||
389 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | /* ALSA cries without these function pointers */ | ||
395 | static int uac2_pcm_null(struct snd_pcm_substream *substream) | ||
396 | { | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static struct snd_pcm_ops uac2_pcm_ops = { | ||
401 | .open = uac2_pcm_open, | ||
402 | .close = uac2_pcm_null, | ||
403 | .ioctl = snd_pcm_lib_ioctl, | ||
404 | .hw_params = uac2_pcm_hw_params, | ||
405 | .hw_free = uac2_pcm_hw_free, | ||
406 | .trigger = uac2_pcm_trigger, | ||
407 | .pointer = uac2_pcm_pointer, | ||
408 | .prepare = uac2_pcm_null, | ||
409 | }; | ||
410 | |||
411 | static int __devinit snd_uac2_probe(struct platform_device *pdev) | ||
412 | { | ||
413 | struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); | ||
414 | struct snd_card *card; | ||
415 | struct snd_pcm *pcm; | ||
416 | int err; | ||
417 | |||
418 | /* Choose any slot, with no id */ | ||
419 | err = snd_card_create(-1, NULL, THIS_MODULE, 0, &card); | ||
420 | if (err < 0) | ||
421 | return err; | ||
422 | |||
423 | uac2->card = card; | ||
424 | |||
425 | /* | ||
426 | * Create first PCM device | ||
427 | * Create a substream only for non-zero channel streams | ||
428 | */ | ||
429 | err = snd_pcm_new(uac2->card, "UAC2 PCM", 0, | ||
430 | p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm); | ||
431 | if (err < 0) | ||
432 | goto snd_fail; | ||
433 | |||
434 | strcpy(pcm->name, "UAC2 PCM"); | ||
435 | pcm->private_data = uac2; | ||
436 | |||
437 | uac2->pcm = pcm; | ||
438 | |||
439 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac2_pcm_ops); | ||
440 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac2_pcm_ops); | ||
441 | |||
442 | strcpy(card->driver, "UAC2_Gadget"); | ||
443 | strcpy(card->shortname, "UAC2_Gadget"); | ||
444 | sprintf(card->longname, "UAC2_Gadget %i", pdev->id); | ||
445 | |||
446 | snd_card_set_dev(card, &pdev->dev); | ||
447 | |||
448 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, | ||
449 | snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); | ||
450 | |||
451 | err = snd_card_register(card); | ||
452 | if (!err) { | ||
453 | platform_set_drvdata(pdev, card); | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | snd_fail: | ||
458 | snd_card_free(card); | ||
459 | |||
460 | uac2->pcm = NULL; | ||
461 | uac2->card = NULL; | ||
462 | |||
463 | return err; | ||
464 | } | ||
465 | |||
466 | static int __devexit snd_uac2_remove(struct platform_device *pdev) | ||
467 | { | ||
468 | struct snd_card *card = platform_get_drvdata(pdev); | ||
469 | |||
470 | platform_set_drvdata(pdev, NULL); | ||
471 | |||
472 | if (card) | ||
473 | return snd_card_free(card); | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static int alsa_uac2_init(struct audio_dev *agdev) | ||
479 | { | ||
480 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
481 | int err; | ||
482 | |||
483 | uac2->pdrv.probe = snd_uac2_probe; | ||
484 | uac2->pdrv.remove = snd_uac2_remove; | ||
485 | uac2->pdrv.driver.name = uac2_name; | ||
486 | |||
487 | uac2->pdev.id = 0; | ||
488 | uac2->pdev.name = uac2_name; | ||
489 | |||
490 | /* Register snd_uac2 driver */ | ||
491 | err = platform_driver_register(&uac2->pdrv); | ||
492 | if (err) | ||
493 | return err; | ||
494 | |||
495 | /* Register snd_uac2 device */ | ||
496 | err = platform_device_register(&uac2->pdev); | ||
497 | if (err) | ||
498 | platform_driver_unregister(&uac2->pdrv); | ||
499 | |||
500 | return err; | ||
501 | } | ||
502 | |||
503 | static void alsa_uac2_exit(struct audio_dev *agdev) | ||
504 | { | ||
505 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
506 | |||
507 | platform_driver_unregister(&uac2->pdrv); | ||
508 | platform_device_unregister(&uac2->pdev); | ||
509 | } | ||
510 | |||
511 | |||
512 | /* --------- USB Function Interface ------------- */ | ||
513 | |||
514 | enum { | ||
515 | STR_ASSOC, | ||
516 | STR_IF_CTRL, | ||
517 | STR_CLKSRC_IN, | ||
518 | STR_CLKSRC_OUT, | ||
519 | STR_USB_IT, | ||
520 | STR_IO_IT, | ||
521 | STR_USB_OT, | ||
522 | STR_IO_OT, | ||
523 | STR_AS_OUT_ALT0, | ||
524 | STR_AS_OUT_ALT1, | ||
525 | STR_AS_IN_ALT0, | ||
526 | STR_AS_IN_ALT1, | ||
527 | }; | ||
528 | |||
529 | static const char ifassoc[] = "Source/Sink"; | ||
530 | static const char ifctrl[] = "Topology Control"; | ||
531 | static char clksrc_in[8]; | ||
532 | static char clksrc_out[8]; | ||
533 | static const char usb_it[] = "USBH Out"; | ||
534 | static const char io_it[] = "USBD Out"; | ||
535 | static const char usb_ot[] = "USBH In"; | ||
536 | static const char io_ot[] = "USBD In"; | ||
537 | static const char out_alt0[] = "Playback Inactive"; | ||
538 | static const char out_alt1[] = "Playback Active"; | ||
539 | static const char in_alt0[] = "Capture Inactive"; | ||
540 | static const char in_alt1[] = "Capture Active"; | ||
541 | |||
542 | static struct usb_string strings_fn[] = { | ||
543 | [STR_ASSOC].s = ifassoc, | ||
544 | [STR_IF_CTRL].s = ifctrl, | ||
545 | [STR_CLKSRC_IN].s = clksrc_in, | ||
546 | [STR_CLKSRC_OUT].s = clksrc_out, | ||
547 | [STR_USB_IT].s = usb_it, | ||
548 | [STR_IO_IT].s = io_it, | ||
549 | [STR_USB_OT].s = usb_ot, | ||
550 | [STR_IO_OT].s = io_ot, | ||
551 | [STR_AS_OUT_ALT0].s = out_alt0, | ||
552 | [STR_AS_OUT_ALT1].s = out_alt1, | ||
553 | [STR_AS_IN_ALT0].s = in_alt0, | ||
554 | [STR_AS_IN_ALT1].s = in_alt1, | ||
555 | { }, | ||
556 | }; | ||
557 | |||
558 | static struct usb_gadget_strings str_fn = { | ||
559 | .language = 0x0409, /* en-us */ | ||
560 | .strings = strings_fn, | ||
561 | }; | ||
562 | |||
563 | static struct usb_gadget_strings *fn_strings[] = { | ||
564 | &str_fn, | ||
565 | NULL, | ||
566 | }; | ||
567 | |||
568 | static struct usb_qualifier_descriptor devqual_desc = { | ||
569 | .bLength = sizeof devqual_desc, | ||
570 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
571 | |||
572 | .bcdUSB = cpu_to_le16(0x200), | ||
573 | .bDeviceClass = USB_CLASS_MISC, | ||
574 | .bDeviceSubClass = 0x02, | ||
575 | .bDeviceProtocol = 0x01, | ||
576 | .bNumConfigurations = 1, | ||
577 | .bRESERVED = 0, | ||
578 | }; | ||
579 | |||
580 | static struct usb_interface_assoc_descriptor iad_desc = { | ||
581 | .bLength = sizeof iad_desc, | ||
582 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, | ||
583 | |||
584 | .bFirstInterface = 0, | ||
585 | .bInterfaceCount = 3, | ||
586 | .bFunctionClass = USB_CLASS_AUDIO, | ||
587 | .bFunctionSubClass = UAC2_FUNCTION_SUBCLASS_UNDEFINED, | ||
588 | .bFunctionProtocol = UAC_VERSION_2, | ||
589 | }; | ||
590 | |||
591 | /* Audio Control Interface */ | ||
592 | static struct usb_interface_descriptor std_ac_if_desc = { | ||
593 | .bLength = sizeof std_ac_if_desc, | ||
594 | .bDescriptorType = USB_DT_INTERFACE, | ||
595 | |||
596 | .bAlternateSetting = 0, | ||
597 | .bNumEndpoints = 0, | ||
598 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
599 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | ||
600 | .bInterfaceProtocol = UAC_VERSION_2, | ||
601 | }; | ||
602 | |||
603 | /* Clock source for IN traffic */ | ||
604 | struct uac_clock_source_descriptor in_clk_src_desc = { | ||
605 | .bLength = sizeof in_clk_src_desc, | ||
606 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
607 | |||
608 | .bDescriptorSubtype = UAC2_CLOCK_SOURCE, | ||
609 | .bClockID = USB_IN_CLK_ID, | ||
610 | .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, | ||
611 | .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), | ||
612 | .bAssocTerminal = 0, | ||
613 | }; | ||
614 | |||
615 | /* Clock source for OUT traffic */ | ||
616 | struct uac_clock_source_descriptor out_clk_src_desc = { | ||
617 | .bLength = sizeof out_clk_src_desc, | ||
618 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
619 | |||
620 | .bDescriptorSubtype = UAC2_CLOCK_SOURCE, | ||
621 | .bClockID = USB_OUT_CLK_ID, | ||
622 | .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, | ||
623 | .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), | ||
624 | .bAssocTerminal = 0, | ||
625 | }; | ||
626 | |||
627 | /* Input Terminal for USB_OUT */ | ||
628 | struct uac2_input_terminal_descriptor usb_out_it_desc = { | ||
629 | .bLength = sizeof usb_out_it_desc, | ||
630 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
631 | |||
632 | .bDescriptorSubtype = UAC_INPUT_TERMINAL, | ||
633 | .bTerminalID = USB_OUT_IT_ID, | ||
634 | .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), | ||
635 | .bAssocTerminal = 0, | ||
636 | .bCSourceID = USB_OUT_CLK_ID, | ||
637 | .iChannelNames = 0, | ||
638 | .bmControls = (CONTROL_RDWR << COPY_CTRL), | ||
639 | }; | ||
640 | |||
641 | /* Input Terminal for I/O-In */ | ||
642 | struct uac2_input_terminal_descriptor io_in_it_desc = { | ||
643 | .bLength = sizeof io_in_it_desc, | ||
644 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
645 | |||
646 | .bDescriptorSubtype = UAC_INPUT_TERMINAL, | ||
647 | .bTerminalID = IO_IN_IT_ID, | ||
648 | .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED), | ||
649 | .bAssocTerminal = 0, | ||
650 | .bCSourceID = USB_IN_CLK_ID, | ||
651 | .iChannelNames = 0, | ||
652 | .bmControls = (CONTROL_RDWR << COPY_CTRL), | ||
653 | }; | ||
654 | |||
655 | /* Ouput Terminal for USB_IN */ | ||
656 | struct uac2_output_terminal_descriptor usb_in_ot_desc = { | ||
657 | .bLength = sizeof usb_in_ot_desc, | ||
658 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
659 | |||
660 | .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, | ||
661 | .bTerminalID = USB_IN_OT_ID, | ||
662 | .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), | ||
663 | .bAssocTerminal = 0, | ||
664 | .bSourceID = IO_IN_IT_ID, | ||
665 | .bCSourceID = USB_IN_CLK_ID, | ||
666 | .bmControls = (CONTROL_RDWR << COPY_CTRL), | ||
667 | }; | ||
668 | |||
669 | /* Ouput Terminal for I/O-Out */ | ||
670 | struct uac2_output_terminal_descriptor io_out_ot_desc = { | ||
671 | .bLength = sizeof io_out_ot_desc, | ||
672 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
673 | |||
674 | .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, | ||
675 | .bTerminalID = IO_OUT_OT_ID, | ||
676 | .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED), | ||
677 | .bAssocTerminal = 0, | ||
678 | .bSourceID = USB_OUT_IT_ID, | ||
679 | .bCSourceID = USB_OUT_CLK_ID, | ||
680 | .bmControls = (CONTROL_RDWR << COPY_CTRL), | ||
681 | }; | ||
682 | |||
683 | struct uac2_ac_header_descriptor ac_hdr_desc = { | ||
684 | .bLength = sizeof ac_hdr_desc, | ||
685 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
686 | |||
687 | .bDescriptorSubtype = UAC_MS_HEADER, | ||
688 | .bcdADC = cpu_to_le16(0x200), | ||
689 | .bCategory = UAC2_FUNCTION_IO_BOX, | ||
690 | .wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc | ||
691 | + sizeof usb_out_it_desc + sizeof io_in_it_desc | ||
692 | + sizeof usb_in_ot_desc + sizeof io_out_ot_desc, | ||
693 | .bmControls = 0, | ||
694 | }; | ||
695 | |||
696 | /* Audio Streaming OUT Interface - Alt0 */ | ||
697 | static struct usb_interface_descriptor std_as_out_if0_desc = { | ||
698 | .bLength = sizeof std_as_out_if0_desc, | ||
699 | .bDescriptorType = USB_DT_INTERFACE, | ||
700 | |||
701 | .bAlternateSetting = 0, | ||
702 | .bNumEndpoints = 0, | ||
703 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
704 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, | ||
705 | .bInterfaceProtocol = UAC_VERSION_2, | ||
706 | }; | ||
707 | |||
708 | /* Audio Streaming OUT Interface - Alt1 */ | ||
709 | static struct usb_interface_descriptor std_as_out_if1_desc = { | ||
710 | .bLength = sizeof std_as_out_if1_desc, | ||
711 | .bDescriptorType = USB_DT_INTERFACE, | ||
712 | |||
713 | .bAlternateSetting = 1, | ||
714 | .bNumEndpoints = 1, | ||
715 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
716 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, | ||
717 | .bInterfaceProtocol = UAC_VERSION_2, | ||
718 | }; | ||
719 | |||
720 | /* Audio Stream OUT Intface Desc */ | ||
721 | struct uac2_as_header_descriptor as_out_hdr_desc = { | ||
722 | .bLength = sizeof as_out_hdr_desc, | ||
723 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
724 | |||
725 | .bDescriptorSubtype = UAC_AS_GENERAL, | ||
726 | .bTerminalLink = USB_OUT_IT_ID, | ||
727 | .bmControls = 0, | ||
728 | .bFormatType = UAC_FORMAT_TYPE_I, | ||
729 | .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM), | ||
730 | .iChannelNames = 0, | ||
731 | }; | ||
732 | |||
733 | /* Audio USB_OUT Format */ | ||
734 | struct uac2_format_type_i_descriptor as_out_fmt1_desc = { | ||
735 | .bLength = sizeof as_out_fmt1_desc, | ||
736 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
737 | .bDescriptorSubtype = UAC_FORMAT_TYPE, | ||
738 | .bFormatType = UAC_FORMAT_TYPE_I, | ||
739 | }; | ||
740 | |||
741 | /* STD AS ISO OUT Endpoint */ | ||
742 | struct usb_endpoint_descriptor fs_epout_desc = { | ||
743 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
744 | .bDescriptorType = USB_DT_ENDPOINT, | ||
745 | |||
746 | .bEndpointAddress = USB_DIR_OUT, | ||
747 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | ||
748 | .bInterval = 1, | ||
749 | }; | ||
750 | |||
751 | struct usb_endpoint_descriptor hs_epout_desc = { | ||
752 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
753 | .bDescriptorType = USB_DT_ENDPOINT, | ||
754 | |||
755 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | ||
756 | .bInterval = 4, | ||
757 | }; | ||
758 | |||
759 | /* CS AS ISO OUT Endpoint */ | ||
760 | static struct uac2_iso_endpoint_descriptor as_iso_out_desc = { | ||
761 | .bLength = sizeof as_iso_out_desc, | ||
762 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
763 | |||
764 | .bDescriptorSubtype = UAC_EP_GENERAL, | ||
765 | .bmAttributes = 0, | ||
766 | .bmControls = 0, | ||
767 | .bLockDelayUnits = 0, | ||
768 | .wLockDelay = 0, | ||
769 | }; | ||
770 | |||
771 | /* Audio Streaming IN Interface - Alt0 */ | ||
772 | static struct usb_interface_descriptor std_as_in_if0_desc = { | ||
773 | .bLength = sizeof std_as_in_if0_desc, | ||
774 | .bDescriptorType = USB_DT_INTERFACE, | ||
775 | |||
776 | .bAlternateSetting = 0, | ||
777 | .bNumEndpoints = 0, | ||
778 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
779 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, | ||
780 | .bInterfaceProtocol = UAC_VERSION_2, | ||
781 | }; | ||
782 | |||
783 | /* Audio Streaming IN Interface - Alt1 */ | ||
784 | static struct usb_interface_descriptor std_as_in_if1_desc = { | ||
785 | .bLength = sizeof std_as_in_if1_desc, | ||
786 | .bDescriptorType = USB_DT_INTERFACE, | ||
787 | |||
788 | .bAlternateSetting = 1, | ||
789 | .bNumEndpoints = 1, | ||
790 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
791 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, | ||
792 | .bInterfaceProtocol = UAC_VERSION_2, | ||
793 | }; | ||
794 | |||
795 | /* Audio Stream IN Intface Desc */ | ||
796 | struct uac2_as_header_descriptor as_in_hdr_desc = { | ||
797 | .bLength = sizeof as_in_hdr_desc, | ||
798 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
799 | |||
800 | .bDescriptorSubtype = UAC_AS_GENERAL, | ||
801 | .bTerminalLink = USB_IN_OT_ID, | ||
802 | .bmControls = 0, | ||
803 | .bFormatType = UAC_FORMAT_TYPE_I, | ||
804 | .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM), | ||
805 | .iChannelNames = 0, | ||
806 | }; | ||
807 | |||
808 | /* Audio USB_IN Format */ | ||
809 | struct uac2_format_type_i_descriptor as_in_fmt1_desc = { | ||
810 | .bLength = sizeof as_in_fmt1_desc, | ||
811 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
812 | .bDescriptorSubtype = UAC_FORMAT_TYPE, | ||
813 | .bFormatType = UAC_FORMAT_TYPE_I, | ||
814 | }; | ||
815 | |||
816 | /* STD AS ISO IN Endpoint */ | ||
817 | struct usb_endpoint_descriptor fs_epin_desc = { | ||
818 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
819 | .bDescriptorType = USB_DT_ENDPOINT, | ||
820 | |||
821 | .bEndpointAddress = USB_DIR_IN, | ||
822 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | ||
823 | .bInterval = 1, | ||
824 | }; | ||
825 | |||
826 | struct usb_endpoint_descriptor hs_epin_desc = { | ||
827 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
828 | .bDescriptorType = USB_DT_ENDPOINT, | ||
829 | |||
830 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | ||
831 | .bInterval = 4, | ||
832 | }; | ||
833 | |||
834 | /* CS AS ISO IN Endpoint */ | ||
835 | static struct uac2_iso_endpoint_descriptor as_iso_in_desc = { | ||
836 | .bLength = sizeof as_iso_in_desc, | ||
837 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
838 | |||
839 | .bDescriptorSubtype = UAC_EP_GENERAL, | ||
840 | .bmAttributes = 0, | ||
841 | .bmControls = 0, | ||
842 | .bLockDelayUnits = 0, | ||
843 | .wLockDelay = 0, | ||
844 | }; | ||
845 | |||
846 | static struct usb_descriptor_header *fs_audio_desc[] = { | ||
847 | (struct usb_descriptor_header *)&iad_desc, | ||
848 | (struct usb_descriptor_header *)&std_ac_if_desc, | ||
849 | |||
850 | (struct usb_descriptor_header *)&ac_hdr_desc, | ||
851 | (struct usb_descriptor_header *)&in_clk_src_desc, | ||
852 | (struct usb_descriptor_header *)&out_clk_src_desc, | ||
853 | (struct usb_descriptor_header *)&usb_out_it_desc, | ||
854 | (struct usb_descriptor_header *)&io_in_it_desc, | ||
855 | (struct usb_descriptor_header *)&usb_in_ot_desc, | ||
856 | (struct usb_descriptor_header *)&io_out_ot_desc, | ||
857 | |||
858 | (struct usb_descriptor_header *)&std_as_out_if0_desc, | ||
859 | (struct usb_descriptor_header *)&std_as_out_if1_desc, | ||
860 | |||
861 | (struct usb_descriptor_header *)&as_out_hdr_desc, | ||
862 | (struct usb_descriptor_header *)&as_out_fmt1_desc, | ||
863 | (struct usb_descriptor_header *)&fs_epout_desc, | ||
864 | (struct usb_descriptor_header *)&as_iso_out_desc, | ||
865 | |||
866 | (struct usb_descriptor_header *)&std_as_in_if0_desc, | ||
867 | (struct usb_descriptor_header *)&std_as_in_if1_desc, | ||
868 | |||
869 | (struct usb_descriptor_header *)&as_in_hdr_desc, | ||
870 | (struct usb_descriptor_header *)&as_in_fmt1_desc, | ||
871 | (struct usb_descriptor_header *)&fs_epin_desc, | ||
872 | (struct usb_descriptor_header *)&as_iso_in_desc, | ||
873 | NULL, | ||
874 | }; | ||
875 | |||
876 | static struct usb_descriptor_header *hs_audio_desc[] = { | ||
877 | (struct usb_descriptor_header *)&iad_desc, | ||
878 | (struct usb_descriptor_header *)&std_ac_if_desc, | ||
879 | |||
880 | (struct usb_descriptor_header *)&ac_hdr_desc, | ||
881 | (struct usb_descriptor_header *)&in_clk_src_desc, | ||
882 | (struct usb_descriptor_header *)&out_clk_src_desc, | ||
883 | (struct usb_descriptor_header *)&usb_out_it_desc, | ||
884 | (struct usb_descriptor_header *)&io_in_it_desc, | ||
885 | (struct usb_descriptor_header *)&usb_in_ot_desc, | ||
886 | (struct usb_descriptor_header *)&io_out_ot_desc, | ||
887 | |||
888 | (struct usb_descriptor_header *)&std_as_out_if0_desc, | ||
889 | (struct usb_descriptor_header *)&std_as_out_if1_desc, | ||
890 | |||
891 | (struct usb_descriptor_header *)&as_out_hdr_desc, | ||
892 | (struct usb_descriptor_header *)&as_out_fmt1_desc, | ||
893 | (struct usb_descriptor_header *)&hs_epout_desc, | ||
894 | (struct usb_descriptor_header *)&as_iso_out_desc, | ||
895 | |||
896 | (struct usb_descriptor_header *)&std_as_in_if0_desc, | ||
897 | (struct usb_descriptor_header *)&std_as_in_if1_desc, | ||
898 | |||
899 | (struct usb_descriptor_header *)&as_in_hdr_desc, | ||
900 | (struct usb_descriptor_header *)&as_in_fmt1_desc, | ||
901 | (struct usb_descriptor_header *)&hs_epin_desc, | ||
902 | (struct usb_descriptor_header *)&as_iso_in_desc, | ||
903 | NULL, | ||
904 | }; | ||
905 | |||
906 | struct cntrl_cur_lay3 { | ||
907 | __u32 dCUR; | ||
908 | }; | ||
909 | |||
910 | struct cntrl_range_lay3 { | ||
911 | __u16 wNumSubRanges; | ||
912 | __u32 dMIN; | ||
913 | __u32 dMAX; | ||
914 | __u32 dRES; | ||
915 | } __packed; | ||
916 | |||
917 | static inline void | ||
918 | free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep) | ||
919 | { | ||
920 | struct snd_uac2_chip *uac2 = prm_to_uac2(prm); | ||
921 | int i; | ||
922 | |||
923 | prm->ep_enabled = false; | ||
924 | |||
925 | for (i = 0; i < USB_XFERS; i++) { | ||
926 | if (prm->ureq[i].req) { | ||
927 | usb_ep_dequeue(ep, prm->ureq[i].req); | ||
928 | usb_ep_free_request(ep, prm->ureq[i].req); | ||
929 | prm->ureq[i].req = NULL; | ||
930 | } | ||
931 | } | ||
932 | |||
933 | if (usb_ep_disable(ep)) | ||
934 | dev_err(&uac2->pdev.dev, | ||
935 | "%s:%d Error!\n", __func__, __LINE__); | ||
936 | } | ||
937 | |||
938 | static int __init | ||
939 | afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | ||
940 | { | ||
941 | struct audio_dev *agdev = func_to_agdev(fn); | ||
942 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
943 | struct usb_composite_dev *cdev = cfg->cdev; | ||
944 | struct usb_gadget *gadget = cdev->gadget; | ||
945 | struct uac2_rtd_params *prm; | ||
946 | int ret; | ||
947 | |||
948 | ret = usb_interface_id(cfg, fn); | ||
949 | if (ret < 0) { | ||
950 | dev_err(&uac2->pdev.dev, | ||
951 | "%s:%d Error!\n", __func__, __LINE__); | ||
952 | return ret; | ||
953 | } | ||
954 | std_ac_if_desc.bInterfaceNumber = ret; | ||
955 | ALT_SET(agdev->ac_alt, 0); | ||
956 | INTF_SET(agdev->ac_alt, ret); | ||
957 | |||
958 | ret = usb_interface_id(cfg, fn); | ||
959 | if (ret < 0) { | ||
960 | dev_err(&uac2->pdev.dev, | ||
961 | "%s:%d Error!\n", __func__, __LINE__); | ||
962 | return ret; | ||
963 | } | ||
964 | std_as_out_if0_desc.bInterfaceNumber = ret; | ||
965 | std_as_out_if1_desc.bInterfaceNumber = ret; | ||
966 | ALT_SET(agdev->as_out_alt, 0); | ||
967 | INTF_SET(agdev->as_out_alt, ret); | ||
968 | |||
969 | ret = usb_interface_id(cfg, fn); | ||
970 | if (ret < 0) { | ||
971 | dev_err(&uac2->pdev.dev, | ||
972 | "%s:%d Error!\n", __func__, __LINE__); | ||
973 | return ret; | ||
974 | } | ||
975 | std_as_in_if0_desc.bInterfaceNumber = ret; | ||
976 | std_as_in_if1_desc.bInterfaceNumber = ret; | ||
977 | ALT_SET(agdev->as_in_alt, 0); | ||
978 | INTF_SET(agdev->as_in_alt, ret); | ||
979 | |||
980 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); | ||
981 | if (!agdev->out_ep) | ||
982 | dev_err(&uac2->pdev.dev, | ||
983 | "%s:%d Error!\n", __func__, __LINE__); | ||
984 | agdev->out_ep->driver_data = agdev; | ||
985 | |||
986 | agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); | ||
987 | if (!agdev->in_ep) | ||
988 | dev_err(&uac2->pdev.dev, | ||
989 | "%s:%d Error!\n", __func__, __LINE__); | ||
990 | agdev->in_ep->driver_data = agdev; | ||
991 | |||
992 | hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; | ||
993 | hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize; | ||
994 | hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; | ||
995 | hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize; | ||
996 | |||
997 | fn->descriptors = usb_copy_descriptors(fs_audio_desc); | ||
998 | if (gadget_is_dualspeed(gadget)) | ||
999 | fn->hs_descriptors = usb_copy_descriptors(hs_audio_desc); | ||
1000 | |||
1001 | prm = &agdev->uac2.c_prm; | ||
1002 | prm->max_psize = hs_epout_desc.wMaxPacketSize; | ||
1003 | prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); | ||
1004 | if (!prm->rbuf) { | ||
1005 | prm->max_psize = 0; | ||
1006 | dev_err(&uac2->pdev.dev, | ||
1007 | "%s:%d Error!\n", __func__, __LINE__); | ||
1008 | } | ||
1009 | |||
1010 | prm = &agdev->uac2.p_prm; | ||
1011 | prm->max_psize = hs_epin_desc.wMaxPacketSize; | ||
1012 | prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); | ||
1013 | if (!prm->rbuf) { | ||
1014 | prm->max_psize = 0; | ||
1015 | dev_err(&uac2->pdev.dev, | ||
1016 | "%s:%d Error!\n", __func__, __LINE__); | ||
1017 | } | ||
1018 | |||
1019 | return alsa_uac2_init(agdev); | ||
1020 | } | ||
1021 | |||
1022 | static void | ||
1023 | afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) | ||
1024 | { | ||
1025 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1026 | struct usb_composite_dev *cdev = cfg->cdev; | ||
1027 | struct usb_gadget *gadget = cdev->gadget; | ||
1028 | struct uac2_rtd_params *prm; | ||
1029 | |||
1030 | alsa_uac2_exit(agdev); | ||
1031 | |||
1032 | prm = &agdev->uac2.p_prm; | ||
1033 | kfree(prm->rbuf); | ||
1034 | |||
1035 | prm = &agdev->uac2.c_prm; | ||
1036 | kfree(prm->rbuf); | ||
1037 | |||
1038 | if (gadget_is_dualspeed(gadget)) | ||
1039 | usb_free_descriptors(fn->hs_descriptors); | ||
1040 | usb_free_descriptors(fn->descriptors); | ||
1041 | |||
1042 | if (agdev->in_ep) | ||
1043 | agdev->in_ep->driver_data = NULL; | ||
1044 | if (agdev->out_ep) | ||
1045 | agdev->out_ep->driver_data = NULL; | ||
1046 | } | ||
1047 | |||
1048 | static int | ||
1049 | afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) | ||
1050 | { | ||
1051 | struct usb_composite_dev *cdev = fn->config->cdev; | ||
1052 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1053 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1054 | struct usb_gadget *gadget = cdev->gadget; | ||
1055 | struct usb_request *req; | ||
1056 | struct usb_ep *ep; | ||
1057 | struct uac2_rtd_params *prm; | ||
1058 | int i; | ||
1059 | |||
1060 | /* No i/f has more than 2 alt settings */ | ||
1061 | if (alt > 1) { | ||
1062 | dev_err(&uac2->pdev.dev, | ||
1063 | "%s:%d Error!\n", __func__, __LINE__); | ||
1064 | return -EINVAL; | ||
1065 | } | ||
1066 | |||
1067 | if (intf == INTF_GET(agdev->ac_alt)) { | ||
1068 | /* Control I/f has only 1 AltSetting - 0 */ | ||
1069 | if (alt) { | ||
1070 | dev_err(&uac2->pdev.dev, | ||
1071 | "%s:%d Error!\n", __func__, __LINE__); | ||
1072 | return -EINVAL; | ||
1073 | } | ||
1074 | return 0; | ||
1075 | } | ||
1076 | |||
1077 | if (intf == INTF_GET(agdev->as_out_alt)) { | ||
1078 | ep = agdev->out_ep; | ||
1079 | prm = &uac2->c_prm; | ||
1080 | config_ep_by_speed(gadget, fn, ep); | ||
1081 | ALT_SET(agdev->as_out_alt, alt); | ||
1082 | } else if (intf == INTF_GET(agdev->as_in_alt)) { | ||
1083 | ep = agdev->in_ep; | ||
1084 | prm = &uac2->p_prm; | ||
1085 | config_ep_by_speed(gadget, fn, ep); | ||
1086 | ALT_SET(agdev->as_in_alt, alt); | ||
1087 | } else { | ||
1088 | dev_err(&uac2->pdev.dev, | ||
1089 | "%s:%d Error!\n", __func__, __LINE__); | ||
1090 | return -EINVAL; | ||
1091 | } | ||
1092 | |||
1093 | if (alt == 0) { | ||
1094 | free_ep(prm, ep); | ||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1098 | prm->ep_enabled = true; | ||
1099 | usb_ep_enable(ep); | ||
1100 | |||
1101 | for (i = 0; i < USB_XFERS; i++) { | ||
1102 | if (prm->ureq[i].req) { | ||
1103 | if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) | ||
1104 | dev_err(&uac2->pdev.dev, "%d Error!\n", | ||
1105 | __LINE__); | ||
1106 | continue; | ||
1107 | } | ||
1108 | |||
1109 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); | ||
1110 | if (req == NULL) { | ||
1111 | dev_err(&uac2->pdev.dev, | ||
1112 | "%s:%d Error!\n", __func__, __LINE__); | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1115 | |||
1116 | prm->ureq[i].req = req; | ||
1117 | prm->ureq[i].pp = prm; | ||
1118 | |||
1119 | req->zero = 0; | ||
1120 | req->dma = DMA_ADDR_INVALID; | ||
1121 | req->context = &prm->ureq[i]; | ||
1122 | req->length = prm->max_psize; | ||
1123 | req->complete = agdev_iso_complete; | ||
1124 | req->buf = prm->rbuf + i * req->length; | ||
1125 | |||
1126 | if (usb_ep_queue(ep, req, GFP_ATOMIC)) | ||
1127 | dev_err(&uac2->pdev.dev, "%d Error!\n", __LINE__); | ||
1128 | } | ||
1129 | |||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | static int | ||
1134 | afunc_get_alt(struct usb_function *fn, unsigned intf) | ||
1135 | { | ||
1136 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1137 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1138 | |||
1139 | if (intf == INTF_GET(agdev->ac_alt)) | ||
1140 | return ALT_GET(agdev->ac_alt); | ||
1141 | else if (intf == INTF_GET(agdev->as_out_alt)) | ||
1142 | return ALT_GET(agdev->as_out_alt); | ||
1143 | else if (intf == INTF_GET(agdev->as_in_alt)) | ||
1144 | return ALT_GET(agdev->as_in_alt); | ||
1145 | else | ||
1146 | dev_err(&uac2->pdev.dev, | ||
1147 | "%s:%d Invalid Interface %d!\n", | ||
1148 | __func__, __LINE__, intf); | ||
1149 | |||
1150 | return -EINVAL; | ||
1151 | } | ||
1152 | |||
1153 | static void | ||
1154 | afunc_disable(struct usb_function *fn) | ||
1155 | { | ||
1156 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1157 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1158 | |||
1159 | free_ep(&uac2->p_prm, agdev->in_ep); | ||
1160 | ALT_SET(agdev->as_in_alt, 0); | ||
1161 | |||
1162 | free_ep(&uac2->c_prm, agdev->out_ep); | ||
1163 | ALT_SET(agdev->as_out_alt, 0); | ||
1164 | } | ||
1165 | |||
1166 | static int | ||
1167 | in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) | ||
1168 | { | ||
1169 | struct usb_request *req = fn->config->cdev->req; | ||
1170 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1171 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1172 | u16 w_length = le16_to_cpu(cr->wLength); | ||
1173 | u16 w_index = le16_to_cpu(cr->wIndex); | ||
1174 | u16 w_value = le16_to_cpu(cr->wValue); | ||
1175 | u8 entity_id = (w_index >> 8) & 0xff; | ||
1176 | u8 control_selector = w_value >> 8; | ||
1177 | int value = -EOPNOTSUPP; | ||
1178 | |||
1179 | if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { | ||
1180 | struct cntrl_cur_lay3 c; | ||
1181 | |||
1182 | if (entity_id == USB_IN_CLK_ID) | ||
1183 | c.dCUR = p_srate; | ||
1184 | else if (entity_id == USB_OUT_CLK_ID) | ||
1185 | c.dCUR = c_srate; | ||
1186 | |||
1187 | value = min_t(unsigned, w_length, sizeof c); | ||
1188 | memcpy(req->buf, &c, value); | ||
1189 | } else if (control_selector == UAC2_CS_CONTROL_CLOCK_VALID) { | ||
1190 | *(u8 *)req->buf = 1; | ||
1191 | value = min_t(unsigned, w_length, 1); | ||
1192 | } else { | ||
1193 | dev_err(&uac2->pdev.dev, | ||
1194 | "%s:%d control_selector=%d TODO!\n", | ||
1195 | __func__, __LINE__, control_selector); | ||
1196 | } | ||
1197 | |||
1198 | return value; | ||
1199 | } | ||
1200 | |||
1201 | static int | ||
1202 | in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) | ||
1203 | { | ||
1204 | struct usb_request *req = fn->config->cdev->req; | ||
1205 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1206 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1207 | u16 w_length = le16_to_cpu(cr->wLength); | ||
1208 | u16 w_index = le16_to_cpu(cr->wIndex); | ||
1209 | u16 w_value = le16_to_cpu(cr->wValue); | ||
1210 | u8 entity_id = (w_index >> 8) & 0xff; | ||
1211 | u8 control_selector = w_value >> 8; | ||
1212 | struct cntrl_range_lay3 r; | ||
1213 | int value = -EOPNOTSUPP; | ||
1214 | |||
1215 | if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { | ||
1216 | if (entity_id == USB_IN_CLK_ID) | ||
1217 | r.dMIN = p_srate; | ||
1218 | else if (entity_id == USB_OUT_CLK_ID) | ||
1219 | r.dMIN = c_srate; | ||
1220 | else | ||
1221 | return -EOPNOTSUPP; | ||
1222 | |||
1223 | r.dMAX = r.dMIN; | ||
1224 | r.dRES = 0; | ||
1225 | r.wNumSubRanges = 1; | ||
1226 | |||
1227 | value = min_t(unsigned, w_length, sizeof r); | ||
1228 | memcpy(req->buf, &r, value); | ||
1229 | } else { | ||
1230 | dev_err(&uac2->pdev.dev, | ||
1231 | "%s:%d control_selector=%d TODO!\n", | ||
1232 | __func__, __LINE__, control_selector); | ||
1233 | } | ||
1234 | |||
1235 | return value; | ||
1236 | } | ||
1237 | |||
1238 | static int | ||
1239 | ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr) | ||
1240 | { | ||
1241 | if (cr->bRequest == UAC2_CS_CUR) | ||
1242 | return in_rq_cur(fn, cr); | ||
1243 | else if (cr->bRequest == UAC2_CS_RANGE) | ||
1244 | return in_rq_range(fn, cr); | ||
1245 | else | ||
1246 | return -EOPNOTSUPP; | ||
1247 | } | ||
1248 | |||
1249 | static int | ||
1250 | out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) | ||
1251 | { | ||
1252 | u16 w_length = le16_to_cpu(cr->wLength); | ||
1253 | u16 w_value = le16_to_cpu(cr->wValue); | ||
1254 | u8 control_selector = w_value >> 8; | ||
1255 | |||
1256 | if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) | ||
1257 | return w_length; | ||
1258 | |||
1259 | return -EOPNOTSUPP; | ||
1260 | } | ||
1261 | |||
1262 | static int | ||
1263 | setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr) | ||
1264 | { | ||
1265 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1266 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1267 | u16 w_index = le16_to_cpu(cr->wIndex); | ||
1268 | u8 intf = w_index & 0xff; | ||
1269 | |||
1270 | if (intf != INTF_GET(agdev->ac_alt)) { | ||
1271 | dev_err(&uac2->pdev.dev, | ||
1272 | "%s:%d Error!\n", __func__, __LINE__); | ||
1273 | return -EOPNOTSUPP; | ||
1274 | } | ||
1275 | |||
1276 | if (cr->bRequestType & USB_DIR_IN) | ||
1277 | return ac_rq_in(fn, cr); | ||
1278 | else if (cr->bRequest == UAC2_CS_CUR) | ||
1279 | return out_rq_cur(fn, cr); | ||
1280 | |||
1281 | return -EOPNOTSUPP; | ||
1282 | } | ||
1283 | |||
1284 | static int | ||
1285 | afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) | ||
1286 | { | ||
1287 | struct usb_composite_dev *cdev = fn->config->cdev; | ||
1288 | struct audio_dev *agdev = func_to_agdev(fn); | ||
1289 | struct snd_uac2_chip *uac2 = &agdev->uac2; | ||
1290 | struct usb_request *req = cdev->req; | ||
1291 | u16 w_length = le16_to_cpu(cr->wLength); | ||
1292 | int value = -EOPNOTSUPP; | ||
1293 | |||
1294 | /* Only Class specific requests are supposed to reach here */ | ||
1295 | if ((cr->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) | ||
1296 | return -EOPNOTSUPP; | ||
1297 | |||
1298 | if ((cr->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE) | ||
1299 | value = setup_rq_inf(fn, cr); | ||
1300 | else | ||
1301 | dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); | ||
1302 | |||
1303 | if (value >= 0) { | ||
1304 | req->length = value; | ||
1305 | req->zero = value < w_length; | ||
1306 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | ||
1307 | if (value < 0) { | ||
1308 | dev_err(&uac2->pdev.dev, | ||
1309 | "%s:%d Error!\n", __func__, __LINE__); | ||
1310 | req->status = 0; | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | return value; | ||
1315 | } | ||
1316 | |||
1317 | static int audio_bind_config(struct usb_configuration *cfg) | ||
1318 | { | ||
1319 | int id, res; | ||
1320 | |||
1321 | agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); | ||
1322 | if (agdev_g == NULL) { | ||
1323 | printk(KERN_ERR "Unable to allocate audio gadget\n"); | ||
1324 | return -ENOMEM; | ||
1325 | } | ||
1326 | |||
1327 | id = usb_string_id(cfg->cdev); | ||
1328 | if (id < 0) | ||
1329 | return id; | ||
1330 | |||
1331 | strings_fn[STR_ASSOC].id = id; | ||
1332 | iad_desc.iFunction = id, | ||
1333 | |||
1334 | id = usb_string_id(cfg->cdev); | ||
1335 | if (id < 0) | ||
1336 | return id; | ||
1337 | |||
1338 | strings_fn[STR_IF_CTRL].id = id; | ||
1339 | std_ac_if_desc.iInterface = id, | ||
1340 | |||
1341 | id = usb_string_id(cfg->cdev); | ||
1342 | if (id < 0) | ||
1343 | return id; | ||
1344 | |||
1345 | strings_fn[STR_CLKSRC_IN].id = id; | ||
1346 | in_clk_src_desc.iClockSource = id, | ||
1347 | |||
1348 | id = usb_string_id(cfg->cdev); | ||
1349 | if (id < 0) | ||
1350 | return id; | ||
1351 | |||
1352 | strings_fn[STR_CLKSRC_OUT].id = id; | ||
1353 | out_clk_src_desc.iClockSource = id, | ||
1354 | |||
1355 | id = usb_string_id(cfg->cdev); | ||
1356 | if (id < 0) | ||
1357 | return id; | ||
1358 | |||
1359 | strings_fn[STR_USB_IT].id = id; | ||
1360 | usb_out_it_desc.iTerminal = id, | ||
1361 | |||
1362 | id = usb_string_id(cfg->cdev); | ||
1363 | if (id < 0) | ||
1364 | return id; | ||
1365 | |||
1366 | strings_fn[STR_IO_IT].id = id; | ||
1367 | io_in_it_desc.iTerminal = id; | ||
1368 | |||
1369 | id = usb_string_id(cfg->cdev); | ||
1370 | if (id < 0) | ||
1371 | return id; | ||
1372 | |||
1373 | strings_fn[STR_USB_OT].id = id; | ||
1374 | usb_in_ot_desc.iTerminal = id; | ||
1375 | |||
1376 | id = usb_string_id(cfg->cdev); | ||
1377 | if (id < 0) | ||
1378 | return id; | ||
1379 | |||
1380 | strings_fn[STR_IO_OT].id = id; | ||
1381 | io_out_ot_desc.iTerminal = id; | ||
1382 | |||
1383 | id = usb_string_id(cfg->cdev); | ||
1384 | if (id < 0) | ||
1385 | return id; | ||
1386 | |||
1387 | strings_fn[STR_AS_OUT_ALT0].id = id; | ||
1388 | std_as_out_if0_desc.iInterface = id; | ||
1389 | |||
1390 | id = usb_string_id(cfg->cdev); | ||
1391 | if (id < 0) | ||
1392 | return id; | ||
1393 | |||
1394 | strings_fn[STR_AS_OUT_ALT1].id = id; | ||
1395 | std_as_out_if1_desc.iInterface = id; | ||
1396 | |||
1397 | id = usb_string_id(cfg->cdev); | ||
1398 | if (id < 0) | ||
1399 | return id; | ||
1400 | |||
1401 | strings_fn[STR_AS_IN_ALT0].id = id; | ||
1402 | std_as_in_if0_desc.iInterface = id; | ||
1403 | |||
1404 | id = usb_string_id(cfg->cdev); | ||
1405 | if (id < 0) | ||
1406 | return id; | ||
1407 | |||
1408 | strings_fn[STR_AS_IN_ALT1].id = id; | ||
1409 | std_as_in_if1_desc.iInterface = id; | ||
1410 | |||
1411 | agdev_g->func.name = "uac2_func"; | ||
1412 | agdev_g->func.strings = fn_strings; | ||
1413 | agdev_g->func.bind = afunc_bind; | ||
1414 | agdev_g->func.unbind = afunc_unbind; | ||
1415 | agdev_g->func.set_alt = afunc_set_alt; | ||
1416 | agdev_g->func.get_alt = afunc_get_alt; | ||
1417 | agdev_g->func.disable = afunc_disable; | ||
1418 | agdev_g->func.setup = afunc_setup; | ||
1419 | |||
1420 | /* Initialize the configurable parameters */ | ||
1421 | usb_out_it_desc.bNrChannels = num_channels(c_chmask); | ||
1422 | usb_out_it_desc.bmChannelConfig = cpu_to_le32(c_chmask); | ||
1423 | io_in_it_desc.bNrChannels = num_channels(p_chmask); | ||
1424 | io_in_it_desc.bmChannelConfig = cpu_to_le32(p_chmask); | ||
1425 | as_out_hdr_desc.bNrChannels = num_channels(c_chmask); | ||
1426 | as_out_hdr_desc.bmChannelConfig = cpu_to_le32(c_chmask); | ||
1427 | as_in_hdr_desc.bNrChannels = num_channels(p_chmask); | ||
1428 | as_in_hdr_desc.bmChannelConfig = cpu_to_le32(p_chmask); | ||
1429 | as_out_fmt1_desc.bSubslotSize = c_ssize; | ||
1430 | as_out_fmt1_desc.bBitResolution = c_ssize * 8; | ||
1431 | as_in_fmt1_desc.bSubslotSize = p_ssize; | ||
1432 | as_in_fmt1_desc.bBitResolution = p_ssize * 8; | ||
1433 | |||
1434 | snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", p_srate); | ||
1435 | snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", c_srate); | ||
1436 | |||
1437 | res = usb_add_function(cfg, &agdev_g->func); | ||
1438 | if (res < 0) | ||
1439 | kfree(agdev_g); | ||
1440 | |||
1441 | return res; | ||
1442 | } | ||
1443 | |||
1444 | static void | ||
1445 | uac2_unbind_config(struct usb_configuration *cfg) | ||
1446 | { | ||
1447 | kfree(agdev_g); | ||
1448 | agdev_g = NULL; | ||
1449 | } | ||
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index b95697c03d07..877a2c46672b 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -1638,6 +1638,7 @@ static int qe_ep_disable(struct usb_ep *_ep) | |||
1638 | /* Nuke all pending requests (does flush) */ | 1638 | /* Nuke all pending requests (does flush) */ |
1639 | nuke(ep, -ESHUTDOWN); | 1639 | nuke(ep, -ESHUTDOWN); |
1640 | ep->desc = NULL; | 1640 | ep->desc = NULL; |
1641 | ep->ep.desc = NULL; | ||
1641 | ep->stopped = 1; | 1642 | ep->stopped = 1; |
1642 | ep->tx_req = NULL; | 1643 | ep->tx_req = NULL; |
1643 | qe_ep_reset(udc, ep->epnum); | 1644 | qe_ep_reset(udc, ep->epnum); |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 1e8c0c425fa1..b30e21fdbb1b 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -659,6 +659,7 @@ static int fsl_ep_disable(struct usb_ep *_ep) | |||
659 | nuke(ep, -ESHUTDOWN); | 659 | nuke(ep, -ESHUTDOWN); |
660 | 660 | ||
661 | ep->desc = NULL; | 661 | ep->desc = NULL; |
662 | ep->ep.desc = NULL; | ||
662 | ep->stopped = 1; | 663 | ep->stopped = 1; |
663 | spin_unlock_irqrestore(&udc->lock, flags); | 664 | spin_unlock_irqrestore(&udc->lock, flags); |
664 | 665 | ||
@@ -768,7 +769,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | |||
768 | * @is_last: return flag if it is the last dTD of the request | 769 | * @is_last: return flag if it is the last dTD of the request |
769 | * return: pointer to the built dTD */ | 770 | * return: pointer to the built dTD */ |
770 | static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, | 771 | static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, |
771 | dma_addr_t *dma, int *is_last) | 772 | dma_addr_t *dma, int *is_last, gfp_t gfp_flags) |
772 | { | 773 | { |
773 | u32 swap_temp; | 774 | u32 swap_temp; |
774 | struct ep_td_struct *dtd; | 775 | struct ep_td_struct *dtd; |
@@ -777,7 +778,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, | |||
777 | *length = min(req->req.length - req->req.actual, | 778 | *length = min(req->req.length - req->req.actual, |
778 | (unsigned)EP_MAX_LENGTH_TRANSFER); | 779 | (unsigned)EP_MAX_LENGTH_TRANSFER); |
779 | 780 | ||
780 | dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma); | 781 | dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma); |
781 | if (dtd == NULL) | 782 | if (dtd == NULL) |
782 | return dtd; | 783 | return dtd; |
783 | 784 | ||
@@ -827,7 +828,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, | |||
827 | } | 828 | } |
828 | 829 | ||
829 | /* Generate dtd chain for a request */ | 830 | /* Generate dtd chain for a request */ |
830 | static int fsl_req_to_dtd(struct fsl_req *req) | 831 | static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) |
831 | { | 832 | { |
832 | unsigned count; | 833 | unsigned count; |
833 | int is_last; | 834 | int is_last; |
@@ -836,7 +837,7 @@ static int fsl_req_to_dtd(struct fsl_req *req) | |||
836 | dma_addr_t dma; | 837 | dma_addr_t dma; |
837 | 838 | ||
838 | do { | 839 | do { |
839 | dtd = fsl_build_dtd(req, &count, &dma, &is_last); | 840 | dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags); |
840 | if (dtd == NULL) | 841 | if (dtd == NULL) |
841 | return -ENOMEM; | 842 | return -ENOMEM; |
842 | 843 | ||
@@ -910,13 +911,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
910 | req->req.actual = 0; | 911 | req->req.actual = 0; |
911 | req->dtd_count = 0; | 912 | req->dtd_count = 0; |
912 | 913 | ||
913 | spin_lock_irqsave(&udc->lock, flags); | ||
914 | |||
915 | /* build dtds and push them to device queue */ | 914 | /* build dtds and push them to device queue */ |
916 | if (!fsl_req_to_dtd(req)) { | 915 | if (!fsl_req_to_dtd(req, gfp_flags)) { |
916 | spin_lock_irqsave(&udc->lock, flags); | ||
917 | fsl_queue_td(ep, req); | 917 | fsl_queue_td(ep, req); |
918 | } else { | 918 | } else { |
919 | spin_unlock_irqrestore(&udc->lock, flags); | ||
920 | return -ENOMEM; | 919 | return -ENOMEM; |
921 | } | 920 | } |
922 | 921 | ||
@@ -1295,7 +1294,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) | |||
1295 | ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 1294 | ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
1296 | req->mapped = 1; | 1295 | req->mapped = 1; |
1297 | 1296 | ||
1298 | if (fsl_req_to_dtd(req) == 0) | 1297 | if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) |
1299 | fsl_queue_td(ep, req); | 1298 | fsl_queue_td(ep, req); |
1300 | else | 1299 | else |
1301 | return -ENOMEM; | 1300 | return -ENOMEM; |
@@ -1379,7 +1378,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, | |||
1379 | req->mapped = 1; | 1378 | req->mapped = 1; |
1380 | 1379 | ||
1381 | /* prime the data phase */ | 1380 | /* prime the data phase */ |
1382 | if ((fsl_req_to_dtd(req) == 0)) | 1381 | if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) |
1383 | fsl_queue_td(ep, req); | 1382 | fsl_queue_td(ep, req); |
1384 | else /* no mem */ | 1383 | else /* no mem */ |
1385 | goto stall; | 1384 | goto stall; |
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 0519d77915ec..331cd6729d3c 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * g_ffs.c -- user mode file system API for USB composite function controllers | 2 | * g_ffs.c -- user mode file system API for USB composite function controllers |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics | 4 | * Copyright (C) 2010 Samsung Electronics |
5 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 5 | * Author: Michal Nazarewicz <mina86@mina86.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 5af70fcce139..e1dfd32dc805 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -235,6 +235,7 @@ static void ep_reset(struct goku_udc_regs __iomem *regs, struct goku_ep *ep) | |||
235 | 235 | ||
236 | ep->ep.maxpacket = MAX_FIFO_SIZE; | 236 | ep->ep.maxpacket = MAX_FIFO_SIZE; |
237 | ep->desc = NULL; | 237 | ep->desc = NULL; |
238 | ep->ep.desc = NULL; | ||
238 | ep->stopped = 1; | 239 | ep->stopped = 1; |
239 | ep->irqs = 0; | 240 | ep->irqs = 0; |
240 | ep->dma = 0; | 241 | ep->dma = 0; |
@@ -310,12 +311,9 @@ done(struct goku_ep *ep, struct goku_request *req, int status) | |||
310 | status = req->req.status; | 311 | status = req->req.status; |
311 | 312 | ||
312 | dev = ep->dev; | 313 | dev = ep->dev; |
313 | if (req->mapped) { | 314 | |
314 | pci_unmap_single(dev->pdev, req->req.dma, req->req.length, | 315 | if (ep->dma) |
315 | ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 316 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); |
316 | req->req.dma = DMA_ADDR_INVALID; | ||
317 | req->mapped = 0; | ||
318 | } | ||
319 | 317 | ||
320 | #ifndef USB_TRACE | 318 | #ifndef USB_TRACE |
321 | if (status && status != -ESHUTDOWN) | 319 | if (status && status != -ESHUTDOWN) |
@@ -736,10 +734,11 @@ goku_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
736 | return -EBUSY; | 734 | return -EBUSY; |
737 | 735 | ||
738 | /* set up dma mapping in case the caller didn't */ | 736 | /* set up dma mapping in case the caller didn't */ |
739 | if (ep->dma && _req->dma == DMA_ADDR_INVALID) { | 737 | if (ep->dma) { |
740 | _req->dma = pci_map_single(dev->pdev, _req->buf, _req->length, | 738 | status = usb_gadget_map_request(&dev->gadget, &req->req, |
741 | ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 739 | ep->is_in); |
742 | req->mapped = 1; | 740 | if (status) |
741 | return status; | ||
743 | } | 742 | } |
744 | 743 | ||
745 | #ifdef USB_TRACE | 744 | #ifdef USB_TRACE |
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 42a88b680f25..edd52d963f14 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -401,16 +401,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req, | |||
401 | dma_pool_free(dev->dtd_pool, curr_dtd, curr_dtd->dtd_dma); | 401 | dma_pool_free(dev->dtd_pool, curr_dtd, curr_dtd->dtd_dma); |
402 | } | 402 | } |
403 | 403 | ||
404 | if (req->mapped) { | 404 | usb_gadget_unmap_request(&dev->gadget, &req->req, is_in(ep)); |
405 | dma_unmap_single(&dev->pdev->dev, | ||
406 | req->req.dma, req->req.length, | ||
407 | is_in(ep) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
408 | req->req.dma = DMA_ADDR_INVALID; | ||
409 | req->mapped = 0; | ||
410 | } else | ||
411 | dma_sync_single_for_cpu(&dev->pdev->dev, req->req.dma, | ||
412 | req->req.length, | ||
413 | is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
414 | 405 | ||
415 | if (status != -ESHUTDOWN) | 406 | if (status != -ESHUTDOWN) |
416 | dev_dbg(&dev->pdev->dev, | 407 | dev_dbg(&dev->pdev->dev, |
@@ -487,6 +478,7 @@ static int langwell_ep_disable(struct usb_ep *_ep) | |||
487 | nuke(ep, -ESHUTDOWN); | 478 | nuke(ep, -ESHUTDOWN); |
488 | 479 | ||
489 | ep->desc = NULL; | 480 | ep->desc = NULL; |
481 | ep->ep.desc = NULL; | ||
490 | ep->stopped = 1; | 482 | ep->stopped = 1; |
491 | 483 | ||
492 | spin_unlock_irqrestore(&dev->lock, flags); | 484 | spin_unlock_irqrestore(&dev->lock, flags); |
@@ -749,7 +741,8 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
749 | struct langwell_ep *ep; | 741 | struct langwell_ep *ep; |
750 | struct langwell_udc *dev; | 742 | struct langwell_udc *dev; |
751 | unsigned long flags; | 743 | unsigned long flags; |
752 | int is_iso = 0, zlflag = 0; | 744 | int is_iso = 0; |
745 | int ret; | ||
753 | 746 | ||
754 | /* always require a cpu-view buffer */ | 747 | /* always require a cpu-view buffer */ |
755 | req = container_of(_req, struct langwell_request, req); | 748 | req = container_of(_req, struct langwell_request, req); |
@@ -776,33 +769,10 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
776 | if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) | 769 | if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) |
777 | return -ESHUTDOWN; | 770 | return -ESHUTDOWN; |
778 | 771 | ||
779 | /* set up dma mapping in case the caller didn't */ | 772 | /* set up dma mapping */ |
780 | if (_req->dma == DMA_ADDR_INVALID) { | 773 | ret = usb_gadget_map_request(&dev->gadget, &req->req, is_in(ep)); |
781 | /* WORKAROUND: WARN_ON(size == 0) */ | 774 | if (ret) |
782 | if (_req->length == 0) { | 775 | return ret; |
783 | dev_vdbg(&dev->pdev->dev, "req->length: 0->1\n"); | ||
784 | zlflag = 1; | ||
785 | _req->length++; | ||
786 | } | ||
787 | |||
788 | _req->dma = dma_map_single(&dev->pdev->dev, | ||
789 | _req->buf, _req->length, | ||
790 | is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
791 | if (zlflag && (_req->length == 1)) { | ||
792 | dev_vdbg(&dev->pdev->dev, "req->length: 1->0\n"); | ||
793 | zlflag = 0; | ||
794 | _req->length = 0; | ||
795 | } | ||
796 | |||
797 | req->mapped = 1; | ||
798 | dev_vdbg(&dev->pdev->dev, "req->mapped = 1\n"); | ||
799 | } else { | ||
800 | dma_sync_single_for_device(&dev->pdev->dev, | ||
801 | _req->dma, _req->length, | ||
802 | is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
803 | req->mapped = 0; | ||
804 | dev_vdbg(&dev->pdev->dev, "req->mapped = 0\n"); | ||
805 | } | ||
806 | 776 | ||
807 | dev_dbg(&dev->pdev->dev, | 777 | dev_dbg(&dev->pdev->dev, |
808 | "%s queue req %p, len %u, buf %p, dma 0x%08x\n", | 778 | "%s queue req %p, len %u, buf %p, dma 0x%08x\n", |
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index e24f72f82a47..1f376eba31f6 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2003-2008 Alan Stern | 4 | * Copyright (C) 2003-2008 Alan Stern |
5 | * Copyright (C) 2009 Samsung Electronics | 5 | * Copyright (C) 2009 Samsung Electronics |
6 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 6 | * Author: Michal Nazarewicz <mina86@mina86.com> |
7 | * All rights reserved. | 7 | * All rights reserved. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 7e7f515b8b19..c37fb33a3d1b 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2008 David Brownell | 4 | * Copyright (C) 2008 David Brownell |
5 | * Copyright (C) 2008 Nokia Corporation | 5 | * Copyright (C) 2008 Nokia Corporation |
6 | * Copyright (C) 2009 Samsung Electronics | 6 | * Copyright (C) 2009 Samsung Electronics |
7 | * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) | 7 | * Author: Michal Nazarewicz (mina86@mina86.com) |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 7369fd92c03f..19bbe80c2f8c 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c | |||
@@ -608,6 +608,7 @@ static int mv_ep_disable(struct usb_ep *_ep) | |||
608 | nuke(ep, -ESHUTDOWN); | 608 | nuke(ep, -ESHUTDOWN); |
609 | 609 | ||
610 | ep->desc = NULL; | 610 | ep->desc = NULL; |
611 | ep->ep.desc = NULL; | ||
611 | ep->stopped = 1; | 612 | ep->stopped = 1; |
612 | 613 | ||
613 | spin_unlock_irqrestore(&udc->lock, flags); | 614 | spin_unlock_irqrestore(&udc->lock, flags); |
@@ -771,8 +772,7 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
771 | udc->ep0_state = DATA_STATE_XMIT; | 772 | udc->ep0_state = DATA_STATE_XMIT; |
772 | 773 | ||
773 | /* irq handler advances the queue */ | 774 | /* irq handler advances the queue */ |
774 | if (req != NULL) | 775 | list_add_tail(&req->queue, &ep->queue); |
775 | list_add_tail(&req->queue, &ep->queue); | ||
776 | spin_unlock_irqrestore(&udc->lock, flags); | 776 | spin_unlock_irqrestore(&udc->lock, flags); |
777 | 777 | ||
778 | return 0; | 778 | return 0; |
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 7322d293213e..01ae56f47174 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c | |||
@@ -385,12 +385,9 @@ net2272_done(struct net2272_ep *ep, struct net2272_request *req, int status) | |||
385 | status = req->req.status; | 385 | status = req->req.status; |
386 | 386 | ||
387 | dev = ep->dev; | 387 | dev = ep->dev; |
388 | if (use_dma && req->mapped) { | 388 | if (use_dma && ep->dma) |
389 | dma_unmap_single(dev->dev, req->req.dma, req->req.length, | 389 | usb_gadget_unmap_request(&dev->gadget, &req->req, |
390 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 390 | ep->is_in); |
391 | req->req.dma = DMA_ADDR_INVALID; | ||
392 | req->mapped = 0; | ||
393 | } | ||
394 | 391 | ||
395 | if (status && status != -ESHUTDOWN) | 392 | if (status && status != -ESHUTDOWN) |
396 | dev_vdbg(dev->dev, "complete %s req %p stat %d len %u/%u buf %p\n", | 393 | dev_vdbg(dev->dev, "complete %s req %p stat %d len %u/%u buf %p\n", |
@@ -850,10 +847,11 @@ net2272_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
850 | return -ESHUTDOWN; | 847 | return -ESHUTDOWN; |
851 | 848 | ||
852 | /* set up dma mapping in case the caller didn't */ | 849 | /* set up dma mapping in case the caller didn't */ |
853 | if (use_dma && ep->dma && _req->dma == DMA_ADDR_INVALID) { | 850 | if (use_dma && ep->dma) { |
854 | _req->dma = dma_map_single(dev->dev, _req->buf, _req->length, | 851 | status = usb_gadget_map_request(&dev->gadget, _req, |
855 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 852 | ep->is_in); |
856 | req->mapped = 1; | 853 | if (status) |
854 | return status; | ||
857 | } | 855 | } |
858 | 856 | ||
859 | dev_vdbg(dev->dev, "%s queue req %p, len %d buf %p dma %08llx %s\n", | 857 | dev_vdbg(dev->dev, "%s queue req %p, len %d buf %p dma %08llx %s\n", |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index cdedd1336745..a5ccabc37f30 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -806,12 +806,8 @@ done (struct net2280_ep *ep, struct net2280_request *req, int status) | |||
806 | status = req->req.status; | 806 | status = req->req.status; |
807 | 807 | ||
808 | dev = ep->dev; | 808 | dev = ep->dev; |
809 | if (req->mapped) { | 809 | if (ep->dma) |
810 | pci_unmap_single (dev->pdev, req->req.dma, req->req.length, | 810 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); |
811 | ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
812 | req->req.dma = DMA_ADDR_INVALID; | ||
813 | req->mapped = 0; | ||
814 | } | ||
815 | 811 | ||
816 | if (status && status != -ESHUTDOWN) | 812 | if (status && status != -ESHUTDOWN) |
817 | VDEBUG (dev, "complete %s req %p stat %d len %u/%u\n", | 813 | VDEBUG (dev, "complete %s req %p stat %d len %u/%u\n", |
@@ -857,10 +853,13 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
857 | return -EOPNOTSUPP; | 853 | return -EOPNOTSUPP; |
858 | 854 | ||
859 | /* set up dma mapping in case the caller didn't */ | 855 | /* set up dma mapping in case the caller didn't */ |
860 | if (ep->dma && _req->dma == DMA_ADDR_INVALID) { | 856 | if (ep->dma) { |
861 | _req->dma = pci_map_single (dev->pdev, _req->buf, _req->length, | 857 | int ret; |
862 | ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 858 | |
863 | req->mapped = 1; | 859 | ret = usb_gadget_map_request(&dev->gadget, _req, |
860 | ep->is_in); | ||
861 | if (ret) | ||
862 | return ret; | ||
864 | } | 863 | } |
865 | 864 | ||
866 | #if 0 | 865 | #if 0 |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index ace8a652b32b..b44830df593e 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -251,6 +251,7 @@ static int omap_ep_disable(struct usb_ep *_ep) | |||
251 | 251 | ||
252 | spin_lock_irqsave(&ep->udc->lock, flags); | 252 | spin_lock_irqsave(&ep->udc->lock, flags); |
253 | ep->desc = NULL; | 253 | ep->desc = NULL; |
254 | ep->ep.desc = NULL; | ||
254 | nuke (ep, -ESHUTDOWN); | 255 | nuke (ep, -ESHUTDOWN); |
255 | ep->ep.maxpacket = ep->maxpacket; | 256 | ep->ep.maxpacket = ep->maxpacket; |
256 | ep->has_dma = 0; | 257 | ep->has_dma = 0; |
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index a3fcaae4bc2a..350dbcd90681 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -15,6 +15,13 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/usb/ch9.h> | 16 | #include <linux/usb/ch9.h> |
17 | #include <linux/usb/gadget.h> | 17 | #include <linux/usb/gadget.h> |
18 | #include <linux/gpio.h> | ||
19 | |||
20 | /* GPIO port for VBUS detecting */ | ||
21 | static int vbus_gpio_port = -1; /* GPIO port number (-1:Not used) */ | ||
22 | |||
23 | #define PCH_VBUS_PERIOD 3000 /* VBUS polling period (msec) */ | ||
24 | #define PCH_VBUS_INTERVAL 10 /* VBUS polling interval (msec) */ | ||
18 | 25 | ||
19 | /* Address offset of Registers */ | 26 | /* Address offset of Registers */ |
20 | #define UDC_EP_REG_SHIFT 0x20 /* Offset to next EP */ | 27 | #define UDC_EP_REG_SHIFT 0x20 /* Offset to next EP */ |
@@ -296,6 +303,21 @@ struct pch_udc_ep { | |||
296 | }; | 303 | }; |
297 | 304 | ||
298 | /** | 305 | /** |
306 | * struct pch_vbus_gpio_data - Structure holding GPIO informaton | ||
307 | * for detecting VBUS | ||
308 | * @port: gpio port number | ||
309 | * @intr: gpio interrupt number | ||
310 | * @irq_work_fall Structure for WorkQueue | ||
311 | * @irq_work_rise Structure for WorkQueue | ||
312 | */ | ||
313 | struct pch_vbus_gpio_data { | ||
314 | int port; | ||
315 | int intr; | ||
316 | struct work_struct irq_work_fall; | ||
317 | struct work_struct irq_work_rise; | ||
318 | }; | ||
319 | |||
320 | /** | ||
299 | * struct pch_udc_dev - Structure holding complete information | 321 | * struct pch_udc_dev - Structure holding complete information |
300 | * of the PCH USB device | 322 | * of the PCH USB device |
301 | * @gadget: gadget driver data | 323 | * @gadget: gadget driver data |
@@ -311,6 +333,7 @@ struct pch_udc_ep { | |||
311 | * @registered: driver regsitered with system | 333 | * @registered: driver regsitered with system |
312 | * @suspended: driver in suspended state | 334 | * @suspended: driver in suspended state |
313 | * @connected: gadget driver associated | 335 | * @connected: gadget driver associated |
336 | * @vbus_session: required vbus_session state | ||
314 | * @set_cfg_not_acked: pending acknowledgement 4 setup | 337 | * @set_cfg_not_acked: pending acknowledgement 4 setup |
315 | * @waiting_zlp_ack: pending acknowledgement 4 ZLP | 338 | * @waiting_zlp_ack: pending acknowledgement 4 ZLP |
316 | * @data_requests: DMA pool for data requests | 339 | * @data_requests: DMA pool for data requests |
@@ -322,6 +345,7 @@ struct pch_udc_ep { | |||
322 | * @base_addr: for mapped device memory | 345 | * @base_addr: for mapped device memory |
323 | * @irq: IRQ line for the device | 346 | * @irq: IRQ line for the device |
324 | * @cfg_data: current cfg, intf, and alt in use | 347 | * @cfg_data: current cfg, intf, and alt in use |
348 | * @vbus_gpio: GPIO informaton for detecting VBUS | ||
325 | */ | 349 | */ |
326 | struct pch_udc_dev { | 350 | struct pch_udc_dev { |
327 | struct usb_gadget gadget; | 351 | struct usb_gadget gadget; |
@@ -337,6 +361,7 @@ struct pch_udc_dev { | |||
337 | registered:1, | 361 | registered:1, |
338 | suspended:1, | 362 | suspended:1, |
339 | connected:1, | 363 | connected:1, |
364 | vbus_session:1, | ||
340 | set_cfg_not_acked:1, | 365 | set_cfg_not_acked:1, |
341 | waiting_zlp_ack:1; | 366 | waiting_zlp_ack:1; |
342 | struct pci_pool *data_requests; | 367 | struct pci_pool *data_requests; |
@@ -347,7 +372,8 @@ struct pch_udc_dev { | |||
347 | unsigned long phys_addr; | 372 | unsigned long phys_addr; |
348 | void __iomem *base_addr; | 373 | void __iomem *base_addr; |
349 | unsigned irq; | 374 | unsigned irq; |
350 | struct pch_udc_cfg_data cfg_data; | 375 | struct pch_udc_cfg_data cfg_data; |
376 | struct pch_vbus_gpio_data vbus_gpio; | ||
351 | }; | 377 | }; |
352 | 378 | ||
353 | #define PCH_UDC_PCI_BAR 1 | 379 | #define PCH_UDC_PCI_BAR 1 |
@@ -554,6 +580,29 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) | |||
554 | } | 580 | } |
555 | 581 | ||
556 | /** | 582 | /** |
583 | * pch_udc_reconnect() - This API initializes usb device controller, | ||
584 | * and clear the disconnect status. | ||
585 | * @dev: Reference to pch_udc_regs structure | ||
586 | */ | ||
587 | static void pch_udc_init(struct pch_udc_dev *dev); | ||
588 | static void pch_udc_reconnect(struct pch_udc_dev *dev) | ||
589 | { | ||
590 | pch_udc_init(dev); | ||
591 | |||
592 | /* enable device interrupts */ | ||
593 | /* pch_udc_enable_interrupts() */ | ||
594 | pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, | ||
595 | UDC_DEVINT_UR | UDC_DEVINT_ENUM); | ||
596 | |||
597 | /* Clear the disconnect */ | ||
598 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); | ||
599 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD); | ||
600 | mdelay(1); | ||
601 | /* Resume USB signalling */ | ||
602 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); | ||
603 | } | ||
604 | |||
605 | /** | ||
557 | * pch_udc_vbus_session() - set or clearr the disconnect status. | 606 | * pch_udc_vbus_session() - set or clearr the disconnect status. |
558 | * @dev: Reference to pch_udc_regs structure | 607 | * @dev: Reference to pch_udc_regs structure |
559 | * @is_active: Parameter specifying the action | 608 | * @is_active: Parameter specifying the action |
@@ -563,10 +612,18 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) | |||
563 | static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, | 612 | static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, |
564 | int is_active) | 613 | int is_active) |
565 | { | 614 | { |
566 | if (is_active) | 615 | if (is_active) { |
567 | pch_udc_clear_disconnect(dev); | 616 | pch_udc_reconnect(dev); |
568 | else | 617 | dev->vbus_session = 1; |
618 | } else { | ||
619 | if (dev->driver && dev->driver->disconnect) { | ||
620 | spin_unlock(&dev->lock); | ||
621 | dev->driver->disconnect(&dev->gadget); | ||
622 | spin_lock(&dev->lock); | ||
623 | } | ||
569 | pch_udc_set_disconnect(dev); | 624 | pch_udc_set_disconnect(dev); |
625 | dev->vbus_session = 0; | ||
626 | } | ||
570 | } | 627 | } |
571 | 628 | ||
572 | /** | 629 | /** |
@@ -1126,7 +1183,17 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) | |||
1126 | if (!gadget) | 1183 | if (!gadget) |
1127 | return -EINVAL; | 1184 | return -EINVAL; |
1128 | dev = container_of(gadget, struct pch_udc_dev, gadget); | 1185 | dev = container_of(gadget, struct pch_udc_dev, gadget); |
1129 | pch_udc_vbus_session(dev, is_on); | 1186 | if (is_on) { |
1187 | pch_udc_reconnect(dev); | ||
1188 | } else { | ||
1189 | if (dev->driver && dev->driver->disconnect) { | ||
1190 | spin_unlock(&dev->lock); | ||
1191 | dev->driver->disconnect(&dev->gadget); | ||
1192 | spin_lock(&dev->lock); | ||
1193 | } | ||
1194 | pch_udc_set_disconnect(dev); | ||
1195 | } | ||
1196 | |||
1130 | return 0; | 1197 | return 0; |
1131 | } | 1198 | } |
1132 | 1199 | ||
@@ -1183,6 +1250,188 @@ static const struct usb_gadget_ops pch_udc_ops = { | |||
1183 | }; | 1250 | }; |
1184 | 1251 | ||
1185 | /** | 1252 | /** |
1253 | * pch_vbus_gpio_get_value() - This API gets value of GPIO port as VBUS status. | ||
1254 | * @dev: Reference to the driver structure | ||
1255 | * | ||
1256 | * Return value: | ||
1257 | * 1: VBUS is high | ||
1258 | * 0: VBUS is low | ||
1259 | * -1: It is not enable to detect VBUS using GPIO | ||
1260 | */ | ||
1261 | static int pch_vbus_gpio_get_value(struct pch_udc_dev *dev) | ||
1262 | { | ||
1263 | int vbus = 0; | ||
1264 | |||
1265 | if (dev->vbus_gpio.port) | ||
1266 | vbus = gpio_get_value(dev->vbus_gpio.port) ? 1 : 0; | ||
1267 | else | ||
1268 | vbus = -1; | ||
1269 | |||
1270 | return vbus; | ||
1271 | } | ||
1272 | |||
1273 | /** | ||
1274 | * pch_vbus_gpio_work_fall() - This API keeps watch on VBUS becoming Low. | ||
1275 | * If VBUS is Low, disconnect is processed | ||
1276 | * @irq_work: Structure for WorkQueue | ||
1277 | * | ||
1278 | */ | ||
1279 | static void pch_vbus_gpio_work_fall(struct work_struct *irq_work) | ||
1280 | { | ||
1281 | struct pch_vbus_gpio_data *vbus_gpio = container_of(irq_work, | ||
1282 | struct pch_vbus_gpio_data, irq_work_fall); | ||
1283 | struct pch_udc_dev *dev = | ||
1284 | container_of(vbus_gpio, struct pch_udc_dev, vbus_gpio); | ||
1285 | int vbus_saved = -1; | ||
1286 | int vbus; | ||
1287 | int count; | ||
1288 | |||
1289 | if (!dev->vbus_gpio.port) | ||
1290 | return; | ||
1291 | |||
1292 | for (count = 0; count < (PCH_VBUS_PERIOD / PCH_VBUS_INTERVAL); | ||
1293 | count++) { | ||
1294 | vbus = pch_vbus_gpio_get_value(dev); | ||
1295 | |||
1296 | if ((vbus_saved == vbus) && (vbus == 0)) { | ||
1297 | dev_dbg(&dev->pdev->dev, "VBUS fell"); | ||
1298 | if (dev->driver | ||
1299 | && dev->driver->disconnect) { | ||
1300 | dev->driver->disconnect( | ||
1301 | &dev->gadget); | ||
1302 | } | ||
1303 | if (dev->vbus_gpio.intr) | ||
1304 | pch_udc_init(dev); | ||
1305 | else | ||
1306 | pch_udc_reconnect(dev); | ||
1307 | return; | ||
1308 | } | ||
1309 | vbus_saved = vbus; | ||
1310 | mdelay(PCH_VBUS_INTERVAL); | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | /** | ||
1315 | * pch_vbus_gpio_work_rise() - This API checks VBUS is High. | ||
1316 | * If VBUS is High, connect is processed | ||
1317 | * @irq_work: Structure for WorkQueue | ||
1318 | * | ||
1319 | */ | ||
1320 | static void pch_vbus_gpio_work_rise(struct work_struct *irq_work) | ||
1321 | { | ||
1322 | struct pch_vbus_gpio_data *vbus_gpio = container_of(irq_work, | ||
1323 | struct pch_vbus_gpio_data, irq_work_rise); | ||
1324 | struct pch_udc_dev *dev = | ||
1325 | container_of(vbus_gpio, struct pch_udc_dev, vbus_gpio); | ||
1326 | int vbus; | ||
1327 | |||
1328 | if (!dev->vbus_gpio.port) | ||
1329 | return; | ||
1330 | |||
1331 | mdelay(PCH_VBUS_INTERVAL); | ||
1332 | vbus = pch_vbus_gpio_get_value(dev); | ||
1333 | |||
1334 | if (vbus == 1) { | ||
1335 | dev_dbg(&dev->pdev->dev, "VBUS rose"); | ||
1336 | pch_udc_reconnect(dev); | ||
1337 | return; | ||
1338 | } | ||
1339 | } | ||
1340 | |||
1341 | /** | ||
1342 | * pch_vbus_gpio_irq() - IRQ handler for GPIO intrerrupt for changing VBUS | ||
1343 | * @irq: Interrupt request number | ||
1344 | * @dev: Reference to the device structure | ||
1345 | * | ||
1346 | * Return codes: | ||
1347 | * 0: Success | ||
1348 | * -EINVAL: GPIO port is invalid or can't be initialized. | ||
1349 | */ | ||
1350 | static irqreturn_t pch_vbus_gpio_irq(int irq, void *data) | ||
1351 | { | ||
1352 | struct pch_udc_dev *dev = (struct pch_udc_dev *)data; | ||
1353 | |||
1354 | if (!dev->vbus_gpio.port || !dev->vbus_gpio.intr) | ||
1355 | return IRQ_NONE; | ||
1356 | |||
1357 | if (pch_vbus_gpio_get_value(dev)) | ||
1358 | schedule_work(&dev->vbus_gpio.irq_work_rise); | ||
1359 | else | ||
1360 | schedule_work(&dev->vbus_gpio.irq_work_fall); | ||
1361 | |||
1362 | return IRQ_HANDLED; | ||
1363 | } | ||
1364 | |||
1365 | /** | ||
1366 | * pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS. | ||
1367 | * @dev: Reference to the driver structure | ||
1368 | * @vbus_gpio Number of GPIO port to detect gpio | ||
1369 | * | ||
1370 | * Return codes: | ||
1371 | * 0: Success | ||
1372 | * -EINVAL: GPIO port is invalid or can't be initialized. | ||
1373 | */ | ||
1374 | static int pch_vbus_gpio_init(struct pch_udc_dev *dev, int vbus_gpio_port) | ||
1375 | { | ||
1376 | int err; | ||
1377 | int irq_num = 0; | ||
1378 | |||
1379 | dev->vbus_gpio.port = 0; | ||
1380 | dev->vbus_gpio.intr = 0; | ||
1381 | |||
1382 | if (vbus_gpio_port <= -1) | ||
1383 | return -EINVAL; | ||
1384 | |||
1385 | err = gpio_is_valid(vbus_gpio_port); | ||
1386 | if (!err) { | ||
1387 | pr_err("%s: gpio port %d is invalid\n", | ||
1388 | __func__, vbus_gpio_port); | ||
1389 | return -EINVAL; | ||
1390 | } | ||
1391 | |||
1392 | err = gpio_request(vbus_gpio_port, "pch_vbus"); | ||
1393 | if (err) { | ||
1394 | pr_err("%s: can't request gpio port %d, err: %d\n", | ||
1395 | __func__, vbus_gpio_port, err); | ||
1396 | return -EINVAL; | ||
1397 | } | ||
1398 | |||
1399 | dev->vbus_gpio.port = vbus_gpio_port; | ||
1400 | gpio_direction_input(vbus_gpio_port); | ||
1401 | INIT_WORK(&dev->vbus_gpio.irq_work_fall, pch_vbus_gpio_work_fall); | ||
1402 | |||
1403 | irq_num = gpio_to_irq(vbus_gpio_port); | ||
1404 | if (irq_num > 0) { | ||
1405 | irq_set_irq_type(irq_num, IRQ_TYPE_EDGE_BOTH); | ||
1406 | err = request_irq(irq_num, pch_vbus_gpio_irq, 0, | ||
1407 | "vbus_detect", dev); | ||
1408 | if (!err) { | ||
1409 | dev->vbus_gpio.intr = irq_num; | ||
1410 | INIT_WORK(&dev->vbus_gpio.irq_work_rise, | ||
1411 | pch_vbus_gpio_work_rise); | ||
1412 | } else { | ||
1413 | pr_err("%s: can't request irq %d, err: %d\n", | ||
1414 | __func__, irq_num, err); | ||
1415 | } | ||
1416 | } | ||
1417 | |||
1418 | return 0; | ||
1419 | } | ||
1420 | |||
1421 | /** | ||
1422 | * pch_vbus_gpio_free() - This API frees resources of GPIO port | ||
1423 | * @dev: Reference to the driver structure | ||
1424 | */ | ||
1425 | static void pch_vbus_gpio_free(struct pch_udc_dev *dev) | ||
1426 | { | ||
1427 | if (dev->vbus_gpio.intr) | ||
1428 | free_irq(dev->vbus_gpio.intr, dev); | ||
1429 | |||
1430 | if (dev->vbus_gpio.port) | ||
1431 | gpio_free(dev->vbus_gpio.port); | ||
1432 | } | ||
1433 | |||
1434 | /** | ||
1186 | * complete_req() - This API is invoked from the driver when processing | 1435 | * complete_req() - This API is invoked from the driver when processing |
1187 | * of a request is complete | 1436 | * of a request is complete |
1188 | * @ep: Reference to the endpoint structure | 1437 | * @ep: Reference to the endpoint structure |
@@ -1493,6 +1742,7 @@ static int pch_udc_pcd_ep_disable(struct usb_ep *usbep) | |||
1493 | pch_udc_ep_disable(ep); | 1742 | pch_udc_ep_disable(ep); |
1494 | pch_udc_disable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); | 1743 | pch_udc_disable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); |
1495 | ep->desc = NULL; | 1744 | ep->desc = NULL; |
1745 | ep->ep.desc = NULL; | ||
1496 | INIT_LIST_HEAD(&ep->queue); | 1746 | INIT_LIST_HEAD(&ep->queue); |
1497 | spin_unlock_irqrestore(&ep->dev->lock, iflags); | 1747 | spin_unlock_irqrestore(&ep->dev->lock, iflags); |
1498 | return 0; | 1748 | return 0; |
@@ -2335,8 +2585,11 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) | |||
2335 | /* Complete request queue */ | 2585 | /* Complete request queue */ |
2336 | empty_req_queue(ep); | 2586 | empty_req_queue(ep); |
2337 | } | 2587 | } |
2338 | if (dev->driver && dev->driver->disconnect) | 2588 | if (dev->driver && dev->driver->disconnect) { |
2589 | spin_unlock(&dev->lock); | ||
2339 | dev->driver->disconnect(&dev->gadget); | 2590 | dev->driver->disconnect(&dev->gadget); |
2591 | spin_lock(&dev->lock); | ||
2592 | } | ||
2340 | } | 2593 | } |
2341 | 2594 | ||
2342 | /** | 2595 | /** |
@@ -2371,6 +2624,11 @@ static void pch_udc_svc_enum_interrupt(struct pch_udc_dev *dev) | |||
2371 | pch_udc_set_dma(dev, DMA_DIR_TX); | 2624 | pch_udc_set_dma(dev, DMA_DIR_TX); |
2372 | pch_udc_set_dma(dev, DMA_DIR_RX); | 2625 | pch_udc_set_dma(dev, DMA_DIR_RX); |
2373 | pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX])); | 2626 | pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX])); |
2627 | |||
2628 | /* enable device interrupts */ | ||
2629 | pch_udc_enable_interrupts(dev, UDC_DEVINT_UR | UDC_DEVINT_US | | ||
2630 | UDC_DEVINT_ES | UDC_DEVINT_ENUM | | ||
2631 | UDC_DEVINT_SI | UDC_DEVINT_SC); | ||
2374 | } | 2632 | } |
2375 | 2633 | ||
2376 | /** | 2634 | /** |
@@ -2459,12 +2717,18 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) | |||
2459 | */ | 2717 | */ |
2460 | static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) | 2718 | static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) |
2461 | { | 2719 | { |
2720 | int vbus; | ||
2721 | |||
2462 | /* USB Reset Interrupt */ | 2722 | /* USB Reset Interrupt */ |
2463 | if (dev_intr & UDC_DEVINT_UR) | 2723 | if (dev_intr & UDC_DEVINT_UR) { |
2464 | pch_udc_svc_ur_interrupt(dev); | 2724 | pch_udc_svc_ur_interrupt(dev); |
2725 | dev_dbg(&dev->pdev->dev, "USB_RESET\n"); | ||
2726 | } | ||
2465 | /* Enumeration Done Interrupt */ | 2727 | /* Enumeration Done Interrupt */ |
2466 | if (dev_intr & UDC_DEVINT_ENUM) | 2728 | if (dev_intr & UDC_DEVINT_ENUM) { |
2467 | pch_udc_svc_enum_interrupt(dev); | 2729 | pch_udc_svc_enum_interrupt(dev); |
2730 | dev_dbg(&dev->pdev->dev, "USB_ENUM\n"); | ||
2731 | } | ||
2468 | /* Set Interface Interrupt */ | 2732 | /* Set Interface Interrupt */ |
2469 | if (dev_intr & UDC_DEVINT_SI) | 2733 | if (dev_intr & UDC_DEVINT_SI) |
2470 | pch_udc_svc_intf_interrupt(dev); | 2734 | pch_udc_svc_intf_interrupt(dev); |
@@ -2472,8 +2736,30 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) | |||
2472 | if (dev_intr & UDC_DEVINT_SC) | 2736 | if (dev_intr & UDC_DEVINT_SC) |
2473 | pch_udc_svc_cfg_interrupt(dev); | 2737 | pch_udc_svc_cfg_interrupt(dev); |
2474 | /* USB Suspend interrupt */ | 2738 | /* USB Suspend interrupt */ |
2475 | if (dev_intr & UDC_DEVINT_US) | 2739 | if (dev_intr & UDC_DEVINT_US) { |
2740 | if (dev->driver | ||
2741 | && dev->driver->suspend) { | ||
2742 | spin_unlock(&dev->lock); | ||
2743 | dev->driver->suspend(&dev->gadget); | ||
2744 | spin_lock(&dev->lock); | ||
2745 | } | ||
2746 | |||
2747 | vbus = pch_vbus_gpio_get_value(dev); | ||
2748 | if ((dev->vbus_session == 0) | ||
2749 | && (vbus != 1)) { | ||
2750 | if (dev->driver && dev->driver->disconnect) { | ||
2751 | spin_unlock(&dev->lock); | ||
2752 | dev->driver->disconnect(&dev->gadget); | ||
2753 | spin_lock(&dev->lock); | ||
2754 | } | ||
2755 | pch_udc_reconnect(dev); | ||
2756 | } else if ((dev->vbus_session == 0) | ||
2757 | && (vbus == 1) | ||
2758 | && !dev->vbus_gpio.intr) | ||
2759 | schedule_work(&dev->vbus_gpio.irq_work_fall); | ||
2760 | |||
2476 | dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); | 2761 | dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); |
2762 | } | ||
2477 | /* Clear the SOF interrupt, if enabled */ | 2763 | /* Clear the SOF interrupt, if enabled */ |
2478 | if (dev_intr & UDC_DEVINT_SOF) | 2764 | if (dev_intr & UDC_DEVINT_SOF) |
2479 | dev_dbg(&dev->pdev->dev, "SOF\n"); | 2765 | dev_dbg(&dev->pdev->dev, "SOF\n"); |
@@ -2499,6 +2785,14 @@ static irqreturn_t pch_udc_isr(int irq, void *pdev) | |||
2499 | dev_intr = pch_udc_read_device_interrupts(dev); | 2785 | dev_intr = pch_udc_read_device_interrupts(dev); |
2500 | ep_intr = pch_udc_read_ep_interrupts(dev); | 2786 | ep_intr = pch_udc_read_ep_interrupts(dev); |
2501 | 2787 | ||
2788 | /* For a hot plug, this find that the controller is hung up. */ | ||
2789 | if (dev_intr == ep_intr) | ||
2790 | if (dev_intr == pch_udc_readl(dev, UDC_DEVCFG_ADDR)) { | ||
2791 | dev_dbg(&dev->pdev->dev, "UDC: Hung up\n"); | ||
2792 | /* The controller is reset */ | ||
2793 | pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR); | ||
2794 | return IRQ_HANDLED; | ||
2795 | } | ||
2502 | if (dev_intr) | 2796 | if (dev_intr) |
2503 | /* Clear device interrupts */ | 2797 | /* Clear device interrupts */ |
2504 | pch_udc_write_device_interrupts(dev, dev_intr); | 2798 | pch_udc_write_device_interrupts(dev, dev_intr); |
@@ -2625,6 +2919,7 @@ static int pch_udc_pcd_init(struct pch_udc_dev *dev) | |||
2625 | { | 2919 | { |
2626 | pch_udc_init(dev); | 2920 | pch_udc_init(dev); |
2627 | pch_udc_pcd_reinit(dev); | 2921 | pch_udc_pcd_reinit(dev); |
2922 | pch_vbus_gpio_init(dev, vbus_gpio_port); | ||
2628 | return 0; | 2923 | return 0; |
2629 | } | 2924 | } |
2630 | 2925 | ||
@@ -2725,7 +3020,8 @@ static int pch_udc_start(struct usb_gadget_driver *driver, | |||
2725 | pch_udc_setup_ep0(dev); | 3020 | pch_udc_setup_ep0(dev); |
2726 | 3021 | ||
2727 | /* clear SD */ | 3022 | /* clear SD */ |
2728 | pch_udc_clear_disconnect(dev); | 3023 | if ((pch_vbus_gpio_get_value(dev) != 0) || !dev->vbus_gpio.intr) |
3024 | pch_udc_clear_disconnect(dev); | ||
2729 | 3025 | ||
2730 | dev->connected = 1; | 3026 | dev->connected = 1; |
2731 | return 0; | 3027 | return 0; |
@@ -2803,6 +3099,8 @@ static void pch_udc_remove(struct pci_dev *pdev) | |||
2803 | UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE); | 3099 | UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE); |
2804 | kfree(dev->ep0out_buf); | 3100 | kfree(dev->ep0out_buf); |
2805 | 3101 | ||
3102 | pch_vbus_gpio_free(dev); | ||
3103 | |||
2806 | pch_udc_exit(dev); | 3104 | pch_udc_exit(dev); |
2807 | 3105 | ||
2808 | if (dev->irq_registered) | 3106 | if (dev->irq_registered) |
@@ -2912,8 +3210,10 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
2912 | } | 3210 | } |
2913 | pch_udc = dev; | 3211 | pch_udc = dev; |
2914 | /* initialize the hardware */ | 3212 | /* initialize the hardware */ |
2915 | if (pch_udc_pcd_init(dev)) | 3213 | if (pch_udc_pcd_init(dev)) { |
3214 | retval = -ENODEV; | ||
2916 | goto finished; | 3215 | goto finished; |
3216 | } | ||
2917 | if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME, | 3217 | if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME, |
2918 | dev)) { | 3218 | dev)) { |
2919 | dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__, | 3219 | dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__, |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index df681b5cd695..1b33634f2736 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -283,6 +283,7 @@ static int pxa25x_ep_disable (struct usb_ep *_ep) | |||
283 | pxa25x_ep_fifo_flush (_ep); | 283 | pxa25x_ep_fifo_flush (_ep); |
284 | 284 | ||
285 | ep->desc = NULL; | 285 | ep->desc = NULL; |
286 | ep->ep.desc = NULL; | ||
286 | ep->stopped = 1; | 287 | ep->stopped = 1; |
287 | 288 | ||
288 | local_irq_restore(flags); | 289 | local_irq_restore(flags); |
@@ -1192,6 +1193,7 @@ static void udc_reinit(struct pxa25x_udc *dev) | |||
1192 | list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); | 1193 | list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); |
1193 | 1194 | ||
1194 | ep->desc = NULL; | 1195 | ep->desc = NULL; |
1196 | ep->ep.desc = NULL; | ||
1195 | ep->stopped = 0; | 1197 | ep->stopped = 0; |
1196 | INIT_LIST_HEAD (&ep->queue); | 1198 | INIT_LIST_HEAD (&ep->queue); |
1197 | ep->pio_irqs = 0; | 1199 | ep->pio_irqs = 0; |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index f5b8d215e1d5..c4401e7dd3a6 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -663,11 +663,7 @@ static int sudmac_alloc_channel(struct r8a66597 *r8a66597, | |||
663 | ep->fifoctr = D0FIFOCTR; | 663 | ep->fifoctr = D0FIFOCTR; |
664 | 664 | ||
665 | /* dma mapping */ | 665 | /* dma mapping */ |
666 | req->req.dma = dma_map_single(r8a66597_to_dev(ep->r8a66597), | 666 | return usb_gadget_map_request(&r8a66597->gadget, &req->req, dma->dir); |
667 | req->req.buf, req->req.length, | ||
668 | dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
669 | |||
670 | return 0; | ||
671 | } | 667 | } |
672 | 668 | ||
673 | static void sudmac_free_channel(struct r8a66597 *r8a66597, | 669 | static void sudmac_free_channel(struct r8a66597 *r8a66597, |
@@ -677,9 +673,7 @@ static void sudmac_free_channel(struct r8a66597 *r8a66597, | |||
677 | if (!r8a66597_is_sudmac(r8a66597)) | 673 | if (!r8a66597_is_sudmac(r8a66597)) |
678 | return; | 674 | return; |
679 | 675 | ||
680 | dma_unmap_single(r8a66597_to_dev(ep->r8a66597), | 676 | usb_gadget_unmap_request(&r8a66597->gadget, &req->req, ep->dma->dir); |
681 | req->req.dma, req->req.length, | ||
682 | ep->dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
683 | 677 | ||
684 | r8a66597_bclr(r8a66597, DREQE, ep->fifosel); | 678 | r8a66597_bclr(r8a66597, DREQE, ep->fifosel); |
685 | r8a66597_change_curpipe(r8a66597, 0, 0, ep->fifosel); | 679 | r8a66597_change_curpipe(r8a66597, 0, 0, ep->fifosel); |
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index c2f3aa650584..cef9b82ff911 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/prefetch.h> | 30 | #include <linux/prefetch.h> |
31 | #include <linux/platform_data/s3c-hsudc.h> | 31 | #include <linux/platform_data/s3c-hsudc.h> |
32 | #include <linux/regulator/consumer.h> | 32 | #include <linux/regulator/consumer.h> |
33 | #include <linux/pm_runtime.h> | ||
33 | 34 | ||
34 | #include <mach/regs-s3c2443-clock.h> | 35 | #include <mach/regs-s3c2443-clock.h> |
35 | 36 | ||
@@ -759,7 +760,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, | |||
759 | unsigned long flags; | 760 | unsigned long flags; |
760 | u32 ecr = 0; | 761 | u32 ecr = 0; |
761 | 762 | ||
762 | hsep = container_of(_ep, struct s3c_hsudc_ep, ep); | 763 | hsep = our_ep(_ep); |
763 | if (!_ep || !desc || hsep->desc || _ep->name == ep0name | 764 | if (!_ep || !desc || hsep->desc || _ep->name == ep0name |
764 | || desc->bDescriptorType != USB_DT_ENDPOINT | 765 | || desc->bDescriptorType != USB_DT_ENDPOINT |
765 | || hsep->bEndpointAddress != desc->bEndpointAddress | 766 | || hsep->bEndpointAddress != desc->bEndpointAddress |
@@ -816,6 +817,7 @@ static int s3c_hsudc_ep_disable(struct usb_ep *_ep) | |||
816 | s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); | 817 | s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); |
817 | 818 | ||
818 | hsep->desc = 0; | 819 | hsep->desc = 0; |
820 | hsep->ep.desc = NULL; | ||
819 | hsep->stopped = 1; | 821 | hsep->stopped = 1; |
820 | 822 | ||
821 | spin_unlock_irqrestore(&hsudc->lock, flags); | 823 | spin_unlock_irqrestore(&hsudc->lock, flags); |
@@ -853,7 +855,7 @@ static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
853 | { | 855 | { |
854 | struct s3c_hsudc_req *hsreq; | 856 | struct s3c_hsudc_req *hsreq; |
855 | 857 | ||
856 | hsreq = container_of(_req, struct s3c_hsudc_req, req); | 858 | hsreq = our_req(_req); |
857 | WARN_ON(!list_empty(&hsreq->queue)); | 859 | WARN_ON(!list_empty(&hsreq->queue)); |
858 | kfree(hsreq); | 860 | kfree(hsreq); |
859 | } | 861 | } |
@@ -876,12 +878,12 @@ static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
876 | u32 offset; | 878 | u32 offset; |
877 | u32 csr; | 879 | u32 csr; |
878 | 880 | ||
879 | hsreq = container_of(_req, struct s3c_hsudc_req, req); | 881 | hsreq = our_req(_req); |
880 | if ((!_req || !_req->complete || !_req->buf || | 882 | if ((!_req || !_req->complete || !_req->buf || |
881 | !list_empty(&hsreq->queue))) | 883 | !list_empty(&hsreq->queue))) |
882 | return -EINVAL; | 884 | return -EINVAL; |
883 | 885 | ||
884 | hsep = container_of(_ep, struct s3c_hsudc_ep, ep); | 886 | hsep = our_ep(_ep); |
885 | hsudc = hsep->dev; | 887 | hsudc = hsep->dev; |
886 | if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) | 888 | if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) |
887 | return -ESHUTDOWN; | 889 | return -ESHUTDOWN; |
@@ -935,7 +937,7 @@ static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
935 | struct s3c_hsudc_req *hsreq; | 937 | struct s3c_hsudc_req *hsreq; |
936 | unsigned long flags; | 938 | unsigned long flags; |
937 | 939 | ||
938 | hsep = container_of(_ep, struct s3c_hsudc_ep, ep); | 940 | hsep = our_ep(_ep); |
939 | if (!_ep || hsep->ep.name == ep0name) | 941 | if (!_ep || hsep->ep.name == ep0name) |
940 | return -EINVAL; | 942 | return -EINVAL; |
941 | 943 | ||
@@ -1005,6 +1007,7 @@ static void s3c_hsudc_initep(struct s3c_hsudc *hsudc, | |||
1005 | hsep->ep.ops = &s3c_hsudc_ep_ops; | 1007 | hsep->ep.ops = &s3c_hsudc_ep_ops; |
1006 | hsep->fifo = hsudc->regs + S3C_BR(epnum); | 1008 | hsep->fifo = hsudc->regs + S3C_BR(epnum); |
1007 | hsep->desc = 0; | 1009 | hsep->desc = 0; |
1010 | hsep->ep.desc = NULL; | ||
1008 | hsep->stopped = 0; | 1011 | hsep->stopped = 0; |
1009 | hsep->wedge = 0; | 1012 | hsep->wedge = 0; |
1010 | 1013 | ||
@@ -1179,6 +1182,9 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, | |||
1179 | dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); | 1182 | dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); |
1180 | 1183 | ||
1181 | s3c_hsudc_reconfig(hsudc); | 1184 | s3c_hsudc_reconfig(hsudc); |
1185 | |||
1186 | pm_runtime_get_sync(hsudc->dev); | ||
1187 | |||
1182 | s3c_hsudc_init_phy(); | 1188 | s3c_hsudc_init_phy(); |
1183 | if (hsudc->pd->gpio_init) | 1189 | if (hsudc->pd->gpio_init) |
1184 | hsudc->pd->gpio_init(); | 1190 | hsudc->pd->gpio_init(); |
@@ -1209,6 +1215,9 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, | |||
1209 | hsudc->gadget.dev.driver = NULL; | 1215 | hsudc->gadget.dev.driver = NULL; |
1210 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | 1216 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; |
1211 | s3c_hsudc_uninit_phy(); | 1217 | s3c_hsudc_uninit_phy(); |
1218 | |||
1219 | pm_runtime_put(hsudc->dev); | ||
1220 | |||
1212 | if (hsudc->pd->gpio_uninit) | 1221 | if (hsudc->pd->gpio_uninit) |
1213 | hsudc->pd->gpio_uninit(); | 1222 | hsudc->pd->gpio_uninit(); |
1214 | s3c_hsudc_stop_activity(hsudc); | 1223 | s3c_hsudc_stop_activity(hsudc); |
@@ -1363,6 +1372,8 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) | |||
1363 | if (ret) | 1372 | if (ret) |
1364 | goto err_add_udc; | 1373 | goto err_add_udc; |
1365 | 1374 | ||
1375 | pm_runtime_enable(dev); | ||
1376 | |||
1366 | return 0; | 1377 | return 0; |
1367 | err_add_udc: | 1378 | err_add_udc: |
1368 | device_unregister(&hsudc->gadget.dev); | 1379 | device_unregister(&hsudc->gadget.dev); |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 3f87cb9344bb..ab9c65e2c1d5 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -1148,6 +1148,7 @@ static int s3c2410_udc_ep_disable(struct usb_ep *_ep) | |||
1148 | dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name); | 1148 | dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name); |
1149 | 1149 | ||
1150 | ep->desc = NULL; | 1150 | ep->desc = NULL; |
1151 | ep->ep.desc = NULL; | ||
1151 | ep->halted = 1; | 1152 | ep->halted = 1; |
1152 | 1153 | ||
1153 | s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN); | 1154 | s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN); |
@@ -1630,6 +1631,7 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev) | |||
1630 | 1631 | ||
1631 | ep->dev = dev; | 1632 | ep->dev = dev; |
1632 | ep->desc = NULL; | 1633 | ep->desc = NULL; |
1634 | ep->ep.desc = NULL; | ||
1633 | ep->halted = 0; | 1635 | ep->halted = 0; |
1634 | INIT_LIST_HEAD (&ep->queue); | 1636 | INIT_LIST_HEAD (&ep->queue); |
1635 | } | 1637 | } |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index ad9e5b2df642..665c07422c26 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -242,7 +242,7 @@ static struct usb_composite_driver gserial_driver = { | |||
242 | .name = "g_serial", | 242 | .name = "g_serial", |
243 | .dev = &device_desc, | 243 | .dev = &device_desc, |
244 | .strings = dev_strings, | 244 | .strings = dev_strings, |
245 | .max_speed = USB_SPEED_HIGH, | 245 | .max_speed = USB_SPEED_SUPER, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static int __init init(void) | 248 | static int __init init(void) |
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 52ab4098b3c9..8081ca3a70a2 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2003-2008 Alan Stern | 4 | * Copyright (C) 2003-2008 Alan Stern |
5 | * Copyeight (C) 2009 Samsung Electronics | 5 | * Copyeight (C) 2009 Samsung Electronics |
6 | * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) | 6 | * Author: Michal Nazarewicz (mina86@mina86.com) |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_uac1.c index 59ffe1ecf1c9..af9898982059 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_uac1.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * u_audio.c -- ALSA audio utilities for Gadget stack | 2 | * u_uac1.c -- ALSA audio utilities for Gadget stack |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> | 4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> |
5 | * Copyright (C) 2008 Analog Devices, Inc | 5 | * Copyright (C) 2008 Analog Devices, Inc |
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/random.h> | 17 | #include <linux/random.h> |
18 | #include <linux/syscalls.h> | 18 | #include <linux/syscalls.h> |
19 | 19 | ||
20 | #include "u_audio.h" | 20 | #include "u_uac1.h" |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * This component encapsulates the ALSA devices for USB audio gadget | 23 | * This component encapsulates the ALSA devices for USB audio gadget |
diff --git a/drivers/usb/gadget/u_audio.h b/drivers/usb/gadget/u_uac1.h index 08ffce3298e6..18c2e729faf6 100644 --- a/drivers/usb/gadget/u_audio.h +++ b/drivers/usb/gadget/u_uac1.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * u_audio.h -- interface to USB gadget "ALSA AUDIO" utilities | 2 | * u_uac1.h -- interface to USB gadget "ALSA AUDIO" utilities |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> | 4 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> |
5 | * Copyright (C) 2008 Analog Devices, Inc | 5 | * Copyright (C) 2008 Analog Devices, Inc |
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 0b0d12ccc487..56da49f31d6c 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/dma-mapping.h> | ||
25 | 26 | ||
26 | #include <linux/usb/ch9.h> | 27 | #include <linux/usb/ch9.h> |
27 | #include <linux/usb/gadget.h> | 28 | #include <linux/usb/gadget.h> |
@@ -49,6 +50,57 @@ static DEFINE_MUTEX(udc_lock); | |||
49 | 50 | ||
50 | /* ------------------------------------------------------------------------- */ | 51 | /* ------------------------------------------------------------------------- */ |
51 | 52 | ||
53 | int usb_gadget_map_request(struct usb_gadget *gadget, | ||
54 | struct usb_request *req, int is_in) | ||
55 | { | ||
56 | if (req->length == 0) | ||
57 | return 0; | ||
58 | |||
59 | if (req->num_sgs) { | ||
60 | int mapped; | ||
61 | |||
62 | mapped = dma_map_sg(&gadget->dev, req->sg, req->num_sgs, | ||
63 | is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
64 | if (mapped == 0) { | ||
65 | dev_err(&gadget->dev, "failed to map SGs\n"); | ||
66 | return -EFAULT; | ||
67 | } | ||
68 | |||
69 | req->num_mapped_sgs = mapped; | ||
70 | } else { | ||
71 | req->dma = dma_map_single(&gadget->dev, req->buf, req->length, | ||
72 | is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
73 | |||
74 | if (dma_mapping_error(&gadget->dev, req->dma)) { | ||
75 | dev_err(&gadget->dev, "failed to map buffer\n"); | ||
76 | return -EFAULT; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | EXPORT_SYMBOL_GPL(usb_gadget_map_request); | ||
83 | |||
84 | void usb_gadget_unmap_request(struct usb_gadget *gadget, | ||
85 | struct usb_request *req, int is_in) | ||
86 | { | ||
87 | if (req->length == 0) | ||
88 | return; | ||
89 | |||
90 | if (req->num_mapped_sgs) { | ||
91 | dma_unmap_sg(&gadget->dev, req->sg, req->num_mapped_sgs, | ||
92 | is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
93 | |||
94 | req->num_mapped_sgs = 0; | ||
95 | } else { | ||
96 | dma_unmap_single(&gadget->dev, req->dma, req->length, | ||
97 | is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
98 | } | ||
99 | } | ||
100 | EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); | ||
101 | |||
102 | /* ------------------------------------------------------------------------- */ | ||
103 | |||
52 | /** | 104 | /** |
53 | * usb_gadget_start - tells usb device controller to start up | 105 | * usb_gadget_start - tells usb device controller to start up |
54 | * @gadget: The gadget we want to get started | 106 | * @gadget: The gadget we want to get started |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index e9a5b1d2615e..a165490bae48 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -413,8 +413,7 @@ static int usbhs_probe(struct platform_device *pdev) | |||
413 | struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; | 413 | struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; |
414 | struct renesas_usbhs_driver_callback *dfunc; | 414 | struct renesas_usbhs_driver_callback *dfunc; |
415 | struct usbhs_priv *priv; | 415 | struct usbhs_priv *priv; |
416 | struct resource *res; | 416 | struct resource *res, *irq_res; |
417 | unsigned int irq; | ||
418 | int ret; | 417 | int ret; |
419 | 418 | ||
420 | /* check platform information */ | 419 | /* check platform information */ |
@@ -426,8 +425,8 @@ static int usbhs_probe(struct platform_device *pdev) | |||
426 | 425 | ||
427 | /* platform data */ | 426 | /* platform data */ |
428 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 427 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
429 | irq = platform_get_irq(pdev, 0); | 428 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
430 | if (!res || (int)irq <= 0) { | 429 | if (!res || !irq_res) { |
431 | dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); | 430 | dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); |
432 | return -ENODEV; | 431 | return -ENODEV; |
433 | } | 432 | } |
@@ -476,7 +475,9 @@ static int usbhs_probe(struct platform_device *pdev) | |||
476 | /* | 475 | /* |
477 | * priv settings | 476 | * priv settings |
478 | */ | 477 | */ |
479 | priv->irq = irq; | 478 | priv->irq = irq_res->start; |
479 | if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE) | ||
480 | priv->irqflags = IRQF_SHARED; | ||
480 | priv->pdev = pdev; | 481 | priv->pdev = pdev; |
481 | INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); | 482 | INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); |
482 | spin_lock_init(usbhs_priv_to_lock(priv)); | 483 | spin_lock_init(usbhs_priv_to_lock(priv)); |
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index d79b3e27db95..3f3ccd358753 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
@@ -242,6 +242,7 @@ struct usbhs_priv { | |||
242 | 242 | ||
243 | void __iomem *base; | 243 | void __iomem *base; |
244 | unsigned int irq; | 244 | unsigned int irq; |
245 | unsigned long irqflags; | ||
245 | 246 | ||
246 | struct renesas_usbhs_platform_callback pfunc; | 247 | struct renesas_usbhs_platform_callback pfunc; |
247 | struct renesas_usbhs_driver_param dparam; | 248 | struct renesas_usbhs_driver_param dparam; |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 72339bd6fcab..3648c82a17fe 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) | 23 | #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) |
24 | #define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo)) | 24 | #define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo)) |
25 | #define usbhsf_get_d1fifo(p) (&((p)->fifo_info.d1fifo)) | 25 | #define usbhsf_get_d1fifo(p) (&((p)->fifo_info.d1fifo)) |
26 | #define usbhsf_is_cfifo(p, f) (usbhsf_get_cfifo(p) == f) | ||
26 | 27 | ||
27 | #define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */ | 28 | #define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */ |
28 | 29 | ||
@@ -75,8 +76,7 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | |||
75 | pipe->handler = &usbhsf_null_handler; | 76 | pipe->handler = &usbhsf_null_handler; |
76 | } | 77 | } |
77 | 78 | ||
78 | list_del_init(&pkt->node); | 79 | list_move_tail(&pkt->node, &pipe->list); |
79 | list_add_tail(&pkt->node, &pipe->list); | ||
80 | 80 | ||
81 | /* | 81 | /* |
82 | * each pkt must hold own handler. | 82 | * each pkt must hold own handler. |
@@ -106,7 +106,7 @@ static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) | |||
106 | if (list_empty(&pipe->list)) | 106 | if (list_empty(&pipe->list)) |
107 | return NULL; | 107 | return NULL; |
108 | 108 | ||
109 | return list_entry(pipe->list.next, struct usbhs_pkt, node); | 109 | return list_first_entry(&pipe->list, struct usbhs_pkt, node); |
110 | } | 110 | } |
111 | 111 | ||
112 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) | 112 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) |
@@ -305,7 +305,10 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, | |||
305 | } | 305 | } |
306 | 306 | ||
307 | /* "base" will be used below */ | 307 | /* "base" will be used below */ |
308 | usbhs_write(priv, fifo->sel, base | MBW_32); | 308 | if (usbhs_get_dparam(priv, has_sudmac) && !usbhsf_is_cfifo(priv, fifo)) |
309 | usbhs_write(priv, fifo->sel, base); | ||
310 | else | ||
311 | usbhs_write(priv, fifo->sel, base | MBW_32); | ||
309 | 312 | ||
310 | /* check ISEL and CURPIPE value */ | 313 | /* check ISEL and CURPIPE value */ |
311 | while (timeout--) { | 314 | while (timeout--) { |
@@ -762,9 +765,9 @@ static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | |||
762 | } | 765 | } |
763 | 766 | ||
764 | static void usbhsf_dma_complete(void *arg); | 767 | static void usbhsf_dma_complete(void *arg); |
765 | static void usbhsf_dma_prepare_tasklet(unsigned long data) | 768 | static void xfer_work(struct work_struct *work) |
766 | { | 769 | { |
767 | struct usbhs_pkt *pkt = (struct usbhs_pkt *)data; | 770 | struct usbhs_pkt *pkt = container_of(work, struct usbhs_pkt, work); |
768 | struct usbhs_pipe *pipe = pkt->pipe; | 771 | struct usbhs_pipe *pipe = pkt->pipe; |
769 | struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe); | 772 | struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe); |
770 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 773 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
@@ -844,11 +847,8 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) | |||
844 | 847 | ||
845 | pkt->trans = len; | 848 | pkt->trans = len; |
846 | 849 | ||
847 | tasklet_init(&fifo->tasklet, | 850 | INIT_WORK(&pkt->work, xfer_work); |
848 | usbhsf_dma_prepare_tasklet, | 851 | schedule_work(&pkt->work); |
849 | (unsigned long)pkt); | ||
850 | |||
851 | tasklet_schedule(&fifo->tasklet); | ||
852 | 852 | ||
853 | return 0; | 853 | return 0; |
854 | 854 | ||
@@ -938,11 +938,8 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
938 | 938 | ||
939 | pkt->trans = len; | 939 | pkt->trans = len; |
940 | 940 | ||
941 | tasklet_init(&fifo->tasklet, | 941 | INIT_WORK(&pkt->work, xfer_work); |
942 | usbhsf_dma_prepare_tasklet, | 942 | schedule_work(&pkt->work); |
943 | (unsigned long)pkt); | ||
944 | |||
945 | tasklet_schedule(&fifo->tasklet); | ||
946 | 943 | ||
947 | return 0; | 944 | return 0; |
948 | 945 | ||
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index f68609c0f489..c31731a843d1 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/sh_dma.h> | 21 | #include <linux/sh_dma.h> |
22 | #include <linux/workqueue.h> | ||
22 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
23 | #include "pipe.h" | 24 | #include "pipe.h" |
24 | 25 | ||
@@ -31,7 +32,6 @@ struct usbhs_fifo { | |||
31 | u32 ctr; /* xFIFOCTR */ | 32 | u32 ctr; /* xFIFOCTR */ |
32 | 33 | ||
33 | struct usbhs_pipe *pipe; | 34 | struct usbhs_pipe *pipe; |
34 | struct tasklet_struct tasklet; | ||
35 | 35 | ||
36 | struct dma_chan *tx_chan; | 36 | struct dma_chan *tx_chan; |
37 | struct dma_chan *rx_chan; | 37 | struct dma_chan *rx_chan; |
@@ -53,6 +53,7 @@ struct usbhs_pkt { | |||
53 | struct usbhs_pkt_handle *handler; | 53 | struct usbhs_pkt_handle *handler; |
54 | void (*done)(struct usbhs_priv *priv, | 54 | void (*done)(struct usbhs_priv *priv, |
55 | struct usbhs_pkt *pkt); | 55 | struct usbhs_pkt *pkt); |
56 | struct work_struct work; | ||
56 | dma_addr_t dma; | 57 | dma_addr_t dma; |
57 | void *buf; | 58 | void *buf; |
58 | int length; | 59 | int length; |
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 1b97fb12694b..0871e816df45 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -152,7 +152,7 @@ int usbhs_mod_probe(struct usbhs_priv *priv) | |||
152 | 152 | ||
153 | /* irq settings */ | 153 | /* irq settings */ |
154 | ret = request_irq(priv->irq, usbhs_interrupt, | 154 | ret = request_irq(priv->irq, usbhs_interrupt, |
155 | 0, dev_name(dev), priv); | 155 | priv->irqflags, dev_name(dev), priv); |
156 | if (ret) { | 156 | if (ret) { |
157 | dev_err(dev, "irq request err\n"); | 157 | dev_err(dev, "irq request err\n"); |
158 | goto mod_init_gadget_err; | 158 | goto mod_init_gadget_err; |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 7542aa94a462..00bd2a5e0362 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -165,69 +165,32 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep, | |||
165 | /* | 165 | /* |
166 | * dma map/unmap | 166 | * dma map/unmap |
167 | */ | 167 | */ |
168 | static int usbhsg_dma_map(struct device *dev, | 168 | static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) |
169 | struct usbhs_pkt *pkt, | ||
170 | enum dma_data_direction dir) | ||
171 | { | ||
172 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); | ||
173 | struct usb_request *req = &ureq->req; | ||
174 | |||
175 | if (pkt->dma != DMA_ADDR_INVALID) { | ||
176 | dev_err(dev, "dma is already mapped\n"); | ||
177 | return -EIO; | ||
178 | } | ||
179 | |||
180 | if (req->dma == DMA_ADDR_INVALID) { | ||
181 | pkt->dma = dma_map_single(dev, pkt->buf, pkt->length, dir); | ||
182 | } else { | ||
183 | dma_sync_single_for_device(dev, req->dma, req->length, dir); | ||
184 | pkt->dma = req->dma; | ||
185 | } | ||
186 | |||
187 | if (dma_mapping_error(dev, pkt->dma)) { | ||
188 | dev_err(dev, "dma mapping error %llx\n", (u64)pkt->dma); | ||
189 | return -EIO; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int usbhsg_dma_unmap(struct device *dev, | ||
196 | struct usbhs_pkt *pkt, | ||
197 | enum dma_data_direction dir) | ||
198 | { | 169 | { |
199 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); | 170 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); |
200 | struct usb_request *req = &ureq->req; | 171 | struct usb_request *req = &ureq->req; |
201 | |||
202 | if (pkt->dma == DMA_ADDR_INVALID) { | ||
203 | dev_err(dev, "dma is not mapped\n"); | ||
204 | return -EIO; | ||
205 | } | ||
206 | |||
207 | if (req->dma == DMA_ADDR_INVALID) | ||
208 | dma_unmap_single(dev, pkt->dma, pkt->length, dir); | ||
209 | else | ||
210 | dma_sync_single_for_cpu(dev, req->dma, req->length, dir); | ||
211 | |||
212 | pkt->dma = DMA_ADDR_INVALID; | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | ||
218 | { | ||
219 | struct usbhs_pipe *pipe = pkt->pipe; | 172 | struct usbhs_pipe *pipe = pkt->pipe; |
220 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); | 173 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); |
221 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 174 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
222 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
223 | enum dma_data_direction dir; | 175 | enum dma_data_direction dir; |
176 | int ret = 0; | ||
224 | 177 | ||
225 | dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 178 | dir = usbhs_pipe_is_dir_host(pipe); |
226 | 179 | ||
227 | if (map) | 180 | if (map) { |
228 | return usbhsg_dma_map(dev, pkt, dir); | 181 | /* it can not use scatter/gather */ |
229 | else | 182 | WARN_ON(req->num_sgs); |
230 | return usbhsg_dma_unmap(dev, pkt, dir); | 183 | |
184 | ret = usb_gadget_map_request(&gpriv->gadget, req, dir); | ||
185 | if (ret < 0) | ||
186 | return ret; | ||
187 | |||
188 | pkt->dma = req->dma; | ||
189 | } else { | ||
190 | usb_gadget_unmap_request(&gpriv->gadget, req, dir); | ||
191 | } | ||
192 | |||
193 | return ret; | ||
231 | } | 194 | } |
232 | 195 | ||
233 | /* | 196 | /* |
@@ -657,8 +620,6 @@ static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, | |||
657 | 620 | ||
658 | usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); | 621 | usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); |
659 | 622 | ||
660 | ureq->req.dma = DMA_ADDR_INVALID; | ||
661 | |||
662 | return &ureq->req; | 623 | return &ureq->req; |
663 | } | 624 | } |
664 | 625 | ||
@@ -941,6 +902,11 @@ static int usbhsg_stop(struct usbhs_priv *priv) | |||
941 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); | 902 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); |
942 | } | 903 | } |
943 | 904 | ||
905 | static void usbhs_mod_gadget_release(struct device *pdev) | ||
906 | { | ||
907 | /* do nothing */ | ||
908 | } | ||
909 | |||
944 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | 910 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
945 | { | 911 | { |
946 | struct usbhsg_gpriv *gpriv; | 912 | struct usbhsg_gpriv *gpriv; |
@@ -989,6 +955,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
989 | */ | 955 | */ |
990 | dev_set_name(&gpriv->gadget.dev, "gadget"); | 956 | dev_set_name(&gpriv->gadget.dev, "gadget"); |
991 | gpriv->gadget.dev.parent = dev; | 957 | gpriv->gadget.dev.parent = dev; |
958 | gpriv->gadget.dev.release = usbhs_mod_gadget_release; | ||
992 | gpriv->gadget.name = "renesas_usbhs_udc"; | 959 | gpriv->gadget.name = "renesas_usbhs_udc"; |
993 | gpriv->gadget.ops = &usbhsg_gadget_ops; | 960 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
994 | gpriv->gadget.max_speed = USB_SPEED_HIGH; | 961 | gpriv->gadget.max_speed = USB_SPEED_HIGH; |
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index 964cb603f7c7..ed13053153f4 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h | |||
@@ -43,6 +43,27 @@ static inline bool uac2_control_is_writeable(u32 bmControls, u8 control) | |||
43 | return (bmControls >> (control * 2)) & 0x2; | 43 | return (bmControls >> (control * 2)) & 0x2; |
44 | } | 44 | } |
45 | 45 | ||
46 | /* 4.7.2 Class-Specific AC Interface Descriptor */ | ||
47 | struct uac2_ac_header_descriptor { | ||
48 | __u8 bLength; /* 9 */ | ||
49 | __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ | ||
50 | __u8 bDescriptorSubtype; /* UAC_MS_HEADER */ | ||
51 | __le16 bcdADC; /* 0x0200 */ | ||
52 | __u8 bCategory; | ||
53 | __le16 wTotalLength; /* includes Unit and Terminal desc. */ | ||
54 | __u8 bmControls; | ||
55 | } __packed; | ||
56 | |||
57 | /* 2.3.1.6 Type I Format Type Descriptor (Frmts20 final.pdf)*/ | ||
58 | struct uac2_format_type_i_descriptor { | ||
59 | __u8 bLength; /* in bytes: 6 */ | ||
60 | __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ | ||
61 | __u8 bDescriptorSubtype; /* FORMAT_TYPE */ | ||
62 | __u8 bFormatType; /* FORMAT_TYPE_1 */ | ||
63 | __u8 bSubslotSize; /* {1,2,3,4} */ | ||
64 | __u8 bBitResolution; | ||
65 | } __packed; | ||
66 | |||
46 | /* 4.7.2.1 Clock Source Descriptor */ | 67 | /* 4.7.2.1 Clock Source Descriptor */ |
47 | 68 | ||
48 | struct uac_clock_source_descriptor { | 69 | struct uac_clock_source_descriptor { |
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index da653b5c7134..9517466ababb 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h | |||
@@ -950,6 +950,16 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v) | |||
950 | 950 | ||
951 | /*-------------------------------------------------------------------------*/ | 951 | /*-------------------------------------------------------------------------*/ |
952 | 952 | ||
953 | /* utility to simplify map/unmap of usb_requests to/from DMA */ | ||
954 | |||
955 | extern int usb_gadget_map_request(struct usb_gadget *gadget, | ||
956 | struct usb_request *req, int is_in); | ||
957 | |||
958 | extern void usb_gadget_unmap_request(struct usb_gadget *gadget, | ||
959 | struct usb_request *req, int is_in); | ||
960 | |||
961 | /*-------------------------------------------------------------------------*/ | ||
962 | |||
953 | /* utility wrapping a simple endpoint selection policy */ | 963 | /* utility wrapping a simple endpoint selection policy */ |
954 | 964 | ||
955 | extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, | 965 | extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, |
diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 0d3f98879256..547e59cc00ea 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h | |||
@@ -149,6 +149,7 @@ struct renesas_usbhs_driver_param { | |||
149 | * option: | 149 | * option: |
150 | */ | 150 | */ |
151 | u32 has_otg:1; /* for controlling PWEN/EXTLP */ | 151 | u32 has_otg:1; /* for controlling PWEN/EXTLP */ |
152 | u32 has_sudmac:1; /* for SUDMAC */ | ||
152 | }; | 153 | }; |
153 | 154 | ||
154 | /* | 155 | /* |
diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c index b9c798631699..53452c35d5e1 100644 --- a/tools/usb/ffs-test.c +++ b/tools/usb/ffs-test.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * ffs-test.c.c -- user mode filesystem api for usb composite function | 2 | * ffs-test.c.c -- user mode filesystem api for usb composite function |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics | 4 | * Copyright (C) 2010 Samsung Electronics |
5 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 5 | * Author: Michal Nazarewicz <mina86@mina86.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c index f08e89463842..6e0f56701e44 100644 --- a/tools/usb/testusb.c +++ b/tools/usb/testusb.c | |||
@@ -3,7 +3,7 @@ | |||
3 | /* | 3 | /* |
4 | * Copyright (c) 2002 by David Brownell | 4 | * Copyright (c) 2002 by David Brownell |
5 | * Copyright (c) 2010 by Samsung Electronics | 5 | * Copyright (c) 2010 by Samsung Electronics |
6 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 6 | * Author: Michal Nazarewicz <mina86@mina86.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |