diff options
author | David S. Miller <davem@davemloft.net> | 2009-01-08 14:05:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-08 14:05:59 -0500 |
commit | 7f46b1343f723f98634a5dcee47856b2000079ed (patch) | |
tree | ed22b6298c8dd2f687890a0d79abcd1d273b5f81 /drivers/usb/gadget | |
parent | b8c31da64165b8566fc6e1c9c826f76e7b98ff02 (diff) | |
parent | 9e42d0cf5020aaf217433cad1a224745241d212a (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 43 | ||||
-rw-r--r-- | drivers/usb/gadget/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/at91_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 2830 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.h | 195 | ||||
-rw-r--r-- | drivers/usb/gadget/epautoconf.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 177 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_qe_udc.c | 14 | ||||
-rw-r--r-- | drivers/usb/gadget/gadget_chips.h | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/goku_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/imx_udc.c | 1516 | ||||
-rw-r--r-- | drivers/usb/gadget/imx_udc.h | 344 | ||||
-rw-r--r-- | drivers/usb/gadget/lh7a40x_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/m66592-udc.c | 9 | ||||
-rw-r--r-- | drivers/usb/gadget/net2280.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa27x_udc.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c2410_udc.c | 36 |
20 files changed, 5137 insertions, 61 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index dd4cd5a51370..3219d137340a 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -297,13 +297,34 @@ config USB_S3C2410_DEBUG | |||
297 | 297 | ||
298 | # musb builds in ../musb along with host support | 298 | # musb builds in ../musb along with host support |
299 | config USB_GADGET_MUSB_HDRC | 299 | config USB_GADGET_MUSB_HDRC |
300 | boolean "Inventra HDRC USB Peripheral (TI, ...)" | 300 | boolean "Inventra HDRC USB Peripheral (TI, ADI, ...)" |
301 | depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG) | 301 | depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG) |
302 | select USB_GADGET_DUALSPEED | 302 | select USB_GADGET_DUALSPEED |
303 | select USB_GADGET_SELECTED | 303 | select USB_GADGET_SELECTED |
304 | help | 304 | help |
305 | This OTG-capable silicon IP is used in dual designs including | 305 | This OTG-capable silicon IP is used in dual designs including |
306 | the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010. | 306 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin |
307 | |||
308 | config USB_GADGET_IMX | ||
309 | boolean "Freescale IMX USB Peripheral Controller" | ||
310 | depends on ARCH_MX1 | ||
311 | help | ||
312 | Freescale's IMX series include an integrated full speed | ||
313 | USB 1.1 device controller. The controller in the IMX series | ||
314 | is register-compatible. | ||
315 | |||
316 | It has Six fixed-function endpoints, as well as endpoint | ||
317 | zero (for control transfers). | ||
318 | |||
319 | Say "y" to link the driver statically, or "m" to build a | ||
320 | dynamically linked module called "imx_udc" and force all | ||
321 | gadget drivers to also be dynamically linked. | ||
322 | |||
323 | config USB_IMX | ||
324 | tristate | ||
325 | depends on USB_GADGET_IMX | ||
326 | default USB_GADGET | ||
327 | select USB_GADGET_SELECTED | ||
307 | 328 | ||
308 | config USB_GADGET_M66592 | 329 | config USB_GADGET_M66592 |
309 | boolean "Renesas M66592 USB Peripheral Controller" | 330 | boolean "Renesas M66592 USB Peripheral Controller" |
@@ -377,6 +398,24 @@ config USB_FSL_QE | |||
377 | default USB_GADGET | 398 | default USB_GADGET |
378 | select USB_GADGET_SELECTED | 399 | select USB_GADGET_SELECTED |
379 | 400 | ||
401 | config USB_GADGET_CI13XXX | ||
402 | boolean "MIPS USB CI13xxx" | ||
403 | depends on PCI | ||
404 | select USB_GADGET_DUALSPEED | ||
405 | help | ||
406 | MIPS USB IP core family device controller | ||
407 | Currently it only supports IP part number CI13412 | ||
408 | |||
409 | Say "y" to link the driver statically, or "m" to build a | ||
410 | dynamically linked module called "ci13xxx_udc" and force all | ||
411 | gadget drivers to also be dynamically linked. | ||
412 | |||
413 | config USB_CI13XXX | ||
414 | tristate | ||
415 | depends on USB_GADGET_CI13XXX | ||
416 | default USB_GADGET | ||
417 | select USB_GADGET_SELECTED | ||
418 | |||
380 | config USB_GADGET_NET2280 | 419 | config USB_GADGET_NET2280 |
381 | boolean "NetChip 228x" | 420 | boolean "NetChip 228x" |
382 | depends on PCI | 421 | depends on PCI |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index bd4041b47dce..39a51d746cb7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_USB_NET2280) += net2280.o | |||
10 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | 10 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o |
11 | obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o | 11 | obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o |
12 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o | 12 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o |
13 | obj-$(CONFIG_USB_IMX) += imx_udc.o | ||
13 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | 14 | obj-$(CONFIG_USB_GOKU) += goku_udc.o |
14 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | 15 | obj-$(CONFIG_USB_OMAP) += omap_udc.o |
15 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o | 16 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o |
@@ -19,6 +20,7 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | |||
19 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | 20 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
20 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 21 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
21 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | 22 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o |
23 | obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o | ||
22 | 24 | ||
23 | # | 25 | # |
24 | # USB gadget drivers | 26 | # USB gadget drivers |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index a8a1de413321..0b2bb8f0706d 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1474,7 +1474,7 @@ static struct at91_udc controller = { | |||
1474 | .ep0 = &controller.ep[0].ep, | 1474 | .ep0 = &controller.ep[0].ep, |
1475 | .name = driver_name, | 1475 | .name = driver_name, |
1476 | .dev = { | 1476 | .dev = { |
1477 | .bus_id = "gadget", | 1477 | .init_name = "gadget", |
1478 | .release = nop_release, | 1478 | .release = nop_release, |
1479 | } | 1479 | } |
1480 | }, | 1480 | }, |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index ae30ab1d264f..65b03e3445a1 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1034,7 +1034,7 @@ static struct usba_udc the_udc = { | |||
1034 | .is_dualspeed = 1, | 1034 | .is_dualspeed = 1, |
1035 | .name = "atmel_usba_udc", | 1035 | .name = "atmel_usba_udc", |
1036 | .dev = { | 1036 | .dev = { |
1037 | .bus_id = "gadget", | 1037 | .init_name = "gadget", |
1038 | .release = nop_release, | 1038 | .release = nop_release, |
1039 | }, | 1039 | }, |
1040 | }, | 1040 | }, |
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c new file mode 100644 index 000000000000..bebf911c7e5f --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -0,0 +1,2830 @@ | |||
1 | /* | ||
2 | * ci13xxx_udc.c - MIPS USB IP core family device controller | ||
3 | * | ||
4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. | ||
5 | * | ||
6 | * Author: David Lopo | ||
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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Description: MIPS USB IP core family device controller | ||
15 | * Currently it only supports IP part number CI13412 | ||
16 | * | ||
17 | * This driver is composed of several blocks: | ||
18 | * - HW: hardware interface | ||
19 | * - DBG: debug facilities (optional) | ||
20 | * - UTIL: utilities | ||
21 | * - ISR: interrupts handling | ||
22 | * - ENDPT: endpoint operations (Gadget API) | ||
23 | * - GADGET: gadget operations (Gadget API) | ||
24 | * - BUS: bus glue code, bus abstraction layer | ||
25 | * - PCI: PCI core interface and PCI resources (interrupts, memory...) | ||
26 | * | ||
27 | * Compile Options | ||
28 | * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities | ||
29 | * - STALL_IN: non-empty bulk-in pipes cannot be halted | ||
30 | * if defined mass storage compliance succeeds but with warnings | ||
31 | * => case 4: Hi > Dn | ||
32 | * => case 5: Hi > Di | ||
33 | * => case 8: Hi <> Do | ||
34 | * if undefined usbtest 13 fails | ||
35 | * - TRACE: enable function tracing (depends on DEBUG) | ||
36 | * | ||
37 | * Main Features | ||
38 | * - Chapter 9 & Mass Storage Compliance with Gadget File Storage | ||
39 | * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined) | ||
40 | * - Normal & LPM support | ||
41 | * | ||
42 | * USBTEST Report | ||
43 | * - OK: 0-12, 13 (STALL_IN defined) & 14 | ||
44 | * - Not Supported: 15 & 16 (ISO) | ||
45 | * | ||
46 | * TODO List | ||
47 | * - OTG | ||
48 | * - Isochronous & Interrupt Traffic | ||
49 | * - Handle requests which spawns into several TDs | ||
50 | * - GET_STATUS(device) - always reports 0 | ||
51 | * - Gadget API (majority of optional features) | ||
52 | * - Suspend & Remote Wakeup | ||
53 | */ | ||
54 | #include <linux/device.h> | ||
55 | #include <linux/dmapool.h> | ||
56 | #include <linux/dma-mapping.h> | ||
57 | #include <linux/init.h> | ||
58 | #include <linux/interrupt.h> | ||
59 | #include <linux/interrupt.h> | ||
60 | #include <linux/io.h> | ||
61 | #include <linux/irq.h> | ||
62 | #include <linux/kernel.h> | ||
63 | #include <linux/module.h> | ||
64 | #include <linux/pci.h> | ||
65 | #include <linux/usb/ch9.h> | ||
66 | #include <linux/usb/gadget.h> | ||
67 | |||
68 | #include "ci13xxx_udc.h" | ||
69 | |||
70 | |||
71 | /****************************************************************************** | ||
72 | * DEFINE | ||
73 | *****************************************************************************/ | ||
74 | /* ctrl register bank access */ | ||
75 | static DEFINE_SPINLOCK(udc_lock); | ||
76 | |||
77 | /* driver name */ | ||
78 | #define UDC_DRIVER_NAME "ci13xxx_udc" | ||
79 | |||
80 | /* control endpoint description */ | ||
81 | static const struct usb_endpoint_descriptor | ||
82 | ctrl_endpt_desc = { | ||
83 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
84 | .bDescriptorType = USB_DT_ENDPOINT, | ||
85 | |||
86 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
87 | .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), | ||
88 | }; | ||
89 | |||
90 | /* UDC descriptor */ | ||
91 | static struct ci13xxx *_udc; | ||
92 | |||
93 | /* Interrupt statistics */ | ||
94 | #define ISR_MASK 0x1F | ||
95 | static struct { | ||
96 | u32 test; | ||
97 | u32 ui; | ||
98 | u32 uei; | ||
99 | u32 pci; | ||
100 | u32 uri; | ||
101 | u32 sli; | ||
102 | u32 none; | ||
103 | struct { | ||
104 | u32 cnt; | ||
105 | u32 buf[ISR_MASK+1]; | ||
106 | u32 idx; | ||
107 | } hndl; | ||
108 | } isr_statistics; | ||
109 | |||
110 | /** | ||
111 | * ffs_nr: find first (least significant) bit set | ||
112 | * @x: the word to search | ||
113 | * | ||
114 | * This function returns bit number (instead of position) | ||
115 | */ | ||
116 | static int ffs_nr(u32 x) | ||
117 | { | ||
118 | int n = ffs(x); | ||
119 | |||
120 | return n ? n-1 : 32; | ||
121 | } | ||
122 | |||
123 | /****************************************************************************** | ||
124 | * HW block | ||
125 | *****************************************************************************/ | ||
126 | /* register bank descriptor */ | ||
127 | static struct { | ||
128 | unsigned lpm; /* is LPM? */ | ||
129 | void __iomem *abs; /* bus map offset */ | ||
130 | void __iomem *cap; /* bus map offset + CAP offset + CAP data */ | ||
131 | size_t size; /* bank size */ | ||
132 | } hw_bank; | ||
133 | |||
134 | /* UDC register map */ | ||
135 | #define ABS_CAPLENGTH (0x100UL) | ||
136 | #define ABS_HCCPARAMS (0x108UL) | ||
137 | #define ABS_DCCPARAMS (0x124UL) | ||
138 | #define ABS_TESTMODE (hw_bank.lpm ? 0x0FCUL : 0x138UL) | ||
139 | /* offset to CAPLENTGH (addr + data) */ | ||
140 | #define CAP_USBCMD (0x000UL) | ||
141 | #define CAP_USBSTS (0x004UL) | ||
142 | #define CAP_USBINTR (0x008UL) | ||
143 | #define CAP_DEVICEADDR (0x014UL) | ||
144 | #define CAP_ENDPTLISTADDR (0x018UL) | ||
145 | #define CAP_PORTSC (0x044UL) | ||
146 | #define CAP_DEVLC (0x0B4UL) | ||
147 | #define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL) | ||
148 | #define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL) | ||
149 | #define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL) | ||
150 | #define CAP_ENDPTFLUSH (hw_bank.lpm ? 0x0E0UL : 0x074UL) | ||
151 | #define CAP_ENDPTSTAT (hw_bank.lpm ? 0x0E4UL : 0x078UL) | ||
152 | #define CAP_ENDPTCOMPLETE (hw_bank.lpm ? 0x0E8UL : 0x07CUL) | ||
153 | #define CAP_ENDPTCTRL (hw_bank.lpm ? 0x0ECUL : 0x080UL) | ||
154 | #define CAP_LAST (hw_bank.lpm ? 0x12CUL : 0x0C0UL) | ||
155 | |||
156 | /* maximum number of enpoints: valid only after hw_device_reset() */ | ||
157 | static unsigned hw_ep_max; | ||
158 | |||
159 | /** | ||
160 | * hw_ep_bit: calculates the bit number | ||
161 | * @num: endpoint number | ||
162 | * @dir: endpoint direction | ||
163 | * | ||
164 | * This function returns bit number | ||
165 | */ | ||
166 | static inline int hw_ep_bit(int num, int dir) | ||
167 | { | ||
168 | return num + (dir ? 16 : 0); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * hw_aread: reads from register bitfield | ||
173 | * @addr: address relative to bus map | ||
174 | * @mask: bitfield mask | ||
175 | * | ||
176 | * This function returns register bitfield data | ||
177 | */ | ||
178 | static u32 hw_aread(u32 addr, u32 mask) | ||
179 | { | ||
180 | return ioread32(addr + hw_bank.abs) & mask; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * hw_awrite: writes to register bitfield | ||
185 | * @addr: address relative to bus map | ||
186 | * @mask: bitfield mask | ||
187 | * @data: new data | ||
188 | */ | ||
189 | static void hw_awrite(u32 addr, u32 mask, u32 data) | ||
190 | { | ||
191 | iowrite32(hw_aread(addr, ~mask) | (data & mask), | ||
192 | addr + hw_bank.abs); | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * hw_cread: reads from register bitfield | ||
197 | * @addr: address relative to CAP offset plus content | ||
198 | * @mask: bitfield mask | ||
199 | * | ||
200 | * This function returns register bitfield data | ||
201 | */ | ||
202 | static u32 hw_cread(u32 addr, u32 mask) | ||
203 | { | ||
204 | return ioread32(addr + hw_bank.cap) & mask; | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * hw_cwrite: writes to register bitfield | ||
209 | * @addr: address relative to CAP offset plus content | ||
210 | * @mask: bitfield mask | ||
211 | * @data: new data | ||
212 | */ | ||
213 | static void hw_cwrite(u32 addr, u32 mask, u32 data) | ||
214 | { | ||
215 | iowrite32(hw_cread(addr, ~mask) | (data & mask), | ||
216 | addr + hw_bank.cap); | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * hw_ctest_and_clear: tests & clears register bitfield | ||
221 | * @addr: address relative to CAP offset plus content | ||
222 | * @mask: bitfield mask | ||
223 | * | ||
224 | * This function returns register bitfield data | ||
225 | */ | ||
226 | static u32 hw_ctest_and_clear(u32 addr, u32 mask) | ||
227 | { | ||
228 | u32 reg = hw_cread(addr, mask); | ||
229 | |||
230 | iowrite32(reg, addr + hw_bank.cap); | ||
231 | return reg; | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * hw_ctest_and_write: tests & writes register bitfield | ||
236 | * @addr: address relative to CAP offset plus content | ||
237 | * @mask: bitfield mask | ||
238 | * @data: new data | ||
239 | * | ||
240 | * This function returns register bitfield data | ||
241 | */ | ||
242 | static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data) | ||
243 | { | ||
244 | u32 reg = hw_cread(addr, ~0); | ||
245 | |||
246 | iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap); | ||
247 | return (reg & mask) >> ffs_nr(mask); | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * hw_device_reset: resets chip (execute without interruption) | ||
252 | * @base: register base address | ||
253 | * | ||
254 | * This function returns an error code | ||
255 | */ | ||
256 | static int hw_device_reset(void __iomem *base) | ||
257 | { | ||
258 | u32 reg; | ||
259 | |||
260 | /* bank is a module variable */ | ||
261 | hw_bank.abs = base; | ||
262 | |||
263 | hw_bank.cap = hw_bank.abs; | ||
264 | hw_bank.cap += ABS_CAPLENGTH; | ||
265 | hw_bank.cap += ioread8(hw_bank.cap); | ||
266 | |||
267 | reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN); | ||
268 | hw_bank.lpm = reg; | ||
269 | hw_bank.size = hw_bank.cap - hw_bank.abs; | ||
270 | hw_bank.size += CAP_LAST; | ||
271 | hw_bank.size /= sizeof(u32); | ||
272 | |||
273 | /* should flush & stop before reset */ | ||
274 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); | ||
275 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); | ||
276 | |||
277 | hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST); | ||
278 | while (hw_cread(CAP_USBCMD, USBCMD_RST)) | ||
279 | udelay(10); /* not RTOS friendly */ | ||
280 | |||
281 | /* USBMODE should be configured step by step */ | ||
282 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | ||
283 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE); | ||
284 | hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); /* HW >= 2.3 */ | ||
285 | |||
286 | if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) { | ||
287 | pr_err("cannot enter in device mode"); | ||
288 | pr_err("lpm = %i", hw_bank.lpm); | ||
289 | return -ENODEV; | ||
290 | } | ||
291 | |||
292 | reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); | ||
293 | if (reg == 0 || reg > ENDPT_MAX) | ||
294 | return -ENODEV; | ||
295 | |||
296 | hw_ep_max = reg; /* cache hw ENDPT_MAX */ | ||
297 | |||
298 | /* setup lock mode ? */ | ||
299 | |||
300 | /* ENDPTSETUPSTAT is '0' by default */ | ||
301 | |||
302 | /* HCSPARAMS.bf.ppc SHOULD BE zero for device */ | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * hw_device_state: enables/disables interrupts & starts/stops device (execute | ||
309 | * without interruption) | ||
310 | * @dma: 0 => disable, !0 => enable and set dma engine | ||
311 | * | ||
312 | * This function returns an error code | ||
313 | */ | ||
314 | static int hw_device_state(u32 dma) | ||
315 | { | ||
316 | if (dma) { | ||
317 | hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma); | ||
318 | /* interrupt, error, port change, reset, sleep/suspend */ | ||
319 | hw_cwrite(CAP_USBINTR, ~0, | ||
320 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); | ||
321 | hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
322 | } else { | ||
323 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); | ||
324 | hw_cwrite(CAP_USBINTR, ~0, 0); | ||
325 | } | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * hw_ep_flush: flush endpoint fifo (execute without interruption) | ||
331 | * @num: endpoint number | ||
332 | * @dir: endpoint direction | ||
333 | * | ||
334 | * This function returns an error code | ||
335 | */ | ||
336 | static int hw_ep_flush(int num, int dir) | ||
337 | { | ||
338 | int n = hw_ep_bit(num, dir); | ||
339 | |||
340 | do { | ||
341 | /* flush any pending transfer */ | ||
342 | hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n)); | ||
343 | while (hw_cread(CAP_ENDPTFLUSH, BIT(n))) | ||
344 | cpu_relax(); | ||
345 | } while (hw_cread(CAP_ENDPTSTAT, BIT(n))); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * hw_ep_disable: disables endpoint (execute without interruption) | ||
352 | * @num: endpoint number | ||
353 | * @dir: endpoint direction | ||
354 | * | ||
355 | * This function returns an error code | ||
356 | */ | ||
357 | static int hw_ep_disable(int num, int dir) | ||
358 | { | ||
359 | hw_ep_flush(num, dir); | ||
360 | hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), | ||
361 | dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0); | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * hw_ep_enable: enables endpoint (execute without interruption) | ||
367 | * @num: endpoint number | ||
368 | * @dir: endpoint direction | ||
369 | * @type: endpoint type | ||
370 | * | ||
371 | * This function returns an error code | ||
372 | */ | ||
373 | static int hw_ep_enable(int num, int dir, int type) | ||
374 | { | ||
375 | u32 mask, data; | ||
376 | |||
377 | if (dir) { | ||
378 | mask = ENDPTCTRL_TXT; /* type */ | ||
379 | data = type << ffs_nr(mask); | ||
380 | |||
381 | mask |= ENDPTCTRL_TXS; /* unstall */ | ||
382 | mask |= ENDPTCTRL_TXR; /* reset data toggle */ | ||
383 | data |= ENDPTCTRL_TXR; | ||
384 | mask |= ENDPTCTRL_TXE; /* enable */ | ||
385 | data |= ENDPTCTRL_TXE; | ||
386 | } else { | ||
387 | mask = ENDPTCTRL_RXT; /* type */ | ||
388 | data = type << ffs_nr(mask); | ||
389 | |||
390 | mask |= ENDPTCTRL_RXS; /* unstall */ | ||
391 | mask |= ENDPTCTRL_RXR; /* reset data toggle */ | ||
392 | data |= ENDPTCTRL_RXR; | ||
393 | mask |= ENDPTCTRL_RXE; /* enable */ | ||
394 | data |= ENDPTCTRL_RXE; | ||
395 | } | ||
396 | hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data); | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * hw_ep_get_halt: return endpoint halt status | ||
402 | * @num: endpoint number | ||
403 | * @dir: endpoint direction | ||
404 | * | ||
405 | * This function returns 1 if endpoint halted | ||
406 | */ | ||
407 | static int hw_ep_get_halt(int num, int dir) | ||
408 | { | ||
409 | u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; | ||
410 | |||
411 | return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0; | ||
412 | } | ||
413 | |||
414 | /** | ||
415 | * hw_ep_is_primed: test if endpoint is primed (execute without interruption) | ||
416 | * @num: endpoint number | ||
417 | * @dir: endpoint direction | ||
418 | * | ||
419 | * This function returns true if endpoint primed | ||
420 | */ | ||
421 | static int hw_ep_is_primed(int num, int dir) | ||
422 | { | ||
423 | u32 reg = hw_cread(CAP_ENDPTPRIME, ~0) | hw_cread(CAP_ENDPTSTAT, ~0); | ||
424 | |||
425 | return test_bit(hw_ep_bit(num, dir), (void *)®); | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * hw_test_and_clear_setup_status: test & clear setup status (execute without | ||
430 | * interruption) | ||
431 | * @n: bit number (endpoint) | ||
432 | * | ||
433 | * This function returns setup status | ||
434 | */ | ||
435 | static int hw_test_and_clear_setup_status(int n) | ||
436 | { | ||
437 | return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n)); | ||
438 | } | ||
439 | |||
440 | /** | ||
441 | * hw_ep_prime: primes endpoint (execute without interruption) | ||
442 | * @num: endpoint number | ||
443 | * @dir: endpoint direction | ||
444 | * @is_ctrl: true if control endpoint | ||
445 | * | ||
446 | * This function returns an error code | ||
447 | */ | ||
448 | static int hw_ep_prime(int num, int dir, int is_ctrl) | ||
449 | { | ||
450 | int n = hw_ep_bit(num, dir); | ||
451 | |||
452 | /* the caller should flush first */ | ||
453 | if (hw_ep_is_primed(num, dir)) | ||
454 | return -EBUSY; | ||
455 | |||
456 | if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num))) | ||
457 | return -EAGAIN; | ||
458 | |||
459 | hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n)); | ||
460 | |||
461 | while (hw_cread(CAP_ENDPTPRIME, BIT(n))) | ||
462 | cpu_relax(); | ||
463 | if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num))) | ||
464 | return -EAGAIN; | ||
465 | |||
466 | /* status shoult be tested according with manual but it doesn't work */ | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | /** | ||
471 | * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute | ||
472 | * without interruption) | ||
473 | * @num: endpoint number | ||
474 | * @dir: endpoint direction | ||
475 | * @value: true => stall, false => unstall | ||
476 | * | ||
477 | * This function returns an error code | ||
478 | */ | ||
479 | static int hw_ep_set_halt(int num, int dir, int value) | ||
480 | { | ||
481 | if (value != 0 && value != 1) | ||
482 | return -EINVAL; | ||
483 | |||
484 | do { | ||
485 | u32 addr = CAP_ENDPTCTRL + num * sizeof(u32); | ||
486 | u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; | ||
487 | u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR; | ||
488 | |||
489 | /* data toggle - reserved for EP0 but it's in ESS */ | ||
490 | hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr); | ||
491 | |||
492 | } while (value != hw_ep_get_halt(num, dir)); | ||
493 | |||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | /** | ||
498 | * hw_intr_clear: disables interrupt & clears interrupt status (execute without | ||
499 | * interruption) | ||
500 | * @n: interrupt bit | ||
501 | * | ||
502 | * This function returns an error code | ||
503 | */ | ||
504 | static int hw_intr_clear(int n) | ||
505 | { | ||
506 | if (n >= REG_BITS) | ||
507 | return -EINVAL; | ||
508 | |||
509 | hw_cwrite(CAP_USBINTR, BIT(n), 0); | ||
510 | hw_cwrite(CAP_USBSTS, BIT(n), BIT(n)); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | /** | ||
515 | * hw_intr_force: enables interrupt & forces interrupt status (execute without | ||
516 | * interruption) | ||
517 | * @n: interrupt bit | ||
518 | * | ||
519 | * This function returns an error code | ||
520 | */ | ||
521 | static int hw_intr_force(int n) | ||
522 | { | ||
523 | if (n >= REG_BITS) | ||
524 | return -EINVAL; | ||
525 | |||
526 | hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE); | ||
527 | hw_cwrite(CAP_USBINTR, BIT(n), BIT(n)); | ||
528 | hw_cwrite(CAP_USBSTS, BIT(n), BIT(n)); | ||
529 | hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0); | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | /** | ||
534 | * hw_is_port_high_speed: test if port is high speed | ||
535 | * | ||
536 | * This function returns true if high speed port | ||
537 | */ | ||
538 | static int hw_port_is_high_speed(void) | ||
539 | { | ||
540 | return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) : | ||
541 | hw_cread(CAP_PORTSC, PORTSC_HSP); | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * hw_port_test_get: reads port test mode value | ||
546 | * | ||
547 | * This function returns port test mode value | ||
548 | */ | ||
549 | static u8 hw_port_test_get(void) | ||
550 | { | ||
551 | return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC); | ||
552 | } | ||
553 | |||
554 | /** | ||
555 | * hw_port_test_set: writes port test mode (execute without interruption) | ||
556 | * @mode: new value | ||
557 | * | ||
558 | * This function returns an error code | ||
559 | */ | ||
560 | static int hw_port_test_set(u8 mode) | ||
561 | { | ||
562 | const u8 TEST_MODE_MAX = 7; | ||
563 | |||
564 | if (mode > TEST_MODE_MAX) | ||
565 | return -EINVAL; | ||
566 | |||
567 | hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC)); | ||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | /** | ||
572 | * hw_read_intr_enable: returns interrupt enable register | ||
573 | * | ||
574 | * This function returns register data | ||
575 | */ | ||
576 | static u32 hw_read_intr_enable(void) | ||
577 | { | ||
578 | return hw_cread(CAP_USBINTR, ~0); | ||
579 | } | ||
580 | |||
581 | /** | ||
582 | * hw_read_intr_status: returns interrupt status register | ||
583 | * | ||
584 | * This function returns register data | ||
585 | */ | ||
586 | static u32 hw_read_intr_status(void) | ||
587 | { | ||
588 | return hw_cread(CAP_USBSTS, ~0); | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * hw_register_read: reads all device registers (execute without interruption) | ||
593 | * @buf: destination buffer | ||
594 | * @size: buffer size | ||
595 | * | ||
596 | * This function returns number of registers read | ||
597 | */ | ||
598 | static size_t hw_register_read(u32 *buf, size_t size) | ||
599 | { | ||
600 | unsigned i; | ||
601 | |||
602 | if (size > hw_bank.size) | ||
603 | size = hw_bank.size; | ||
604 | |||
605 | for (i = 0; i < size; i++) | ||
606 | buf[i] = hw_aread(i * sizeof(u32), ~0); | ||
607 | |||
608 | return size; | ||
609 | } | ||
610 | |||
611 | /** | ||
612 | * hw_register_write: writes to register | ||
613 | * @addr: register address | ||
614 | * @data: register value | ||
615 | * | ||
616 | * This function returns an error code | ||
617 | */ | ||
618 | static int hw_register_write(u16 addr, u32 data) | ||
619 | { | ||
620 | /* align */ | ||
621 | addr /= sizeof(u32); | ||
622 | |||
623 | if (addr >= hw_bank.size) | ||
624 | return -EINVAL; | ||
625 | |||
626 | /* align */ | ||
627 | addr *= sizeof(u32); | ||
628 | |||
629 | hw_awrite(addr, ~0, data); | ||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | /** | ||
634 | * hw_test_and_clear_complete: test & clear complete status (execute without | ||
635 | * interruption) | ||
636 | * @n: bit number (endpoint) | ||
637 | * | ||
638 | * This function returns complete status | ||
639 | */ | ||
640 | static int hw_test_and_clear_complete(int n) | ||
641 | { | ||
642 | return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n)); | ||
643 | } | ||
644 | |||
645 | /** | ||
646 | * hw_test_and_clear_intr_active: test & clear active interrupts (execute | ||
647 | * without interruption) | ||
648 | * | ||
649 | * This function returns active interrutps | ||
650 | */ | ||
651 | static u32 hw_test_and_clear_intr_active(void) | ||
652 | { | ||
653 | u32 reg = hw_read_intr_status() & hw_read_intr_enable(); | ||
654 | |||
655 | hw_cwrite(CAP_USBSTS, ~0, reg); | ||
656 | return reg; | ||
657 | } | ||
658 | |||
659 | /** | ||
660 | * hw_test_and_clear_setup_guard: test & clear setup guard (execute without | ||
661 | * interruption) | ||
662 | * | ||
663 | * This function returns guard value | ||
664 | */ | ||
665 | static int hw_test_and_clear_setup_guard(void) | ||
666 | { | ||
667 | return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0); | ||
668 | } | ||
669 | |||
670 | /** | ||
671 | * hw_test_and_set_setup_guard: test & set setup guard (execute without | ||
672 | * interruption) | ||
673 | * | ||
674 | * This function returns guard value | ||
675 | */ | ||
676 | static int hw_test_and_set_setup_guard(void) | ||
677 | { | ||
678 | return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW); | ||
679 | } | ||
680 | |||
681 | /** | ||
682 | * hw_usb_set_address: configures USB address (execute without interruption) | ||
683 | * @value: new USB address | ||
684 | * | ||
685 | * This function returns an error code | ||
686 | */ | ||
687 | static int hw_usb_set_address(u8 value) | ||
688 | { | ||
689 | /* advance */ | ||
690 | hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA, | ||
691 | value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA); | ||
692 | return 0; | ||
693 | } | ||
694 | |||
695 | /** | ||
696 | * hw_usb_reset: restart device after a bus reset (execute without | ||
697 | * interruption) | ||
698 | * | ||
699 | * This function returns an error code | ||
700 | */ | ||
701 | static int hw_usb_reset(void) | ||
702 | { | ||
703 | hw_usb_set_address(0); | ||
704 | |||
705 | /* ESS flushes only at end?!? */ | ||
706 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); /* flush all EPs */ | ||
707 | |||
708 | /* clear setup token semaphores */ | ||
709 | hw_cwrite(CAP_ENDPTSETUPSTAT, 0, 0); /* writes its content */ | ||
710 | |||
711 | /* clear complete status */ | ||
712 | hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */ | ||
713 | |||
714 | /* wait until all bits cleared */ | ||
715 | while (hw_cread(CAP_ENDPTPRIME, ~0)) | ||
716 | udelay(10); /* not RTOS friendly */ | ||
717 | |||
718 | /* reset all endpoints ? */ | ||
719 | |||
720 | /* reset internal status and wait for further instructions | ||
721 | no need to verify the port reset status (ESS does it) */ | ||
722 | |||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | /****************************************************************************** | ||
727 | * DBG block | ||
728 | *****************************************************************************/ | ||
729 | /** | ||
730 | * show_device: prints information about device capabilities and status | ||
731 | * | ||
732 | * Check "device.h" for details | ||
733 | */ | ||
734 | static ssize_t show_device(struct device *dev, struct device_attribute *attr, | ||
735 | char *buf) | ||
736 | { | ||
737 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
738 | struct usb_gadget *gadget = &udc->gadget; | ||
739 | int n = 0; | ||
740 | |||
741 | dbg_trace("[%s] %p\n", __func__, buf); | ||
742 | if (attr == NULL || buf == NULL) { | ||
743 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", | ||
748 | gadget->speed); | ||
749 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", | ||
750 | gadget->is_dualspeed); | ||
751 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", | ||
752 | gadget->is_otg); | ||
753 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", | ||
754 | gadget->is_a_peripheral); | ||
755 | n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n", | ||
756 | gadget->b_hnp_enable); | ||
757 | n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n", | ||
758 | gadget->a_hnp_support); | ||
759 | n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n", | ||
760 | gadget->a_alt_hnp_support); | ||
761 | n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n", | ||
762 | (gadget->name ? gadget->name : "")); | ||
763 | |||
764 | return n; | ||
765 | } | ||
766 | static DEVICE_ATTR(device, S_IRUSR, show_device, NULL); | ||
767 | |||
768 | /** | ||
769 | * show_driver: prints information about attached gadget (if any) | ||
770 | * | ||
771 | * Check "device.h" for details | ||
772 | */ | ||
773 | static ssize_t show_driver(struct device *dev, struct device_attribute *attr, | ||
774 | char *buf) | ||
775 | { | ||
776 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
777 | struct usb_gadget_driver *driver = udc->driver; | ||
778 | int n = 0; | ||
779 | |||
780 | dbg_trace("[%s] %p\n", __func__, buf); | ||
781 | if (attr == NULL || buf == NULL) { | ||
782 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | if (driver == NULL) | ||
787 | return scnprintf(buf, PAGE_SIZE, | ||
788 | "There is no gadget attached!\n"); | ||
789 | |||
790 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", | ||
791 | (driver->function ? driver->function : "")); | ||
792 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", | ||
793 | driver->speed); | ||
794 | |||
795 | return n; | ||
796 | } | ||
797 | static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL); | ||
798 | |||
799 | /* Maximum event message length */ | ||
800 | #define DBG_DATA_MSG 64UL | ||
801 | |||
802 | /* Maximum event messages */ | ||
803 | #define DBG_DATA_MAX 128UL | ||
804 | |||
805 | /* Event buffer descriptor */ | ||
806 | static struct { | ||
807 | char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */ | ||
808 | unsigned idx; /* index */ | ||
809 | unsigned tty; /* print to console? */ | ||
810 | rwlock_t lck; /* lock */ | ||
811 | } dbg_data = { | ||
812 | .idx = 0, | ||
813 | .tty = 0, | ||
814 | .lck = __RW_LOCK_UNLOCKED(lck) | ||
815 | }; | ||
816 | |||
817 | /** | ||
818 | * dbg_dec: decrements debug event index | ||
819 | * @idx: buffer index | ||
820 | */ | ||
821 | static void dbg_dec(unsigned *idx) | ||
822 | { | ||
823 | *idx = (*idx - 1) & (DBG_DATA_MAX-1); | ||
824 | } | ||
825 | |||
826 | /** | ||
827 | * dbg_inc: increments debug event index | ||
828 | * @idx: buffer index | ||
829 | */ | ||
830 | static void dbg_inc(unsigned *idx) | ||
831 | { | ||
832 | *idx = (*idx + 1) & (DBG_DATA_MAX-1); | ||
833 | } | ||
834 | |||
835 | /** | ||
836 | * dbg_print: prints the common part of the event | ||
837 | * @addr: endpoint address | ||
838 | * @name: event name | ||
839 | * @status: status | ||
840 | * @extra: extra information | ||
841 | */ | ||
842 | static void dbg_print(u8 addr, const char *name, int status, const char *extra) | ||
843 | { | ||
844 | struct timeval tval; | ||
845 | unsigned int stamp; | ||
846 | unsigned long flags; | ||
847 | |||
848 | write_lock_irqsave(&dbg_data.lck, flags); | ||
849 | |||
850 | do_gettimeofday(&tval); | ||
851 | stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */ | ||
852 | stamp = stamp * 1000000 + tval.tv_usec; | ||
853 | |||
854 | scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, | ||
855 | "%04X\t» %02X %-7.7s %4i «\t%s\n", | ||
856 | stamp, addr, name, status, extra); | ||
857 | |||
858 | dbg_inc(&dbg_data.idx); | ||
859 | |||
860 | write_unlock_irqrestore(&dbg_data.lck, flags); | ||
861 | |||
862 | if (dbg_data.tty != 0) | ||
863 | pr_notice("%04X\t» %02X %-7.7s %4i «\t%s\n", | ||
864 | stamp, addr, name, status, extra); | ||
865 | } | ||
866 | |||
867 | /** | ||
868 | * dbg_done: prints a DONE event | ||
869 | * @addr: endpoint address | ||
870 | * @td: transfer descriptor | ||
871 | * @status: status | ||
872 | */ | ||
873 | static void dbg_done(u8 addr, const u32 token, int status) | ||
874 | { | ||
875 | char msg[DBG_DATA_MSG]; | ||
876 | |||
877 | scnprintf(msg, sizeof(msg), "%d %02X", | ||
878 | (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES), | ||
879 | (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS)); | ||
880 | dbg_print(addr, "DONE", status, msg); | ||
881 | } | ||
882 | |||
883 | /** | ||
884 | * dbg_event: prints a generic event | ||
885 | * @addr: endpoint address | ||
886 | * @name: event name | ||
887 | * @status: status | ||
888 | */ | ||
889 | static void dbg_event(u8 addr, const char *name, int status) | ||
890 | { | ||
891 | if (name != NULL) | ||
892 | dbg_print(addr, name, status, ""); | ||
893 | } | ||
894 | |||
895 | /* | ||
896 | * dbg_queue: prints a QUEUE event | ||
897 | * @addr: endpoint address | ||
898 | * @req: USB request | ||
899 | * @status: status | ||
900 | */ | ||
901 | static void dbg_queue(u8 addr, const struct usb_request *req, int status) | ||
902 | { | ||
903 | char msg[DBG_DATA_MSG]; | ||
904 | |||
905 | if (req != NULL) { | ||
906 | scnprintf(msg, sizeof(msg), | ||
907 | "%d %d", !req->no_interrupt, req->length); | ||
908 | dbg_print(addr, "QUEUE", status, msg); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | /** | ||
913 | * dbg_setup: prints a SETUP event | ||
914 | * @addr: endpoint address | ||
915 | * @req: setup request | ||
916 | */ | ||
917 | static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req) | ||
918 | { | ||
919 | char msg[DBG_DATA_MSG]; | ||
920 | |||
921 | if (req != NULL) { | ||
922 | scnprintf(msg, sizeof(msg), | ||
923 | "%02X %02X %04X %04X %d", req->bRequestType, | ||
924 | req->bRequest, le16_to_cpu(req->wValue), | ||
925 | le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength)); | ||
926 | dbg_print(addr, "SETUP", 0, msg); | ||
927 | } | ||
928 | } | ||
929 | |||
930 | /** | ||
931 | * show_events: displays the event buffer | ||
932 | * | ||
933 | * Check "device.h" for details | ||
934 | */ | ||
935 | static ssize_t show_events(struct device *dev, struct device_attribute *attr, | ||
936 | char *buf) | ||
937 | { | ||
938 | unsigned long flags; | ||
939 | unsigned i, j, n = 0; | ||
940 | |||
941 | dbg_trace("[%s] %p\n", __func__, buf); | ||
942 | if (attr == NULL || buf == NULL) { | ||
943 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
944 | return 0; | ||
945 | } | ||
946 | |||
947 | read_lock_irqsave(&dbg_data.lck, flags); | ||
948 | |||
949 | i = dbg_data.idx; | ||
950 | for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) { | ||
951 | n += strlen(dbg_data.buf[i]); | ||
952 | if (n >= PAGE_SIZE) { | ||
953 | n -= strlen(dbg_data.buf[i]); | ||
954 | break; | ||
955 | } | ||
956 | } | ||
957 | for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i)) | ||
958 | j += scnprintf(buf + j, PAGE_SIZE - j, | ||
959 | "%s", dbg_data.buf[i]); | ||
960 | |||
961 | read_unlock_irqrestore(&dbg_data.lck, flags); | ||
962 | |||
963 | return n; | ||
964 | } | ||
965 | |||
966 | /** | ||
967 | * store_events: configure if events are going to be also printed to console | ||
968 | * | ||
969 | * Check "device.h" for details | ||
970 | */ | ||
971 | static ssize_t store_events(struct device *dev, struct device_attribute *attr, | ||
972 | const char *buf, size_t count) | ||
973 | { | ||
974 | unsigned tty; | ||
975 | |||
976 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
977 | if (attr == NULL || buf == NULL) { | ||
978 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
979 | goto done; | ||
980 | } | ||
981 | |||
982 | if (sscanf(buf, "%u", &tty) != 1 || tty > 1) { | ||
983 | dev_err(dev, "<1|0>: enable|disable console log\n"); | ||
984 | goto done; | ||
985 | } | ||
986 | |||
987 | dbg_data.tty = tty; | ||
988 | dev_info(dev, "tty = %u", dbg_data.tty); | ||
989 | |||
990 | done: | ||
991 | return count; | ||
992 | } | ||
993 | static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events); | ||
994 | |||
995 | /** | ||
996 | * show_inters: interrupt status, enable status and historic | ||
997 | * | ||
998 | * Check "device.h" for details | ||
999 | */ | ||
1000 | static ssize_t show_inters(struct device *dev, struct device_attribute *attr, | ||
1001 | char *buf) | ||
1002 | { | ||
1003 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1004 | unsigned long flags; | ||
1005 | u32 intr; | ||
1006 | unsigned i, j, n = 0; | ||
1007 | |||
1008 | dbg_trace("[%s] %p\n", __func__, buf); | ||
1009 | if (attr == NULL || buf == NULL) { | ||
1010 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1011 | return 0; | ||
1012 | } | ||
1013 | |||
1014 | spin_lock_irqsave(udc->lock, flags); | ||
1015 | |||
1016 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1017 | "status = %08x\n", hw_read_intr_status()); | ||
1018 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1019 | "enable = %08x\n", hw_read_intr_enable()); | ||
1020 | |||
1021 | n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n", | ||
1022 | isr_statistics.test); | ||
1023 | n += scnprintf(buf + n, PAGE_SIZE - n, "» ui = %d\n", | ||
1024 | isr_statistics.ui); | ||
1025 | n += scnprintf(buf + n, PAGE_SIZE - n, "» uei = %d\n", | ||
1026 | isr_statistics.uei); | ||
1027 | n += scnprintf(buf + n, PAGE_SIZE - n, "» pci = %d\n", | ||
1028 | isr_statistics.pci); | ||
1029 | n += scnprintf(buf + n, PAGE_SIZE - n, "» uri = %d\n", | ||
1030 | isr_statistics.uri); | ||
1031 | n += scnprintf(buf + n, PAGE_SIZE - n, "» sli = %d\n", | ||
1032 | isr_statistics.sli); | ||
1033 | n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n", | ||
1034 | isr_statistics.none); | ||
1035 | n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n", | ||
1036 | isr_statistics.hndl.cnt); | ||
1037 | |||
1038 | for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) { | ||
1039 | i &= ISR_MASK; | ||
1040 | intr = isr_statistics.hndl.buf[i]; | ||
1041 | |||
1042 | if (USBi_UI & intr) | ||
1043 | n += scnprintf(buf + n, PAGE_SIZE - n, "ui "); | ||
1044 | intr &= ~USBi_UI; | ||
1045 | if (USBi_UEI & intr) | ||
1046 | n += scnprintf(buf + n, PAGE_SIZE - n, "uei "); | ||
1047 | intr &= ~USBi_UEI; | ||
1048 | if (USBi_PCI & intr) | ||
1049 | n += scnprintf(buf + n, PAGE_SIZE - n, "pci "); | ||
1050 | intr &= ~USBi_PCI; | ||
1051 | if (USBi_URI & intr) | ||
1052 | n += scnprintf(buf + n, PAGE_SIZE - n, "uri "); | ||
1053 | intr &= ~USBi_URI; | ||
1054 | if (USBi_SLI & intr) | ||
1055 | n += scnprintf(buf + n, PAGE_SIZE - n, "sli "); | ||
1056 | intr &= ~USBi_SLI; | ||
1057 | if (intr) | ||
1058 | n += scnprintf(buf + n, PAGE_SIZE - n, "??? "); | ||
1059 | if (isr_statistics.hndl.buf[i]) | ||
1060 | n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); | ||
1061 | } | ||
1062 | |||
1063 | spin_unlock_irqrestore(udc->lock, flags); | ||
1064 | |||
1065 | return n; | ||
1066 | } | ||
1067 | |||
1068 | /** | ||
1069 | * store_inters: enable & force or disable an individual interrutps | ||
1070 | * (to be used for test purposes only) | ||
1071 | * | ||
1072 | * Check "device.h" for details | ||
1073 | */ | ||
1074 | static ssize_t store_inters(struct device *dev, struct device_attribute *attr, | ||
1075 | const char *buf, size_t count) | ||
1076 | { | ||
1077 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1078 | unsigned long flags; | ||
1079 | unsigned en, bit; | ||
1080 | |||
1081 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
1082 | if (attr == NULL || buf == NULL) { | ||
1083 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1084 | goto done; | ||
1085 | } | ||
1086 | |||
1087 | if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) { | ||
1088 | dev_err(dev, "<1|0> <bit>: enable|disable interrupt"); | ||
1089 | goto done; | ||
1090 | } | ||
1091 | |||
1092 | spin_lock_irqsave(udc->lock, flags); | ||
1093 | if (en) { | ||
1094 | if (hw_intr_force(bit)) | ||
1095 | dev_err(dev, "invalid bit number\n"); | ||
1096 | else | ||
1097 | isr_statistics.test++; | ||
1098 | } else { | ||
1099 | if (hw_intr_clear(bit)) | ||
1100 | dev_err(dev, "invalid bit number\n"); | ||
1101 | } | ||
1102 | spin_unlock_irqrestore(udc->lock, flags); | ||
1103 | |||
1104 | done: | ||
1105 | return count; | ||
1106 | } | ||
1107 | static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters); | ||
1108 | |||
1109 | /** | ||
1110 | * show_port_test: reads port test mode | ||
1111 | * | ||
1112 | * Check "device.h" for details | ||
1113 | */ | ||
1114 | static ssize_t show_port_test(struct device *dev, | ||
1115 | struct device_attribute *attr, char *buf) | ||
1116 | { | ||
1117 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1118 | unsigned long flags; | ||
1119 | unsigned mode; | ||
1120 | |||
1121 | dbg_trace("[%s] %p\n", __func__, buf); | ||
1122 | if (attr == NULL || buf == NULL) { | ||
1123 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1124 | return 0; | ||
1125 | } | ||
1126 | |||
1127 | spin_lock_irqsave(udc->lock, flags); | ||
1128 | mode = hw_port_test_get(); | ||
1129 | spin_unlock_irqrestore(udc->lock, flags); | ||
1130 | |||
1131 | return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode); | ||
1132 | } | ||
1133 | |||
1134 | /** | ||
1135 | * store_port_test: writes port test mode | ||
1136 | * | ||
1137 | * Check "device.h" for details | ||
1138 | */ | ||
1139 | static ssize_t store_port_test(struct device *dev, | ||
1140 | struct device_attribute *attr, | ||
1141 | const char *buf, size_t count) | ||
1142 | { | ||
1143 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1144 | unsigned long flags; | ||
1145 | unsigned mode; | ||
1146 | |||
1147 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
1148 | if (attr == NULL || buf == NULL) { | ||
1149 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1150 | goto done; | ||
1151 | } | ||
1152 | |||
1153 | if (sscanf(buf, "%u", &mode) != 1) { | ||
1154 | dev_err(dev, "<mode>: set port test mode"); | ||
1155 | goto done; | ||
1156 | } | ||
1157 | |||
1158 | spin_lock_irqsave(udc->lock, flags); | ||
1159 | if (hw_port_test_set(mode)) | ||
1160 | dev_err(dev, "invalid mode\n"); | ||
1161 | spin_unlock_irqrestore(udc->lock, flags); | ||
1162 | |||
1163 | done: | ||
1164 | return count; | ||
1165 | } | ||
1166 | static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR, | ||
1167 | show_port_test, store_port_test); | ||
1168 | |||
1169 | /** | ||
1170 | * show_qheads: DMA contents of all queue heads | ||
1171 | * | ||
1172 | * Check "device.h" for details | ||
1173 | */ | ||
1174 | static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, | ||
1175 | char *buf) | ||
1176 | { | ||
1177 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1178 | unsigned long flags; | ||
1179 | unsigned i, j, n = 0; | ||
1180 | |||
1181 | dbg_trace("[%s] %p\n", __func__, buf); | ||
1182 | if (attr == NULL || buf == NULL) { | ||
1183 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | spin_lock_irqsave(udc->lock, flags); | ||
1188 | for (i = 0; i < hw_ep_max; i++) { | ||
1189 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | ||
1190 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1191 | "EP=%02i: RX=%08X TX=%08X\n", | ||
1192 | i, (u32)mEp->qh[RX].dma, (u32)mEp->qh[TX].dma); | ||
1193 | for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) { | ||
1194 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1195 | " %04X: %08X %08X\n", j, | ||
1196 | *((u32 *)mEp->qh[RX].ptr + j), | ||
1197 | *((u32 *)mEp->qh[TX].ptr + j)); | ||
1198 | } | ||
1199 | } | ||
1200 | spin_unlock_irqrestore(udc->lock, flags); | ||
1201 | |||
1202 | return n; | ||
1203 | } | ||
1204 | static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL); | ||
1205 | |||
1206 | /** | ||
1207 | * show_registers: dumps all registers | ||
1208 | * | ||
1209 | * Check "device.h" for details | ||
1210 | */ | ||
1211 | static ssize_t show_registers(struct device *dev, | ||
1212 | struct device_attribute *attr, char *buf) | ||
1213 | { | ||
1214 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1215 | unsigned long flags; | ||
1216 | u32 dump[512]; | ||
1217 | unsigned i, k, n = 0; | ||
1218 | |||
1219 | dbg_trace("[%s] %p\n", __func__, buf); | ||
1220 | if (attr == NULL || buf == NULL) { | ||
1221 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1222 | return 0; | ||
1223 | } | ||
1224 | |||
1225 | spin_lock_irqsave(udc->lock, flags); | ||
1226 | k = hw_register_read(dump, sizeof(dump)/sizeof(u32)); | ||
1227 | spin_unlock_irqrestore(udc->lock, flags); | ||
1228 | |||
1229 | for (i = 0; i < k; i++) { | ||
1230 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1231 | "reg[0x%04X] = 0x%08X\n", | ||
1232 | i * (unsigned)sizeof(u32), dump[i]); | ||
1233 | } | ||
1234 | |||
1235 | return n; | ||
1236 | } | ||
1237 | |||
1238 | /** | ||
1239 | * store_registers: writes value to register address | ||
1240 | * | ||
1241 | * Check "device.h" for details | ||
1242 | */ | ||
1243 | static ssize_t store_registers(struct device *dev, | ||
1244 | struct device_attribute *attr, | ||
1245 | const char *buf, size_t count) | ||
1246 | { | ||
1247 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1248 | unsigned long addr, data, flags; | ||
1249 | |||
1250 | dbg_trace("[%s] %p, %d\n", __func__, buf, count); | ||
1251 | if (attr == NULL || buf == NULL) { | ||
1252 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1253 | goto done; | ||
1254 | } | ||
1255 | |||
1256 | if (sscanf(buf, "%li %li", &addr, &data) != 2) { | ||
1257 | dev_err(dev, "<addr> <data>: write data to register address"); | ||
1258 | goto done; | ||
1259 | } | ||
1260 | |||
1261 | spin_lock_irqsave(udc->lock, flags); | ||
1262 | if (hw_register_write(addr, data)) | ||
1263 | dev_err(dev, "invalid address range\n"); | ||
1264 | spin_unlock_irqrestore(udc->lock, flags); | ||
1265 | |||
1266 | done: | ||
1267 | return count; | ||
1268 | } | ||
1269 | static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR, | ||
1270 | show_registers, store_registers); | ||
1271 | |||
1272 | /** | ||
1273 | * show_requests: DMA contents of all requests currently queued (all endpts) | ||
1274 | * | ||
1275 | * Check "device.h" for details | ||
1276 | */ | ||
1277 | static ssize_t show_requests(struct device *dev, struct device_attribute *attr, | ||
1278 | char *buf) | ||
1279 | { | ||
1280 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||
1281 | unsigned long flags; | ||
1282 | struct list_head *ptr = NULL; | ||
1283 | struct ci13xxx_req *req = NULL; | ||
1284 | unsigned i, j, k, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32); | ||
1285 | |||
1286 | dbg_trace("[%s] %p\n", __func__, buf); | ||
1287 | if (attr == NULL || buf == NULL) { | ||
1288 | dev_err(dev, "[%s] EINVAL\n", __func__); | ||
1289 | return 0; | ||
1290 | } | ||
1291 | |||
1292 | spin_lock_irqsave(udc->lock, flags); | ||
1293 | for (i = 0; i < hw_ep_max; i++) | ||
1294 | for (k = RX; k <= TX; k++) | ||
1295 | list_for_each(ptr, &udc->ci13xxx_ep[i].qh[k].queue) | ||
1296 | { | ||
1297 | req = list_entry(ptr, | ||
1298 | struct ci13xxx_req, queue); | ||
1299 | |||
1300 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1301 | "EP=%02i: TD=%08X %s\n", | ||
1302 | i, (u32)req->dma, | ||
1303 | ((k == RX) ? "RX" : "TX")); | ||
1304 | |||
1305 | for (j = 0; j < qSize; j++) | ||
1306 | n += scnprintf(buf + n, PAGE_SIZE - n, | ||
1307 | " %04X: %08X\n", j, | ||
1308 | *((u32 *)req->ptr + j)); | ||
1309 | } | ||
1310 | spin_unlock_irqrestore(udc->lock, flags); | ||
1311 | |||
1312 | return n; | ||
1313 | } | ||
1314 | static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL); | ||
1315 | |||
1316 | /** | ||
1317 | * dbg_create_files: initializes the attribute interface | ||
1318 | * @dev: device | ||
1319 | * | ||
1320 | * This function returns an error code | ||
1321 | */ | ||
1322 | __maybe_unused static int dbg_create_files(struct device *dev) | ||
1323 | { | ||
1324 | int retval = 0; | ||
1325 | |||
1326 | if (dev == NULL) | ||
1327 | return -EINVAL; | ||
1328 | retval = device_create_file(dev, &dev_attr_device); | ||
1329 | if (retval) | ||
1330 | goto done; | ||
1331 | retval = device_create_file(dev, &dev_attr_driver); | ||
1332 | if (retval) | ||
1333 | goto rm_device; | ||
1334 | retval = device_create_file(dev, &dev_attr_events); | ||
1335 | if (retval) | ||
1336 | goto rm_driver; | ||
1337 | retval = device_create_file(dev, &dev_attr_inters); | ||
1338 | if (retval) | ||
1339 | goto rm_events; | ||
1340 | retval = device_create_file(dev, &dev_attr_port_test); | ||
1341 | if (retval) | ||
1342 | goto rm_inters; | ||
1343 | retval = device_create_file(dev, &dev_attr_qheads); | ||
1344 | if (retval) | ||
1345 | goto rm_port_test; | ||
1346 | retval = device_create_file(dev, &dev_attr_registers); | ||
1347 | if (retval) | ||
1348 | goto rm_qheads; | ||
1349 | retval = device_create_file(dev, &dev_attr_requests); | ||
1350 | if (retval) | ||
1351 | goto rm_registers; | ||
1352 | return 0; | ||
1353 | |||
1354 | rm_registers: | ||
1355 | device_remove_file(dev, &dev_attr_registers); | ||
1356 | rm_qheads: | ||
1357 | device_remove_file(dev, &dev_attr_qheads); | ||
1358 | rm_port_test: | ||
1359 | device_remove_file(dev, &dev_attr_port_test); | ||
1360 | rm_inters: | ||
1361 | device_remove_file(dev, &dev_attr_inters); | ||
1362 | rm_events: | ||
1363 | device_remove_file(dev, &dev_attr_events); | ||
1364 | rm_driver: | ||
1365 | device_remove_file(dev, &dev_attr_driver); | ||
1366 | rm_device: | ||
1367 | device_remove_file(dev, &dev_attr_device); | ||
1368 | done: | ||
1369 | return retval; | ||
1370 | } | ||
1371 | |||
1372 | /** | ||
1373 | * dbg_remove_files: destroys the attribute interface | ||
1374 | * @dev: device | ||
1375 | * | ||
1376 | * This function returns an error code | ||
1377 | */ | ||
1378 | __maybe_unused static int dbg_remove_files(struct device *dev) | ||
1379 | { | ||
1380 | if (dev == NULL) | ||
1381 | return -EINVAL; | ||
1382 | device_remove_file(dev, &dev_attr_requests); | ||
1383 | device_remove_file(dev, &dev_attr_registers); | ||
1384 | device_remove_file(dev, &dev_attr_qheads); | ||
1385 | device_remove_file(dev, &dev_attr_port_test); | ||
1386 | device_remove_file(dev, &dev_attr_inters); | ||
1387 | device_remove_file(dev, &dev_attr_events); | ||
1388 | device_remove_file(dev, &dev_attr_driver); | ||
1389 | device_remove_file(dev, &dev_attr_device); | ||
1390 | return 0; | ||
1391 | } | ||
1392 | |||
1393 | /****************************************************************************** | ||
1394 | * UTIL block | ||
1395 | *****************************************************************************/ | ||
1396 | /** | ||
1397 | * _usb_addr: calculates endpoint address from direction & number | ||
1398 | * @ep: endpoint | ||
1399 | */ | ||
1400 | static inline u8 _usb_addr(struct ci13xxx_ep *ep) | ||
1401 | { | ||
1402 | return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num; | ||
1403 | } | ||
1404 | |||
1405 | /** | ||
1406 | * _hardware_queue: configures a request at hardware level | ||
1407 | * @gadget: gadget | ||
1408 | * @mEp: endpoint | ||
1409 | * | ||
1410 | * This function returns an error code | ||
1411 | */ | ||
1412 | static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | ||
1413 | { | ||
1414 | unsigned i; | ||
1415 | |||
1416 | trace("%p, %p", mEp, mReq); | ||
1417 | |||
1418 | /* don't queue twice */ | ||
1419 | if (mReq->req.status == -EALREADY) | ||
1420 | return -EALREADY; | ||
1421 | |||
1422 | if (hw_ep_is_primed(mEp->num, mEp->dir)) | ||
1423 | return -EBUSY; | ||
1424 | |||
1425 | mReq->req.status = -EALREADY; | ||
1426 | |||
1427 | if (mReq->req.length && !mReq->req.dma) { | ||
1428 | mReq->req.dma = \ | ||
1429 | dma_map_single(mEp->device, mReq->req.buf, | ||
1430 | mReq->req.length, mEp->dir ? | ||
1431 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
1432 | if (mReq->req.dma == 0) | ||
1433 | return -ENOMEM; | ||
1434 | |||
1435 | mReq->map = 1; | ||
1436 | } | ||
1437 | |||
1438 | /* | ||
1439 | * TD configuration | ||
1440 | * TODO - handle requests which spawns into several TDs | ||
1441 | */ | ||
1442 | memset(mReq->ptr, 0, sizeof(*mReq->ptr)); | ||
1443 | mReq->ptr->next |= TD_TERMINATE; | ||
1444 | mReq->ptr->token = mReq->req.length << ffs_nr(TD_TOTAL_BYTES); | ||
1445 | mReq->ptr->token &= TD_TOTAL_BYTES; | ||
1446 | mReq->ptr->token |= TD_IOC; | ||
1447 | mReq->ptr->token |= TD_STATUS_ACTIVE; | ||
1448 | mReq->ptr->page[0] = mReq->req.dma; | ||
1449 | for (i = 1; i < 5; i++) | ||
1450 | mReq->ptr->page[i] = | ||
1451 | (mReq->req.dma + i * PAGE_SIZE) & ~TD_RESERVED_MASK; | ||
1452 | |||
1453 | /* | ||
1454 | * QH configuration | ||
1455 | * At this point it's guaranteed exclusive access to qhead | ||
1456 | * (endpt is not primed) so it's no need to use tripwire | ||
1457 | */ | ||
1458 | mEp->qh[mEp->dir].ptr->td.next = mReq->dma; /* TERMINATE = 0 */ | ||
1459 | mEp->qh[mEp->dir].ptr->td.token &= ~TD_STATUS; /* clear status */ | ||
1460 | if (mReq->req.zero == 0) | ||
1461 | mEp->qh[mEp->dir].ptr->cap |= QH_ZLT; | ||
1462 | else | ||
1463 | mEp->qh[mEp->dir].ptr->cap &= ~QH_ZLT; | ||
1464 | |||
1465 | wmb(); /* synchronize before ep prime */ | ||
1466 | |||
1467 | return hw_ep_prime(mEp->num, mEp->dir, | ||
1468 | mEp->type == USB_ENDPOINT_XFER_CONTROL); | ||
1469 | } | ||
1470 | |||
1471 | /** | ||
1472 | * _hardware_dequeue: handles a request at hardware level | ||
1473 | * @gadget: gadget | ||
1474 | * @mEp: endpoint | ||
1475 | * | ||
1476 | * This function returns an error code | ||
1477 | */ | ||
1478 | static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | ||
1479 | { | ||
1480 | trace("%p, %p", mEp, mReq); | ||
1481 | |||
1482 | if (mReq->req.status != -EALREADY) | ||
1483 | return -EINVAL; | ||
1484 | |||
1485 | if (hw_ep_is_primed(mEp->num, mEp->dir)) | ||
1486 | hw_ep_flush(mEp->num, mEp->dir); | ||
1487 | |||
1488 | mReq->req.status = 0; | ||
1489 | |||
1490 | if (mReq->map) { | ||
1491 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | ||
1492 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
1493 | mReq->req.dma = 0; | ||
1494 | mReq->map = 0; | ||
1495 | } | ||
1496 | |||
1497 | mReq->req.status = mReq->ptr->token & TD_STATUS; | ||
1498 | if ((TD_STATUS_ACTIVE & mReq->req.status) != 0) | ||
1499 | mReq->req.status = -ECONNRESET; | ||
1500 | else if ((TD_STATUS_HALTED & mReq->req.status) != 0) | ||
1501 | mReq->req.status = -1; | ||
1502 | else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0) | ||
1503 | mReq->req.status = -1; | ||
1504 | else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0) | ||
1505 | mReq->req.status = -1; | ||
1506 | |||
1507 | mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES; | ||
1508 | mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES); | ||
1509 | mReq->req.actual = mReq->req.length - mReq->req.actual; | ||
1510 | mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual; | ||
1511 | |||
1512 | return mReq->req.actual; | ||
1513 | } | ||
1514 | |||
1515 | /** | ||
1516 | * _ep_nuke: dequeues all endpoint requests | ||
1517 | * @mEp: endpoint | ||
1518 | * | ||
1519 | * This function returns an error code | ||
1520 | * Caller must hold lock | ||
1521 | */ | ||
1522 | static int _ep_nuke(struct ci13xxx_ep *mEp) | ||
1523 | __releases(mEp->lock) | ||
1524 | __acquires(mEp->lock) | ||
1525 | { | ||
1526 | trace("%p", mEp); | ||
1527 | |||
1528 | if (mEp == NULL) | ||
1529 | return -EINVAL; | ||
1530 | |||
1531 | hw_ep_flush(mEp->num, mEp->dir); | ||
1532 | |||
1533 | while (!list_empty(&mEp->qh[mEp->dir].queue)) { | ||
1534 | |||
1535 | /* pop oldest request */ | ||
1536 | struct ci13xxx_req *mReq = \ | ||
1537 | list_entry(mEp->qh[mEp->dir].queue.next, | ||
1538 | struct ci13xxx_req, queue); | ||
1539 | list_del_init(&mReq->queue); | ||
1540 | mReq->req.status = -ESHUTDOWN; | ||
1541 | |||
1542 | if (!mReq->req.no_interrupt && mReq->req.complete != NULL) { | ||
1543 | spin_unlock(mEp->lock); | ||
1544 | mReq->req.complete(&mEp->ep, &mReq->req); | ||
1545 | spin_lock(mEp->lock); | ||
1546 | } | ||
1547 | } | ||
1548 | return 0; | ||
1549 | } | ||
1550 | |||
1551 | /** | ||
1552 | * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts | ||
1553 | * @gadget: gadget | ||
1554 | * | ||
1555 | * This function returns an error code | ||
1556 | * Caller must hold lock | ||
1557 | */ | ||
1558 | static int _gadget_stop_activity(struct usb_gadget *gadget) | ||
1559 | __releases(udc->lock) | ||
1560 | __acquires(udc->lock) | ||
1561 | { | ||
1562 | struct usb_ep *ep; | ||
1563 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); | ||
1564 | struct ci13xxx_ep *mEp = container_of(gadget->ep0, | ||
1565 | struct ci13xxx_ep, ep); | ||
1566 | |||
1567 | trace("%p", gadget); | ||
1568 | |||
1569 | if (gadget == NULL) | ||
1570 | return -EINVAL; | ||
1571 | |||
1572 | spin_unlock(udc->lock); | ||
1573 | |||
1574 | /* flush all endpoints */ | ||
1575 | gadget_for_each_ep(ep, gadget) { | ||
1576 | usb_ep_fifo_flush(ep); | ||
1577 | } | ||
1578 | usb_ep_fifo_flush(gadget->ep0); | ||
1579 | |||
1580 | udc->driver->disconnect(gadget); | ||
1581 | |||
1582 | /* make sure to disable all endpoints */ | ||
1583 | gadget_for_each_ep(ep, gadget) { | ||
1584 | usb_ep_disable(ep); | ||
1585 | } | ||
1586 | usb_ep_disable(gadget->ep0); | ||
1587 | |||
1588 | if (mEp->status != NULL) { | ||
1589 | usb_ep_free_request(gadget->ep0, mEp->status); | ||
1590 | mEp->status = NULL; | ||
1591 | } | ||
1592 | |||
1593 | spin_lock(udc->lock); | ||
1594 | |||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1598 | /****************************************************************************** | ||
1599 | * ISR block | ||
1600 | *****************************************************************************/ | ||
1601 | /** | ||
1602 | * isr_reset_handler: USB reset interrupt handler | ||
1603 | * @udc: UDC device | ||
1604 | * | ||
1605 | * This function resets USB engine after a bus reset occurred | ||
1606 | */ | ||
1607 | static void isr_reset_handler(struct ci13xxx *udc) | ||
1608 | __releases(udc->lock) | ||
1609 | __acquires(udc->lock) | ||
1610 | { | ||
1611 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[0]; | ||
1612 | int retval; | ||
1613 | |||
1614 | trace("%p", udc); | ||
1615 | |||
1616 | if (udc == NULL) { | ||
1617 | err("EINVAL"); | ||
1618 | return; | ||
1619 | } | ||
1620 | |||
1621 | dbg_event(0xFF, "BUS RST", 0); | ||
1622 | |||
1623 | retval = _gadget_stop_activity(&udc->gadget); | ||
1624 | if (retval) | ||
1625 | goto done; | ||
1626 | |||
1627 | retval = hw_usb_reset(); | ||
1628 | if (retval) | ||
1629 | goto done; | ||
1630 | |||
1631 | spin_unlock(udc->lock); | ||
1632 | retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); | ||
1633 | if (!retval) { | ||
1634 | mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_KERNEL); | ||
1635 | if (mEp->status == NULL) { | ||
1636 | usb_ep_disable(&mEp->ep); | ||
1637 | retval = -ENOMEM; | ||
1638 | } | ||
1639 | } | ||
1640 | spin_lock(udc->lock); | ||
1641 | |||
1642 | done: | ||
1643 | if (retval) | ||
1644 | err("error: %i", retval); | ||
1645 | } | ||
1646 | |||
1647 | /** | ||
1648 | * isr_get_status_complete: get_status request complete function | ||
1649 | * @ep: endpoint | ||
1650 | * @req: request handled | ||
1651 | * | ||
1652 | * Caller must release lock | ||
1653 | */ | ||
1654 | static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) | ||
1655 | { | ||
1656 | trace("%p, %p", ep, req); | ||
1657 | |||
1658 | if (ep == NULL || req == NULL) { | ||
1659 | err("EINVAL"); | ||
1660 | return; | ||
1661 | } | ||
1662 | |||
1663 | kfree(req->buf); | ||
1664 | usb_ep_free_request(ep, req); | ||
1665 | } | ||
1666 | |||
1667 | /** | ||
1668 | * isr_get_status_response: get_status request response | ||
1669 | * @ep: endpoint | ||
1670 | * @setup: setup request packet | ||
1671 | * | ||
1672 | * This function returns an error code | ||
1673 | */ | ||
1674 | static int isr_get_status_response(struct ci13xxx_ep *mEp, | ||
1675 | struct usb_ctrlrequest *setup) | ||
1676 | __releases(mEp->lock) | ||
1677 | __acquires(mEp->lock) | ||
1678 | { | ||
1679 | struct usb_request *req = NULL; | ||
1680 | gfp_t gfp_flags = GFP_ATOMIC; | ||
1681 | int dir, num, retval; | ||
1682 | |||
1683 | trace("%p, %p", mEp, setup); | ||
1684 | |||
1685 | if (mEp == NULL || setup == NULL) | ||
1686 | return -EINVAL; | ||
1687 | |||
1688 | spin_unlock(mEp->lock); | ||
1689 | req = usb_ep_alloc_request(&mEp->ep, gfp_flags); | ||
1690 | spin_lock(mEp->lock); | ||
1691 | if (req == NULL) | ||
1692 | return -ENOMEM; | ||
1693 | |||
1694 | req->complete = isr_get_status_complete; | ||
1695 | req->length = 2; | ||
1696 | req->buf = kzalloc(req->length, gfp_flags); | ||
1697 | if (req->buf == NULL) { | ||
1698 | retval = -ENOMEM; | ||
1699 | goto err_free_req; | ||
1700 | } | ||
1701 | |||
1702 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | ||
1703 | /* TODO: D1 - Remote Wakeup; D0 - Self Powered */ | ||
1704 | retval = 0; | ||
1705 | } else if ((setup->bRequestType & USB_RECIP_MASK) \ | ||
1706 | == USB_RECIP_ENDPOINT) { | ||
1707 | dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ? | ||
1708 | TX : RX; | ||
1709 | num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK; | ||
1710 | *((u16 *)req->buf) = hw_ep_get_halt(num, dir); | ||
1711 | } | ||
1712 | /* else do nothing; reserved for future use */ | ||
1713 | |||
1714 | spin_unlock(mEp->lock); | ||
1715 | retval = usb_ep_queue(&mEp->ep, req, gfp_flags); | ||
1716 | spin_lock(mEp->lock); | ||
1717 | if (retval) | ||
1718 | goto err_free_buf; | ||
1719 | |||
1720 | return 0; | ||
1721 | |||
1722 | err_free_buf: | ||
1723 | kfree(req->buf); | ||
1724 | err_free_req: | ||
1725 | spin_unlock(mEp->lock); | ||
1726 | usb_ep_free_request(&mEp->ep, req); | ||
1727 | spin_lock(mEp->lock); | ||
1728 | return retval; | ||
1729 | } | ||
1730 | |||
1731 | /** | ||
1732 | * isr_setup_status_phase: queues the status phase of a setup transation | ||
1733 | * @mEp: endpoint | ||
1734 | * | ||
1735 | * This function returns an error code | ||
1736 | */ | ||
1737 | static int isr_setup_status_phase(struct ci13xxx_ep *mEp) | ||
1738 | __releases(mEp->lock) | ||
1739 | __acquires(mEp->lock) | ||
1740 | { | ||
1741 | int retval; | ||
1742 | |||
1743 | trace("%p", mEp); | ||
1744 | |||
1745 | /* mEp is always valid & configured */ | ||
1746 | |||
1747 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
1748 | mEp->dir = (mEp->dir == TX) ? RX : TX; | ||
1749 | |||
1750 | mEp->status->no_interrupt = 1; | ||
1751 | |||
1752 | spin_unlock(mEp->lock); | ||
1753 | retval = usb_ep_queue(&mEp->ep, mEp->status, GFP_ATOMIC); | ||
1754 | spin_lock(mEp->lock); | ||
1755 | |||
1756 | return retval; | ||
1757 | } | ||
1758 | |||
1759 | /** | ||
1760 | * isr_tr_complete_low: transaction complete low level handler | ||
1761 | * @mEp: endpoint | ||
1762 | * | ||
1763 | * This function returns an error code | ||
1764 | * Caller must hold lock | ||
1765 | */ | ||
1766 | static int isr_tr_complete_low(struct ci13xxx_ep *mEp) | ||
1767 | __releases(mEp->lock) | ||
1768 | __acquires(mEp->lock) | ||
1769 | { | ||
1770 | struct ci13xxx_req *mReq; | ||
1771 | int retval; | ||
1772 | |||
1773 | trace("%p", mEp); | ||
1774 | |||
1775 | if (list_empty(&mEp->qh[mEp->dir].queue)) | ||
1776 | return -EINVAL; | ||
1777 | |||
1778 | /* pop oldest request */ | ||
1779 | mReq = list_entry(mEp->qh[mEp->dir].queue.next, | ||
1780 | struct ci13xxx_req, queue); | ||
1781 | list_del_init(&mReq->queue); | ||
1782 | |||
1783 | retval = _hardware_dequeue(mEp, mReq); | ||
1784 | if (retval < 0) { | ||
1785 | dbg_event(_usb_addr(mEp), "DONE", retval); | ||
1786 | goto done; | ||
1787 | } | ||
1788 | |||
1789 | dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); | ||
1790 | |||
1791 | if (!mReq->req.no_interrupt && mReq->req.complete != NULL) { | ||
1792 | spin_unlock(mEp->lock); | ||
1793 | mReq->req.complete(&mEp->ep, &mReq->req); | ||
1794 | spin_lock(mEp->lock); | ||
1795 | } | ||
1796 | |||
1797 | if (!list_empty(&mEp->qh[mEp->dir].queue)) { | ||
1798 | mReq = list_entry(mEp->qh[mEp->dir].queue.next, | ||
1799 | struct ci13xxx_req, queue); | ||
1800 | _hardware_enqueue(mEp, mReq); | ||
1801 | } | ||
1802 | |||
1803 | done: | ||
1804 | return retval; | ||
1805 | } | ||
1806 | |||
1807 | /** | ||
1808 | * isr_tr_complete_handler: transaction complete interrupt handler | ||
1809 | * @udc: UDC descriptor | ||
1810 | * | ||
1811 | * This function handles traffic events | ||
1812 | */ | ||
1813 | static void isr_tr_complete_handler(struct ci13xxx *udc) | ||
1814 | __releases(udc->lock) | ||
1815 | __acquires(udc->lock) | ||
1816 | { | ||
1817 | unsigned i; | ||
1818 | |||
1819 | trace("%p", udc); | ||
1820 | |||
1821 | if (udc == NULL) { | ||
1822 | err("EINVAL"); | ||
1823 | return; | ||
1824 | } | ||
1825 | |||
1826 | for (i = 0; i < hw_ep_max; i++) { | ||
1827 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | ||
1828 | int type, num, err = -EINVAL; | ||
1829 | struct usb_ctrlrequest req; | ||
1830 | |||
1831 | |||
1832 | if (mEp->desc == NULL) | ||
1833 | continue; /* not configured */ | ||
1834 | |||
1835 | if ((mEp->dir == RX && hw_test_and_clear_complete(i)) || | ||
1836 | (mEp->dir == TX && hw_test_and_clear_complete(i + 16))) { | ||
1837 | err = isr_tr_complete_low(mEp); | ||
1838 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { | ||
1839 | if (err > 0) /* needs status phase */ | ||
1840 | err = isr_setup_status_phase(mEp); | ||
1841 | if (err < 0) { | ||
1842 | dbg_event(_usb_addr(mEp), | ||
1843 | "ERROR", err); | ||
1844 | spin_unlock(udc->lock); | ||
1845 | if (usb_ep_set_halt(&mEp->ep)) | ||
1846 | err("error: ep_set_halt"); | ||
1847 | spin_lock(udc->lock); | ||
1848 | } | ||
1849 | } | ||
1850 | } | ||
1851 | |||
1852 | if (mEp->type != USB_ENDPOINT_XFER_CONTROL || | ||
1853 | !hw_test_and_clear_setup_status(i)) | ||
1854 | continue; | ||
1855 | |||
1856 | if (i != 0) { | ||
1857 | warn("ctrl traffic received at endpoint"); | ||
1858 | continue; | ||
1859 | } | ||
1860 | |||
1861 | /* read_setup_packet */ | ||
1862 | do { | ||
1863 | hw_test_and_set_setup_guard(); | ||
1864 | memcpy(&req, &mEp->qh[RX].ptr->setup, sizeof(req)); | ||
1865 | } while (!hw_test_and_clear_setup_guard()); | ||
1866 | |||
1867 | type = req.bRequestType; | ||
1868 | |||
1869 | mEp->dir = (type & USB_DIR_IN) ? TX : RX; | ||
1870 | |||
1871 | dbg_setup(_usb_addr(mEp), &req); | ||
1872 | |||
1873 | switch (req.bRequest) { | ||
1874 | case USB_REQ_CLEAR_FEATURE: | ||
1875 | if (type != (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
1876 | le16_to_cpu(req.wValue) != USB_ENDPOINT_HALT) | ||
1877 | goto delegate; | ||
1878 | if (req.wLength != 0) | ||
1879 | break; | ||
1880 | num = le16_to_cpu(req.wIndex); | ||
1881 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
1882 | if (!udc->ci13xxx_ep[num].wedge) { | ||
1883 | spin_unlock(udc->lock); | ||
1884 | err = usb_ep_clear_halt( | ||
1885 | &udc->ci13xxx_ep[num].ep); | ||
1886 | spin_lock(udc->lock); | ||
1887 | if (err) | ||
1888 | break; | ||
1889 | } | ||
1890 | err = isr_setup_status_phase(mEp); | ||
1891 | break; | ||
1892 | case USB_REQ_GET_STATUS: | ||
1893 | if (type != (USB_DIR_IN|USB_RECIP_DEVICE) && | ||
1894 | type != (USB_DIR_IN|USB_RECIP_ENDPOINT) && | ||
1895 | type != (USB_DIR_IN|USB_RECIP_INTERFACE)) | ||
1896 | goto delegate; | ||
1897 | if (le16_to_cpu(req.wLength) != 2 || | ||
1898 | le16_to_cpu(req.wValue) != 0) | ||
1899 | break; | ||
1900 | err = isr_get_status_response(mEp, &req); | ||
1901 | break; | ||
1902 | case USB_REQ_SET_ADDRESS: | ||
1903 | if (type != (USB_DIR_OUT|USB_RECIP_DEVICE)) | ||
1904 | goto delegate; | ||
1905 | if (le16_to_cpu(req.wLength) != 0 || | ||
1906 | le16_to_cpu(req.wIndex) != 0) | ||
1907 | break; | ||
1908 | err = hw_usb_set_address((u8)le16_to_cpu(req.wValue)); | ||
1909 | if (err) | ||
1910 | break; | ||
1911 | err = isr_setup_status_phase(mEp); | ||
1912 | break; | ||
1913 | case USB_REQ_SET_FEATURE: | ||
1914 | if (type != (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
1915 | le16_to_cpu(req.wValue) != USB_ENDPOINT_HALT) | ||
1916 | goto delegate; | ||
1917 | if (req.wLength != 0) | ||
1918 | break; | ||
1919 | num = le16_to_cpu(req.wIndex); | ||
1920 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
1921 | |||
1922 | spin_unlock(udc->lock); | ||
1923 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); | ||
1924 | spin_lock(udc->lock); | ||
1925 | if (err) | ||
1926 | break; | ||
1927 | err = isr_setup_status_phase(mEp); | ||
1928 | break; | ||
1929 | default: | ||
1930 | delegate: | ||
1931 | if (req.wLength == 0) /* no data phase */ | ||
1932 | mEp->dir = TX; | ||
1933 | |||
1934 | spin_unlock(udc->lock); | ||
1935 | err = udc->driver->setup(&udc->gadget, &req); | ||
1936 | spin_lock(udc->lock); | ||
1937 | break; | ||
1938 | } | ||
1939 | |||
1940 | if (err < 0) { | ||
1941 | dbg_event(_usb_addr(mEp), "ERROR", err); | ||
1942 | |||
1943 | spin_unlock(udc->lock); | ||
1944 | if (usb_ep_set_halt(&mEp->ep)) | ||
1945 | err("error: ep_set_halt"); | ||
1946 | spin_lock(udc->lock); | ||
1947 | } | ||
1948 | } | ||
1949 | } | ||
1950 | |||
1951 | /****************************************************************************** | ||
1952 | * ENDPT block | ||
1953 | *****************************************************************************/ | ||
1954 | /** | ||
1955 | * ep_enable: configure endpoint, making it usable | ||
1956 | * | ||
1957 | * Check usb_ep_enable() at "usb_gadget.h" for details | ||
1958 | */ | ||
1959 | static int ep_enable(struct usb_ep *ep, | ||
1960 | const struct usb_endpoint_descriptor *desc) | ||
1961 | { | ||
1962 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
1963 | int direction, retval = 0; | ||
1964 | unsigned long flags; | ||
1965 | |||
1966 | trace("%p, %p", ep, desc); | ||
1967 | |||
1968 | if (ep == NULL || desc == NULL) | ||
1969 | return -EINVAL; | ||
1970 | |||
1971 | spin_lock_irqsave(mEp->lock, flags); | ||
1972 | |||
1973 | /* only internal SW should enable ctrl endpts */ | ||
1974 | |||
1975 | mEp->desc = desc; | ||
1976 | |||
1977 | if (!list_empty(&mEp->qh[mEp->dir].queue)) | ||
1978 | warn("enabling a non-empty endpoint!"); | ||
1979 | |||
1980 | mEp->dir = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? TX : RX; | ||
1981 | mEp->num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1982 | mEp->type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | ||
1983 | |||
1984 | mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize); | ||
1985 | |||
1986 | direction = mEp->dir; | ||
1987 | do { | ||
1988 | dbg_event(_usb_addr(mEp), "ENABLE", 0); | ||
1989 | |||
1990 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
1991 | mEp->qh[mEp->dir].ptr->cap |= QH_IOS; | ||
1992 | else if (mEp->type == USB_ENDPOINT_XFER_ISOC) | ||
1993 | mEp->qh[mEp->dir].ptr->cap &= ~QH_MULT; | ||
1994 | else | ||
1995 | mEp->qh[mEp->dir].ptr->cap &= ~QH_ZLT; | ||
1996 | |||
1997 | mEp->qh[mEp->dir].ptr->cap |= | ||
1998 | (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT; | ||
1999 | mEp->qh[mEp->dir].ptr->td.next |= TD_TERMINATE; /* needed? */ | ||
2000 | |||
2001 | retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type); | ||
2002 | |||
2003 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
2004 | mEp->dir = (mEp->dir == TX) ? RX : TX; | ||
2005 | |||
2006 | } while (mEp->dir != direction); | ||
2007 | |||
2008 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2009 | return retval; | ||
2010 | } | ||
2011 | |||
2012 | /** | ||
2013 | * ep_disable: endpoint is no longer usable | ||
2014 | * | ||
2015 | * Check usb_ep_disable() at "usb_gadget.h" for details | ||
2016 | */ | ||
2017 | static int ep_disable(struct usb_ep *ep) | ||
2018 | { | ||
2019 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2020 | int direction, retval = 0; | ||
2021 | unsigned long flags; | ||
2022 | |||
2023 | trace("%p", ep); | ||
2024 | |||
2025 | if (ep == NULL) | ||
2026 | return -EINVAL; | ||
2027 | else if (mEp->desc == NULL) | ||
2028 | return -EBUSY; | ||
2029 | |||
2030 | spin_lock_irqsave(mEp->lock, flags); | ||
2031 | |||
2032 | /* only internal SW should disable ctrl endpts */ | ||
2033 | |||
2034 | direction = mEp->dir; | ||
2035 | do { | ||
2036 | dbg_event(_usb_addr(mEp), "DISABLE", 0); | ||
2037 | |||
2038 | retval |= _ep_nuke(mEp); | ||
2039 | retval |= hw_ep_disable(mEp->num, mEp->dir); | ||
2040 | |||
2041 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
2042 | mEp->dir = (mEp->dir == TX) ? RX : TX; | ||
2043 | |||
2044 | } while (mEp->dir != direction); | ||
2045 | |||
2046 | mEp->desc = NULL; | ||
2047 | |||
2048 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2049 | return retval; | ||
2050 | } | ||
2051 | |||
2052 | /** | ||
2053 | * ep_alloc_request: allocate a request object to use with this endpoint | ||
2054 | * | ||
2055 | * Check usb_ep_alloc_request() at "usb_gadget.h" for details | ||
2056 | */ | ||
2057 | static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | ||
2058 | { | ||
2059 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2060 | struct ci13xxx_req *mReq = NULL; | ||
2061 | unsigned long flags; | ||
2062 | |||
2063 | trace("%p, %i", ep, gfp_flags); | ||
2064 | |||
2065 | if (ep == NULL) { | ||
2066 | err("EINVAL"); | ||
2067 | return NULL; | ||
2068 | } | ||
2069 | |||
2070 | spin_lock_irqsave(mEp->lock, flags); | ||
2071 | |||
2072 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); | ||
2073 | if (mReq != NULL) { | ||
2074 | INIT_LIST_HEAD(&mReq->queue); | ||
2075 | |||
2076 | mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, | ||
2077 | &mReq->dma); | ||
2078 | if (mReq->ptr == NULL) { | ||
2079 | kfree(mReq); | ||
2080 | mReq = NULL; | ||
2081 | } | ||
2082 | } | ||
2083 | |||
2084 | dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); | ||
2085 | |||
2086 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2087 | |||
2088 | return (mReq == NULL) ? NULL : &mReq->req; | ||
2089 | } | ||
2090 | |||
2091 | /** | ||
2092 | * ep_free_request: frees a request object | ||
2093 | * | ||
2094 | * Check usb_ep_free_request() at "usb_gadget.h" for details | ||
2095 | */ | ||
2096 | static void ep_free_request(struct usb_ep *ep, struct usb_request *req) | ||
2097 | { | ||
2098 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2099 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | ||
2100 | unsigned long flags; | ||
2101 | |||
2102 | trace("%p, %p", ep, req); | ||
2103 | |||
2104 | if (ep == NULL || req == NULL) { | ||
2105 | err("EINVAL"); | ||
2106 | return; | ||
2107 | } else if (!list_empty(&mReq->queue)) { | ||
2108 | err("EBUSY"); | ||
2109 | return; | ||
2110 | } | ||
2111 | |||
2112 | spin_lock_irqsave(mEp->lock, flags); | ||
2113 | |||
2114 | if (mReq->ptr) | ||
2115 | dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma); | ||
2116 | kfree(mReq); | ||
2117 | |||
2118 | dbg_event(_usb_addr(mEp), "FREE", 0); | ||
2119 | |||
2120 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2121 | } | ||
2122 | |||
2123 | /** | ||
2124 | * ep_queue: queues (submits) an I/O request to an endpoint | ||
2125 | * | ||
2126 | * Check usb_ep_queue()* at usb_gadget.h" for details | ||
2127 | */ | ||
2128 | static int ep_queue(struct usb_ep *ep, struct usb_request *req, | ||
2129 | gfp_t __maybe_unused gfp_flags) | ||
2130 | { | ||
2131 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2132 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | ||
2133 | int retval = 0; | ||
2134 | unsigned long flags; | ||
2135 | |||
2136 | trace("%p, %p, %X", ep, req, gfp_flags); | ||
2137 | |||
2138 | if (ep == NULL || req == NULL || mEp->desc == NULL) | ||
2139 | return -EINVAL; | ||
2140 | |||
2141 | spin_lock_irqsave(mEp->lock, flags); | ||
2142 | |||
2143 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL && | ||
2144 | !list_empty(&mEp->qh[mEp->dir].queue)) { | ||
2145 | _ep_nuke(mEp); | ||
2146 | retval = -EOVERFLOW; | ||
2147 | warn("endpoint ctrl %X nuked", _usb_addr(mEp)); | ||
2148 | } | ||
2149 | |||
2150 | /* first nuke then test link, e.g. previous status has not sent */ | ||
2151 | if (!list_empty(&mReq->queue)) { | ||
2152 | retval = -EBUSY; | ||
2153 | err("request already in queue"); | ||
2154 | goto done; | ||
2155 | } | ||
2156 | |||
2157 | if (req->length > (4 * PAGE_SIZE)) { | ||
2158 | req->length = (4 * PAGE_SIZE); | ||
2159 | retval = -EMSGSIZE; | ||
2160 | warn("request length truncated"); | ||
2161 | } | ||
2162 | |||
2163 | dbg_queue(_usb_addr(mEp), req, retval); | ||
2164 | |||
2165 | /* push request */ | ||
2166 | mReq->req.status = -EINPROGRESS; | ||
2167 | mReq->req.actual = 0; | ||
2168 | list_add_tail(&mReq->queue, &mEp->qh[mEp->dir].queue); | ||
2169 | |||
2170 | retval = _hardware_enqueue(mEp, mReq); | ||
2171 | if (retval == -EALREADY || retval == -EBUSY) { | ||
2172 | dbg_event(_usb_addr(mEp), "QUEUE", retval); | ||
2173 | retval = 0; | ||
2174 | } | ||
2175 | |||
2176 | done: | ||
2177 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2178 | return retval; | ||
2179 | } | ||
2180 | |||
2181 | /** | ||
2182 | * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint | ||
2183 | * | ||
2184 | * Check usb_ep_dequeue() at "usb_gadget.h" for details | ||
2185 | */ | ||
2186 | static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) | ||
2187 | { | ||
2188 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2189 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | ||
2190 | unsigned long flags; | ||
2191 | |||
2192 | trace("%p, %p", ep, req); | ||
2193 | |||
2194 | if (ep == NULL || req == NULL || mEp->desc == NULL || | ||
2195 | list_empty(&mReq->queue) || list_empty(&mEp->qh[mEp->dir].queue)) | ||
2196 | return -EINVAL; | ||
2197 | |||
2198 | spin_lock_irqsave(mEp->lock, flags); | ||
2199 | |||
2200 | dbg_event(_usb_addr(mEp), "DEQUEUE", 0); | ||
2201 | |||
2202 | if (mReq->req.status == -EALREADY) | ||
2203 | _hardware_dequeue(mEp, mReq); | ||
2204 | |||
2205 | /* pop request */ | ||
2206 | list_del_init(&mReq->queue); | ||
2207 | req->status = -ECONNRESET; | ||
2208 | |||
2209 | if (!mReq->req.no_interrupt && mReq->req.complete != NULL) { | ||
2210 | spin_unlock(mEp->lock); | ||
2211 | mReq->req.complete(&mEp->ep, &mReq->req); | ||
2212 | spin_lock(mEp->lock); | ||
2213 | } | ||
2214 | |||
2215 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2216 | return 0; | ||
2217 | } | ||
2218 | |||
2219 | /** | ||
2220 | * ep_set_halt: sets the endpoint halt feature | ||
2221 | * | ||
2222 | * Check usb_ep_set_halt() at "usb_gadget.h" for details | ||
2223 | */ | ||
2224 | static int ep_set_halt(struct usb_ep *ep, int value) | ||
2225 | { | ||
2226 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2227 | int direction, retval = 0; | ||
2228 | unsigned long flags; | ||
2229 | |||
2230 | trace("%p, %i", ep, value); | ||
2231 | |||
2232 | if (ep == NULL || mEp->desc == NULL) | ||
2233 | return -EINVAL; | ||
2234 | |||
2235 | spin_lock_irqsave(mEp->lock, flags); | ||
2236 | |||
2237 | #ifndef STALL_IN | ||
2238 | /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */ | ||
2239 | if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX && | ||
2240 | !list_empty(&mEp->qh[mEp->dir].queue)) { | ||
2241 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2242 | return -EAGAIN; | ||
2243 | } | ||
2244 | #endif | ||
2245 | |||
2246 | direction = mEp->dir; | ||
2247 | do { | ||
2248 | dbg_event(_usb_addr(mEp), "HALT", value); | ||
2249 | retval |= hw_ep_set_halt(mEp->num, mEp->dir, value); | ||
2250 | |||
2251 | if (!value) | ||
2252 | mEp->wedge = 0; | ||
2253 | |||
2254 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | ||
2255 | mEp->dir = (mEp->dir == TX) ? RX : TX; | ||
2256 | |||
2257 | } while (mEp->dir != direction); | ||
2258 | |||
2259 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2260 | return retval; | ||
2261 | } | ||
2262 | |||
2263 | /** | ||
2264 | * ep_set_wedge: sets the halt feature and ignores clear requests | ||
2265 | * | ||
2266 | * Check usb_ep_set_wedge() at "usb_gadget.h" for details | ||
2267 | */ | ||
2268 | static int ep_set_wedge(struct usb_ep *ep) | ||
2269 | { | ||
2270 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2271 | unsigned long flags; | ||
2272 | |||
2273 | trace("%p", ep); | ||
2274 | |||
2275 | if (ep == NULL || mEp->desc == NULL) | ||
2276 | return -EINVAL; | ||
2277 | |||
2278 | spin_lock_irqsave(mEp->lock, flags); | ||
2279 | |||
2280 | dbg_event(_usb_addr(mEp), "WEDGE", 0); | ||
2281 | mEp->wedge = 1; | ||
2282 | |||
2283 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2284 | |||
2285 | return usb_ep_set_halt(ep); | ||
2286 | } | ||
2287 | |||
2288 | /** | ||
2289 | * ep_fifo_flush: flushes contents of a fifo | ||
2290 | * | ||
2291 | * Check usb_ep_fifo_flush() at "usb_gadget.h" for details | ||
2292 | */ | ||
2293 | static void ep_fifo_flush(struct usb_ep *ep) | ||
2294 | { | ||
2295 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | ||
2296 | unsigned long flags; | ||
2297 | |||
2298 | trace("%p", ep); | ||
2299 | |||
2300 | if (ep == NULL) { | ||
2301 | err("%02X: -EINVAL", _usb_addr(mEp)); | ||
2302 | return; | ||
2303 | } | ||
2304 | |||
2305 | spin_lock_irqsave(mEp->lock, flags); | ||
2306 | |||
2307 | dbg_event(_usb_addr(mEp), "FFLUSH", 0); | ||
2308 | hw_ep_flush(mEp->num, mEp->dir); | ||
2309 | |||
2310 | spin_unlock_irqrestore(mEp->lock, flags); | ||
2311 | } | ||
2312 | |||
2313 | /** | ||
2314 | * Endpoint-specific part of the API to the USB controller hardware | ||
2315 | * Check "usb_gadget.h" for details | ||
2316 | */ | ||
2317 | static const struct usb_ep_ops usb_ep_ops = { | ||
2318 | .enable = ep_enable, | ||
2319 | .disable = ep_disable, | ||
2320 | .alloc_request = ep_alloc_request, | ||
2321 | .free_request = ep_free_request, | ||
2322 | .queue = ep_queue, | ||
2323 | .dequeue = ep_dequeue, | ||
2324 | .set_halt = ep_set_halt, | ||
2325 | .set_wedge = ep_set_wedge, | ||
2326 | .fifo_flush = ep_fifo_flush, | ||
2327 | }; | ||
2328 | |||
2329 | /****************************************************************************** | ||
2330 | * GADGET block | ||
2331 | *****************************************************************************/ | ||
2332 | /** | ||
2333 | * Device operations part of the API to the USB controller hardware, | ||
2334 | * which don't involve endpoints (or i/o) | ||
2335 | * Check "usb_gadget.h" for details | ||
2336 | */ | ||
2337 | static const struct usb_gadget_ops usb_gadget_ops; | ||
2338 | |||
2339 | /** | ||
2340 | * usb_gadget_register_driver: register a gadget driver | ||
2341 | * | ||
2342 | * Check usb_gadget_register_driver() at "usb_gadget.h" for details | ||
2343 | * Interrupts are enabled here | ||
2344 | */ | ||
2345 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
2346 | { | ||
2347 | struct ci13xxx *udc = _udc; | ||
2348 | unsigned long i, k, flags; | ||
2349 | int retval = -ENOMEM; | ||
2350 | |||
2351 | trace("%p", driver); | ||
2352 | |||
2353 | if (driver == NULL || | ||
2354 | driver->bind == NULL || | ||
2355 | driver->unbind == NULL || | ||
2356 | driver->setup == NULL || | ||
2357 | driver->disconnect == NULL || | ||
2358 | driver->suspend == NULL || | ||
2359 | driver->resume == NULL) | ||
2360 | return -EINVAL; | ||
2361 | else if (udc == NULL) | ||
2362 | return -ENODEV; | ||
2363 | else if (udc->driver != NULL) | ||
2364 | return -EBUSY; | ||
2365 | |||
2366 | /* alloc resources */ | ||
2367 | udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev, | ||
2368 | sizeof(struct ci13xxx_qh), | ||
2369 | 64, PAGE_SIZE); | ||
2370 | if (udc->qh_pool == NULL) | ||
2371 | return -ENOMEM; | ||
2372 | |||
2373 | udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev, | ||
2374 | sizeof(struct ci13xxx_td), | ||
2375 | 64, PAGE_SIZE); | ||
2376 | if (udc->td_pool == NULL) { | ||
2377 | dma_pool_destroy(udc->qh_pool); | ||
2378 | udc->qh_pool = NULL; | ||
2379 | return -ENOMEM; | ||
2380 | } | ||
2381 | |||
2382 | spin_lock_irqsave(udc->lock, flags); | ||
2383 | |||
2384 | info("hw_ep_max = %d", hw_ep_max); | ||
2385 | |||
2386 | udc->driver = driver; | ||
2387 | udc->gadget.ops = NULL; | ||
2388 | udc->gadget.dev.driver = NULL; | ||
2389 | |||
2390 | retval = 0; | ||
2391 | for (i = 0; i < hw_ep_max; i++) { | ||
2392 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | ||
2393 | |||
2394 | scnprintf(mEp->name, sizeof(mEp->name), "ep%i", (int)i); | ||
2395 | |||
2396 | mEp->lock = udc->lock; | ||
2397 | mEp->device = &udc->gadget.dev; | ||
2398 | mEp->td_pool = udc->td_pool; | ||
2399 | |||
2400 | mEp->ep.name = mEp->name; | ||
2401 | mEp->ep.ops = &usb_ep_ops; | ||
2402 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | ||
2403 | |||
2404 | /* this allocation cannot be random */ | ||
2405 | for (k = RX; k <= TX; k++) { | ||
2406 | INIT_LIST_HEAD(&mEp->qh[k].queue); | ||
2407 | mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, | ||
2408 | GFP_KERNEL, | ||
2409 | &mEp->qh[k].dma); | ||
2410 | if (mEp->qh[k].ptr == NULL) | ||
2411 | retval = -ENOMEM; | ||
2412 | else | ||
2413 | memset(mEp->qh[k].ptr, 0, | ||
2414 | sizeof(*mEp->qh[k].ptr)); | ||
2415 | } | ||
2416 | if (i == 0) | ||
2417 | udc->gadget.ep0 = &mEp->ep; | ||
2418 | else | ||
2419 | list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list); | ||
2420 | } | ||
2421 | if (retval) | ||
2422 | goto done; | ||
2423 | |||
2424 | /* bind gadget */ | ||
2425 | driver->driver.bus = NULL; | ||
2426 | udc->gadget.ops = &usb_gadget_ops; | ||
2427 | udc->gadget.dev.driver = &driver->driver; | ||
2428 | |||
2429 | spin_unlock_irqrestore(udc->lock, flags); | ||
2430 | retval = driver->bind(&udc->gadget); /* MAY SLEEP */ | ||
2431 | spin_lock_irqsave(udc->lock, flags); | ||
2432 | |||
2433 | if (retval) { | ||
2434 | udc->gadget.ops = NULL; | ||
2435 | udc->gadget.dev.driver = NULL; | ||
2436 | goto done; | ||
2437 | } | ||
2438 | |||
2439 | retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); | ||
2440 | |||
2441 | done: | ||
2442 | spin_unlock_irqrestore(udc->lock, flags); | ||
2443 | if (retval) | ||
2444 | usb_gadget_unregister_driver(driver); | ||
2445 | return retval; | ||
2446 | } | ||
2447 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
2448 | |||
2449 | /** | ||
2450 | * usb_gadget_unregister_driver: unregister a gadget driver | ||
2451 | * | ||
2452 | * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details | ||
2453 | */ | ||
2454 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
2455 | { | ||
2456 | struct ci13xxx *udc = _udc; | ||
2457 | unsigned long i, k, flags; | ||
2458 | |||
2459 | trace("%p", driver); | ||
2460 | |||
2461 | if (driver == NULL || | ||
2462 | driver->bind == NULL || | ||
2463 | driver->unbind == NULL || | ||
2464 | driver->setup == NULL || | ||
2465 | driver->disconnect == NULL || | ||
2466 | driver->suspend == NULL || | ||
2467 | driver->resume == NULL || | ||
2468 | driver != udc->driver) | ||
2469 | return -EINVAL; | ||
2470 | |||
2471 | spin_lock_irqsave(udc->lock, flags); | ||
2472 | |||
2473 | hw_device_state(0); | ||
2474 | |||
2475 | /* unbind gadget */ | ||
2476 | if (udc->gadget.ops != NULL) { | ||
2477 | _gadget_stop_activity(&udc->gadget); | ||
2478 | |||
2479 | spin_unlock_irqrestore(udc->lock, flags); | ||
2480 | driver->unbind(&udc->gadget); /* MAY SLEEP */ | ||
2481 | spin_lock_irqsave(udc->lock, flags); | ||
2482 | |||
2483 | udc->gadget.ops = NULL; | ||
2484 | udc->gadget.dev.driver = NULL; | ||
2485 | } | ||
2486 | |||
2487 | /* free resources */ | ||
2488 | for (i = 0; i < hw_ep_max; i++) { | ||
2489 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | ||
2490 | |||
2491 | if (i == 0) | ||
2492 | udc->gadget.ep0 = NULL; | ||
2493 | else if (!list_empty(&mEp->ep.ep_list)) | ||
2494 | list_del_init(&mEp->ep.ep_list); | ||
2495 | |||
2496 | for (k = RX; k <= TX; k++) | ||
2497 | if (mEp->qh[k].ptr != NULL) | ||
2498 | dma_pool_free(udc->qh_pool, | ||
2499 | mEp->qh[k].ptr, mEp->qh[k].dma); | ||
2500 | } | ||
2501 | |||
2502 | udc->driver = NULL; | ||
2503 | |||
2504 | spin_unlock_irqrestore(udc->lock, flags); | ||
2505 | |||
2506 | if (udc->td_pool != NULL) { | ||
2507 | dma_pool_destroy(udc->td_pool); | ||
2508 | udc->td_pool = NULL; | ||
2509 | } | ||
2510 | if (udc->qh_pool != NULL) { | ||
2511 | dma_pool_destroy(udc->qh_pool); | ||
2512 | udc->qh_pool = NULL; | ||
2513 | } | ||
2514 | |||
2515 | return 0; | ||
2516 | } | ||
2517 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2518 | |||
2519 | /****************************************************************************** | ||
2520 | * BUS block | ||
2521 | *****************************************************************************/ | ||
2522 | /** | ||
2523 | * udc_irq: global interrupt handler | ||
2524 | * | ||
2525 | * This function returns IRQ_HANDLED if the IRQ has been handled | ||
2526 | * It locks access to registers | ||
2527 | */ | ||
2528 | static irqreturn_t udc_irq(void) | ||
2529 | { | ||
2530 | struct ci13xxx *udc = _udc; | ||
2531 | irqreturn_t retval; | ||
2532 | u32 intr; | ||
2533 | |||
2534 | trace(); | ||
2535 | |||
2536 | if (udc == NULL) { | ||
2537 | err("ENODEV"); | ||
2538 | return IRQ_HANDLED; | ||
2539 | } | ||
2540 | |||
2541 | spin_lock(udc->lock); | ||
2542 | intr = hw_test_and_clear_intr_active(); | ||
2543 | if (intr) { | ||
2544 | isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr; | ||
2545 | isr_statistics.hndl.idx &= ISR_MASK; | ||
2546 | isr_statistics.hndl.cnt++; | ||
2547 | |||
2548 | /* order defines priority - do NOT change it */ | ||
2549 | if (USBi_URI & intr) { | ||
2550 | isr_statistics.uri++; | ||
2551 | isr_reset_handler(udc); | ||
2552 | } | ||
2553 | if (USBi_PCI & intr) { | ||
2554 | isr_statistics.pci++; | ||
2555 | udc->gadget.speed = hw_port_is_high_speed() ? | ||
2556 | USB_SPEED_HIGH : USB_SPEED_FULL; | ||
2557 | } | ||
2558 | if (USBi_UEI & intr) | ||
2559 | isr_statistics.uei++; | ||
2560 | if (USBi_UI & intr) { | ||
2561 | isr_statistics.ui++; | ||
2562 | isr_tr_complete_handler(udc); | ||
2563 | } | ||
2564 | if (USBi_SLI & intr) | ||
2565 | isr_statistics.sli++; | ||
2566 | retval = IRQ_HANDLED; | ||
2567 | } else { | ||
2568 | isr_statistics.none++; | ||
2569 | retval = IRQ_NONE; | ||
2570 | } | ||
2571 | spin_unlock(udc->lock); | ||
2572 | |||
2573 | return retval; | ||
2574 | } | ||
2575 | |||
2576 | /** | ||
2577 | * udc_release: driver release function | ||
2578 | * @dev: device | ||
2579 | * | ||
2580 | * Currently does nothing | ||
2581 | */ | ||
2582 | static void udc_release(struct device *dev) | ||
2583 | { | ||
2584 | trace("%p", dev); | ||
2585 | |||
2586 | if (dev == NULL) | ||
2587 | err("EINVAL"); | ||
2588 | } | ||
2589 | |||
2590 | /** | ||
2591 | * udc_probe: parent probe must call this to initialize UDC | ||
2592 | * @dev: parent device | ||
2593 | * @regs: registers base address | ||
2594 | * @name: driver name | ||
2595 | * | ||
2596 | * This function returns an error code | ||
2597 | * No interrupts active, the IRQ has not been requested yet | ||
2598 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask | ||
2599 | */ | ||
2600 | static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | ||
2601 | { | ||
2602 | struct ci13xxx *udc; | ||
2603 | int retval = 0; | ||
2604 | |||
2605 | trace("%p, %p, %p", dev, regs, name); | ||
2606 | |||
2607 | if (dev == NULL || regs == NULL || name == NULL) | ||
2608 | return -EINVAL; | ||
2609 | |||
2610 | udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL); | ||
2611 | if (udc == NULL) | ||
2612 | return -ENOMEM; | ||
2613 | |||
2614 | udc->lock = &udc_lock; | ||
2615 | |||
2616 | retval = hw_device_reset(regs); | ||
2617 | if (retval) | ||
2618 | goto done; | ||
2619 | |||
2620 | udc->gadget.ops = NULL; | ||
2621 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
2622 | udc->gadget.is_dualspeed = 1; | ||
2623 | udc->gadget.is_otg = 0; | ||
2624 | udc->gadget.name = name; | ||
2625 | |||
2626 | INIT_LIST_HEAD(&udc->gadget.ep_list); | ||
2627 | udc->gadget.ep0 = NULL; | ||
2628 | |||
2629 | strcpy(udc->gadget.dev.bus_id, "gadget"); | ||
2630 | udc->gadget.dev.dma_mask = dev->dma_mask; | ||
2631 | udc->gadget.dev.parent = dev; | ||
2632 | udc->gadget.dev.release = udc_release; | ||
2633 | |||
2634 | retval = device_register(&udc->gadget.dev); | ||
2635 | if (retval) | ||
2636 | goto done; | ||
2637 | |||
2638 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
2639 | retval = dbg_create_files(&udc->gadget.dev); | ||
2640 | #endif | ||
2641 | if (retval) { | ||
2642 | device_unregister(&udc->gadget.dev); | ||
2643 | goto done; | ||
2644 | } | ||
2645 | |||
2646 | _udc = udc; | ||
2647 | return retval; | ||
2648 | |||
2649 | done: | ||
2650 | err("error = %i", retval); | ||
2651 | kfree(udc); | ||
2652 | _udc = NULL; | ||
2653 | return retval; | ||
2654 | } | ||
2655 | |||
2656 | /** | ||
2657 | * udc_remove: parent remove must call this to remove UDC | ||
2658 | * | ||
2659 | * No interrupts active, the IRQ has been released | ||
2660 | */ | ||
2661 | static void udc_remove(void) | ||
2662 | { | ||
2663 | struct ci13xxx *udc = _udc; | ||
2664 | |||
2665 | if (udc == NULL) { | ||
2666 | err("EINVAL"); | ||
2667 | return; | ||
2668 | } | ||
2669 | |||
2670 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
2671 | dbg_remove_files(&udc->gadget.dev); | ||
2672 | #endif | ||
2673 | device_unregister(&udc->gadget.dev); | ||
2674 | |||
2675 | kfree(udc); | ||
2676 | _udc = NULL; | ||
2677 | } | ||
2678 | |||
2679 | /****************************************************************************** | ||
2680 | * PCI block | ||
2681 | *****************************************************************************/ | ||
2682 | /** | ||
2683 | * ci13xxx_pci_irq: interrut handler | ||
2684 | * @irq: irq number | ||
2685 | * @pdev: USB Device Controller interrupt source | ||
2686 | * | ||
2687 | * This function returns IRQ_HANDLED if the IRQ has been handled | ||
2688 | * This is an ISR don't trace, use attribute interface instead | ||
2689 | */ | ||
2690 | static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev) | ||
2691 | { | ||
2692 | if (irq == 0) { | ||
2693 | dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!"); | ||
2694 | return IRQ_HANDLED; | ||
2695 | } | ||
2696 | return udc_irq(); | ||
2697 | } | ||
2698 | |||
2699 | /** | ||
2700 | * ci13xxx_pci_probe: PCI probe | ||
2701 | * @pdev: USB device controller being probed | ||
2702 | * @id: PCI hotplug ID connecting controller to UDC framework | ||
2703 | * | ||
2704 | * This function returns an error code | ||
2705 | * Allocates basic PCI resources for this USB device controller, and then | ||
2706 | * invokes the udc_probe() method to start the UDC associated with it | ||
2707 | */ | ||
2708 | static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, | ||
2709 | const struct pci_device_id *id) | ||
2710 | { | ||
2711 | void __iomem *regs = NULL; | ||
2712 | int retval = 0; | ||
2713 | |||
2714 | if (id == NULL) | ||
2715 | return -EINVAL; | ||
2716 | |||
2717 | retval = pci_enable_device(pdev); | ||
2718 | if (retval) | ||
2719 | goto done; | ||
2720 | |||
2721 | if (!pdev->irq) { | ||
2722 | dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!"); | ||
2723 | retval = -ENODEV; | ||
2724 | goto disable_device; | ||
2725 | } | ||
2726 | |||
2727 | retval = pci_request_regions(pdev, UDC_DRIVER_NAME); | ||
2728 | if (retval) | ||
2729 | goto disable_device; | ||
2730 | |||
2731 | /* BAR 0 holds all the registers */ | ||
2732 | regs = pci_iomap(pdev, 0, 0); | ||
2733 | if (!regs) { | ||
2734 | dev_err(&pdev->dev, "Error mapping memory!"); | ||
2735 | retval = -EFAULT; | ||
2736 | goto release_regions; | ||
2737 | } | ||
2738 | pci_set_drvdata(pdev, (__force void *)regs); | ||
2739 | |||
2740 | pci_set_master(pdev); | ||
2741 | pci_try_set_mwi(pdev); | ||
2742 | |||
2743 | retval = udc_probe(&pdev->dev, regs, UDC_DRIVER_NAME); | ||
2744 | if (retval) | ||
2745 | goto iounmap; | ||
2746 | |||
2747 | /* our device does not have MSI capability */ | ||
2748 | |||
2749 | retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED, | ||
2750 | UDC_DRIVER_NAME, pdev); | ||
2751 | if (retval) | ||
2752 | goto gadget_remove; | ||
2753 | |||
2754 | return 0; | ||
2755 | |||
2756 | gadget_remove: | ||
2757 | udc_remove(); | ||
2758 | iounmap: | ||
2759 | pci_iounmap(pdev, regs); | ||
2760 | release_regions: | ||
2761 | pci_release_regions(pdev); | ||
2762 | disable_device: | ||
2763 | pci_disable_device(pdev); | ||
2764 | done: | ||
2765 | return retval; | ||
2766 | } | ||
2767 | |||
2768 | /** | ||
2769 | * ci13xxx_pci_remove: PCI remove | ||
2770 | * @pdev: USB Device Controller being removed | ||
2771 | * | ||
2772 | * Reverses the effect of ci13xxx_pci_probe(), | ||
2773 | * first invoking the udc_remove() and then releases | ||
2774 | * all PCI resources allocated for this USB device controller | ||
2775 | */ | ||
2776 | static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) | ||
2777 | { | ||
2778 | free_irq(pdev->irq, pdev); | ||
2779 | udc_remove(); | ||
2780 | pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev)); | ||
2781 | pci_release_regions(pdev); | ||
2782 | pci_disable_device(pdev); | ||
2783 | } | ||
2784 | |||
2785 | /** | ||
2786 | * PCI device table | ||
2787 | * PCI device structure | ||
2788 | * | ||
2789 | * Check "pci.h" for details | ||
2790 | */ | ||
2791 | static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = { | ||
2792 | { PCI_DEVICE(0x153F, 0x1004) }, | ||
2793 | { PCI_DEVICE(0x153F, 0x1006) }, | ||
2794 | { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ } | ||
2795 | }; | ||
2796 | MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); | ||
2797 | |||
2798 | static struct pci_driver ci13xxx_pci_driver = { | ||
2799 | .name = UDC_DRIVER_NAME, | ||
2800 | .id_table = ci13xxx_pci_id_table, | ||
2801 | .probe = ci13xxx_pci_probe, | ||
2802 | .remove = __devexit_p(ci13xxx_pci_remove), | ||
2803 | }; | ||
2804 | |||
2805 | /** | ||
2806 | * ci13xxx_pci_init: module init | ||
2807 | * | ||
2808 | * Driver load | ||
2809 | */ | ||
2810 | static int __init ci13xxx_pci_init(void) | ||
2811 | { | ||
2812 | return pci_register_driver(&ci13xxx_pci_driver); | ||
2813 | } | ||
2814 | module_init(ci13xxx_pci_init); | ||
2815 | |||
2816 | /** | ||
2817 | * ci13xxx_pci_exit: module exit | ||
2818 | * | ||
2819 | * Driver unload | ||
2820 | */ | ||
2821 | static void __exit ci13xxx_pci_exit(void) | ||
2822 | { | ||
2823 | pci_unregister_driver(&ci13xxx_pci_driver); | ||
2824 | } | ||
2825 | module_exit(ci13xxx_pci_exit); | ||
2826 | |||
2827 | MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>"); | ||
2828 | MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller"); | ||
2829 | MODULE_LICENSE("GPL"); | ||
2830 | MODULE_VERSION("June 2008"); | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h new file mode 100644 index 000000000000..4026e9cede34 --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * ci13xxx_udc.h - structures, registers, and macros MIPS USB IP core | ||
3 | * | ||
4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. | ||
5 | * | ||
6 | * Author: David Lopo | ||
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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * Description: MIPS USB IP core family device controller | ||
13 | * Structures, registers and logging macros | ||
14 | */ | ||
15 | |||
16 | #ifndef _CI13XXX_h_ | ||
17 | #define _CI13XXX_h_ | ||
18 | |||
19 | /****************************************************************************** | ||
20 | * DEFINE | ||
21 | *****************************************************************************/ | ||
22 | #define ENDPT_MAX (16) | ||
23 | #define CTRL_PAYLOAD_MAX (64) | ||
24 | #define RX (0) /* similar to USB_DIR_OUT but can be used as an index */ | ||
25 | #define TX (1) /* similar to USB_DIR_IN but can be used as an index */ | ||
26 | |||
27 | /****************************************************************************** | ||
28 | * STRUCTURES | ||
29 | *****************************************************************************/ | ||
30 | /* DMA layout of transfer descriptors */ | ||
31 | struct ci13xxx_td { | ||
32 | /* 0 */ | ||
33 | u32 next; | ||
34 | #define TD_TERMINATE BIT(0) | ||
35 | /* 1 */ | ||
36 | u32 token; | ||
37 | #define TD_STATUS (0x00FFUL << 0) | ||
38 | #define TD_STATUS_TR_ERR BIT(3) | ||
39 | #define TD_STATUS_DT_ERR BIT(5) | ||
40 | #define TD_STATUS_HALTED BIT(6) | ||
41 | #define TD_STATUS_ACTIVE BIT(7) | ||
42 | #define TD_MULTO (0x0003UL << 10) | ||
43 | #define TD_IOC BIT(15) | ||
44 | #define TD_TOTAL_BYTES (0x7FFFUL << 16) | ||
45 | /* 2 */ | ||
46 | u32 page[5]; | ||
47 | #define TD_CURR_OFFSET (0x0FFFUL << 0) | ||
48 | #define TD_FRAME_NUM (0x07FFUL << 0) | ||
49 | #define TD_RESERVED_MASK (0x0FFFUL << 0) | ||
50 | } __attribute__ ((packed)); | ||
51 | |||
52 | /* DMA layout of queue heads */ | ||
53 | struct ci13xxx_qh { | ||
54 | /* 0 */ | ||
55 | u32 cap; | ||
56 | #define QH_IOS BIT(15) | ||
57 | #define QH_MAX_PKT (0x07FFUL << 16) | ||
58 | #define QH_ZLT BIT(29) | ||
59 | #define QH_MULT (0x0003UL << 30) | ||
60 | /* 1 */ | ||
61 | u32 curr; | ||
62 | /* 2 - 8 */ | ||
63 | struct ci13xxx_td td; | ||
64 | /* 9 */ | ||
65 | u32 RESERVED; | ||
66 | struct usb_ctrlrequest setup; | ||
67 | } __attribute__ ((packed)); | ||
68 | |||
69 | /* Extension of usb_request */ | ||
70 | struct ci13xxx_req { | ||
71 | struct usb_request req; | ||
72 | unsigned map; | ||
73 | struct list_head queue; | ||
74 | struct ci13xxx_td *ptr; | ||
75 | dma_addr_t dma; | ||
76 | }; | ||
77 | |||
78 | /* Extension of usb_ep */ | ||
79 | struct ci13xxx_ep { | ||
80 | struct usb_ep ep; | ||
81 | const struct usb_endpoint_descriptor *desc; | ||
82 | u8 dir; | ||
83 | u8 num; | ||
84 | u8 type; | ||
85 | char name[16]; | ||
86 | struct { | ||
87 | struct list_head queue; | ||
88 | struct ci13xxx_qh *ptr; | ||
89 | dma_addr_t dma; | ||
90 | } qh[2]; | ||
91 | struct usb_request *status; | ||
92 | int wedge; | ||
93 | |||
94 | /* global resources */ | ||
95 | spinlock_t *lock; | ||
96 | struct device *device; | ||
97 | struct dma_pool *td_pool; | ||
98 | }; | ||
99 | |||
100 | /* CI13XXX UDC descriptor & global resources */ | ||
101 | struct ci13xxx { | ||
102 | spinlock_t *lock; /* ctrl register bank access */ | ||
103 | |||
104 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ | ||
105 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ | ||
106 | |||
107 | struct usb_gadget gadget; /* USB slave device */ | ||
108 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ | ||
109 | |||
110 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ | ||
111 | }; | ||
112 | |||
113 | /****************************************************************************** | ||
114 | * REGISTERS | ||
115 | *****************************************************************************/ | ||
116 | /* register size */ | ||
117 | #define REG_BITS (32) | ||
118 | |||
119 | /* HCCPARAMS */ | ||
120 | #define HCCPARAMS_LEN BIT(17) | ||
121 | |||
122 | /* DCCPARAMS */ | ||
123 | #define DCCPARAMS_DEN (0x1F << 0) | ||
124 | #define DCCPARAMS_DC BIT(7) | ||
125 | |||
126 | /* TESTMODE */ | ||
127 | #define TESTMODE_FORCE BIT(0) | ||
128 | |||
129 | /* USBCMD */ | ||
130 | #define USBCMD_RS BIT(0) | ||
131 | #define USBCMD_RST BIT(1) | ||
132 | #define USBCMD_SUTW BIT(13) | ||
133 | |||
134 | /* USBSTS & USBINTR */ | ||
135 | #define USBi_UI BIT(0) | ||
136 | #define USBi_UEI BIT(1) | ||
137 | #define USBi_PCI BIT(2) | ||
138 | #define USBi_URI BIT(6) | ||
139 | #define USBi_SLI BIT(8) | ||
140 | |||
141 | /* DEVICEADDR */ | ||
142 | #define DEVICEADDR_USBADRA BIT(24) | ||
143 | #define DEVICEADDR_USBADR (0x7FUL << 25) | ||
144 | |||
145 | /* PORTSC */ | ||
146 | #define PORTSC_SUSP BIT(7) | ||
147 | #define PORTSC_HSP BIT(9) | ||
148 | #define PORTSC_PTC (0x0FUL << 16) | ||
149 | |||
150 | /* DEVLC */ | ||
151 | #define DEVLC_PSPD (0x03UL << 25) | ||
152 | #define DEVLC_PSPD_HS (0x02UL << 25) | ||
153 | |||
154 | /* USBMODE */ | ||
155 | #define USBMODE_CM (0x03UL << 0) | ||
156 | #define USBMODE_CM_IDLE (0x00UL << 0) | ||
157 | #define USBMODE_CM_DEVICE (0x02UL << 0) | ||
158 | #define USBMODE_CM_HOST (0x03UL << 0) | ||
159 | #define USBMODE_SLOM BIT(3) | ||
160 | |||
161 | /* ENDPTCTRL */ | ||
162 | #define ENDPTCTRL_RXS BIT(0) | ||
163 | #define ENDPTCTRL_RXT (0x03UL << 2) | ||
164 | #define ENDPTCTRL_RXR BIT(6) /* reserved for port 0 */ | ||
165 | #define ENDPTCTRL_RXE BIT(7) | ||
166 | #define ENDPTCTRL_TXS BIT(16) | ||
167 | #define ENDPTCTRL_TXT (0x03UL << 18) | ||
168 | #define ENDPTCTRL_TXR BIT(22) /* reserved for port 0 */ | ||
169 | #define ENDPTCTRL_TXE BIT(23) | ||
170 | |||
171 | /****************************************************************************** | ||
172 | * LOGGING | ||
173 | *****************************************************************************/ | ||
174 | #define ci13xxx_printk(level, format, args...) \ | ||
175 | do { \ | ||
176 | if (_udc == NULL) \ | ||
177 | printk(level "[%s] " format "\n", __func__, ## args); \ | ||
178 | else \ | ||
179 | dev_printk(level, _udc->gadget.dev.parent, \ | ||
180 | "[%s] " format "\n", __func__, ## args); \ | ||
181 | } while (0) | ||
182 | |||
183 | #define err(format, args...) ci13xxx_printk(KERN_ERR, format, ## args) | ||
184 | #define warn(format, args...) ci13xxx_printk(KERN_WARNING, format, ## args) | ||
185 | #define info(format, args...) ci13xxx_printk(KERN_INFO, format, ## args) | ||
186 | |||
187 | #ifdef TRACE | ||
188 | #define trace(format, args...) ci13xxx_printk(KERN_DEBUG, format, ## args) | ||
189 | #define dbg_trace(format, args...) dev_dbg(dev, format, ##args) | ||
190 | #else | ||
191 | #define trace(format, args...) do {} while (0) | ||
192 | #define dbg_trace(format, args...) do {} while (0) | ||
193 | #endif | ||
194 | |||
195 | #endif /* _CI13XXX_h_ */ | ||
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 9462e30192d8..a36b1175b18d 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -161,7 +161,7 @@ ep_matches ( | |||
161 | /* report address */ | 161 | /* report address */ |
162 | desc->bEndpointAddress &= USB_DIR_IN; | 162 | desc->bEndpointAddress &= USB_DIR_IN; |
163 | if (isdigit (ep->name [2])) { | 163 | if (isdigit (ep->name [2])) { |
164 | u8 num = simple_strtol (&ep->name [2], NULL, 10); | 164 | u8 num = simple_strtoul (&ep->name [2], NULL, 10); |
165 | desc->bEndpointAddress |= num; | 165 | desc->bEndpointAddress |= num; |
166 | #ifdef MANY_ENDPOINTS | 166 | #ifdef MANY_ENDPOINTS |
167 | } else if (desc->bEndpointAddress & USB_DIR_IN) { | 167 | } else if (desc->bEndpointAddress & USB_DIR_IN) { |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 2e71368f45b4..b10fa31cc915 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development | 2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2007 Alan Stern | 4 | * Copyright (C) 2003-2008 Alan Stern |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
@@ -38,16 +38,17 @@ | |||
38 | 38 | ||
39 | /* | 39 | /* |
40 | * The File-backed Storage Gadget acts as a USB Mass Storage device, | 40 | * The File-backed Storage Gadget acts as a USB Mass Storage device, |
41 | * appearing to the host as a disk drive. In addition to providing an | 41 | * appearing to the host as a disk drive or as a CD-ROM drive. In addition |
42 | * example of a genuinely useful gadget driver for a USB device, it also | 42 | * to providing an example of a genuinely useful gadget driver for a USB |
43 | * illustrates a technique of double-buffering for increased throughput. | 43 | * device, it also illustrates a technique of double-buffering for increased |
44 | * Last but not least, it gives an easy way to probe the behavior of the | 44 | * throughput. Last but not least, it gives an easy way to probe the |
45 | * Mass Storage drivers in a USB host. | 45 | * behavior of the Mass Storage drivers in a USB host. |
46 | * | 46 | * |
47 | * Backing storage is provided by a regular file or a block device, specified | 47 | * Backing storage is provided by a regular file or a block device, specified |
48 | * by the "file" module parameter. Access can be limited to read-only by | 48 | * by the "file" module parameter. Access can be limited to read-only by |
49 | * setting the optional "ro" module parameter. The gadget will indicate that | 49 | * setting the optional "ro" module parameter. (For CD-ROM emulation, |
50 | * it has removable media if the optional "removable" module parameter is set. | 50 | * access is always read-only.) The gadget will indicate that it has |
51 | * removable media if the optional "removable" module parameter is set. | ||
51 | * | 52 | * |
52 | * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), | 53 | * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), |
53 | * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected | 54 | * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected |
@@ -64,7 +65,12 @@ | |||
64 | * The default number of LUNs is taken from the number of "file" elements; | 65 | * The default number of LUNs is taken from the number of "file" elements; |
65 | * it is 1 if "file" is not given. If "removable" is not set then a backing | 66 | * it is 1 if "file" is not given. If "removable" is not set then a backing |
66 | * file must be specified for each LUN. If it is set, then an unspecified | 67 | * file must be specified for each LUN. If it is set, then an unspecified |
67 | * or empty backing filename means the LUN's medium is not loaded. | 68 | * or empty backing filename means the LUN's medium is not loaded. Ideally |
69 | * each LUN would be settable independently as a disk drive or a CD-ROM | ||
70 | * drive, but currently all LUNs have to be the same type. The CD-ROM | ||
71 | * emulation includes a single data track and no audio tracks; hence there | ||
72 | * need be only one backing file per LUN. Note also that the CD-ROM block | ||
73 | * length is set to 512 rather than the more common value 2048. | ||
68 | * | 74 | * |
69 | * Requirements are modest; only a bulk-in and a bulk-out endpoint are | 75 | * Requirements are modest; only a bulk-in and a bulk-out endpoint are |
70 | * needed (an interrupt-out endpoint is also needed for CBI). The memory | 76 | * needed (an interrupt-out endpoint is also needed for CBI). The memory |
@@ -91,6 +97,8 @@ | |||
91 | * USB device controller (usually true), | 97 | * USB device controller (usually true), |
92 | * boolean to permit the driver to halt | 98 | * boolean to permit the driver to halt |
93 | * bulk endpoints | 99 | * bulk endpoints |
100 | * cdrom Default false, boolean for whether to emulate | ||
101 | * a CD-ROM drive | ||
94 | * transport=XXX Default BBB, transport name (CB, CBI, or BBB) | 102 | * transport=XXX Default BBB, transport name (CB, CBI, or BBB) |
95 | * protocol=YYY Default SCSI, protocol name (RBC, 8020 or | 103 | * protocol=YYY Default SCSI, protocol name (RBC, 8020 or |
96 | * ATAPI, QIC, UFI, 8070, or SCSI; | 104 | * ATAPI, QIC, UFI, 8070, or SCSI; |
@@ -103,15 +111,16 @@ | |||
103 | * PAGE_CACHE_SIZE) | 111 | * PAGE_CACHE_SIZE) |
104 | * | 112 | * |
105 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", | 113 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", |
106 | * "removable", "luns", and "stall" options are available; default values | 114 | * "removable", "luns", "stall", and "cdrom" options are available; default |
107 | * are used for everything else. | 115 | * values are used for everything else. |
108 | * | 116 | * |
109 | * The pathnames of the backing files and the ro settings are available in | 117 | * The pathnames of the backing files and the ro settings are available in |
110 | * the attribute files "file" and "ro" in the lun<n> subdirectory of the | 118 | * the attribute files "file" and "ro" in the lun<n> subdirectory of the |
111 | * gadget's sysfs directory. If the "removable" option is set, writing to | 119 | * gadget's sysfs directory. If the "removable" option is set, writing to |
112 | * these files will simulate ejecting/loading the medium (writing an empty | 120 | * these files will simulate ejecting/loading the medium (writing an empty |
113 | * line means eject) and adjusting a write-enable tab. Changes to the ro | 121 | * line means eject) and adjusting a write-enable tab. Changes to the ro |
114 | * setting are not allowed when the medium is loaded. | 122 | * setting are not allowed when the medium is loaded or if CD-ROM emulation |
123 | * is being used. | ||
115 | * | 124 | * |
116 | * This gadget driver is heavily based on "Gadget Zero" by David Brownell. | 125 | * This gadget driver is heavily based on "Gadget Zero" by David Brownell. |
117 | * The driver's SCSI command interface was based on the "Information | 126 | * The driver's SCSI command interface was based on the "Information |
@@ -261,7 +270,7 @@ | |||
261 | 270 | ||
262 | #define DRIVER_DESC "File-backed Storage Gadget" | 271 | #define DRIVER_DESC "File-backed Storage Gadget" |
263 | #define DRIVER_NAME "g_file_storage" | 272 | #define DRIVER_NAME "g_file_storage" |
264 | #define DRIVER_VERSION "7 August 2007" | 273 | #define DRIVER_VERSION "20 November 2008" |
265 | 274 | ||
266 | static const char longname[] = DRIVER_DESC; | 275 | static const char longname[] = DRIVER_DESC; |
267 | static const char shortname[] = DRIVER_NAME; | 276 | static const char shortname[] = DRIVER_NAME; |
@@ -341,6 +350,7 @@ static struct { | |||
341 | 350 | ||
342 | int removable; | 351 | int removable; |
343 | int can_stall; | 352 | int can_stall; |
353 | int cdrom; | ||
344 | 354 | ||
345 | char *transport_parm; | 355 | char *transport_parm; |
346 | char *protocol_parm; | 356 | char *protocol_parm; |
@@ -359,6 +369,7 @@ static struct { | |||
359 | .protocol_parm = "SCSI", | 369 | .protocol_parm = "SCSI", |
360 | .removable = 0, | 370 | .removable = 0, |
361 | .can_stall = 1, | 371 | .can_stall = 1, |
372 | .cdrom = 0, | ||
362 | .vendor = DRIVER_VENDOR_ID, | 373 | .vendor = DRIVER_VENDOR_ID, |
363 | .product = DRIVER_PRODUCT_ID, | 374 | .product = DRIVER_PRODUCT_ID, |
364 | .release = 0xffff, // Use controller chip type | 375 | .release = 0xffff, // Use controller chip type |
@@ -382,6 +393,9 @@ MODULE_PARM_DESC(removable, "true to simulate removable media"); | |||
382 | module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); | 393 | module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); |
383 | MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); | 394 | MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); |
384 | 395 | ||
396 | module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); | ||
397 | MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); | ||
398 | |||
385 | 399 | ||
386 | /* In the non-TEST version, only the module parameters listed above | 400 | /* In the non-TEST version, only the module parameters listed above |
387 | * are available. */ | 401 | * are available. */ |
@@ -411,6 +425,10 @@ MODULE_PARM_DESC(buflen, "I/O buffer size"); | |||
411 | 425 | ||
412 | /*-------------------------------------------------------------------------*/ | 426 | /*-------------------------------------------------------------------------*/ |
413 | 427 | ||
428 | /* SCSI device types */ | ||
429 | #define TYPE_DISK 0x00 | ||
430 | #define TYPE_CDROM 0x05 | ||
431 | |||
414 | /* USB protocol value = the transport method */ | 432 | /* USB protocol value = the transport method */ |
415 | #define USB_PR_CBI 0x00 // Control/Bulk/Interrupt | 433 | #define USB_PR_CBI 0x00 // Control/Bulk/Interrupt |
416 | #define USB_PR_CB 0x01 // Control/Bulk w/o interrupt | 434 | #define USB_PR_CB 0x01 // Control/Bulk w/o interrupt |
@@ -487,6 +505,8 @@ struct interrupt_data { | |||
487 | #define SC_READ_12 0xa8 | 505 | #define SC_READ_12 0xa8 |
488 | #define SC_READ_CAPACITY 0x25 | 506 | #define SC_READ_CAPACITY 0x25 |
489 | #define SC_READ_FORMAT_CAPACITIES 0x23 | 507 | #define SC_READ_FORMAT_CAPACITIES 0x23 |
508 | #define SC_READ_HEADER 0x44 | ||
509 | #define SC_READ_TOC 0x43 | ||
490 | #define SC_RELEASE 0x17 | 510 | #define SC_RELEASE 0x17 |
491 | #define SC_REQUEST_SENSE 0x03 | 511 | #define SC_REQUEST_SENSE 0x03 |
492 | #define SC_RESERVE 0x16 | 512 | #define SC_RESERVE 0x16 |
@@ -2006,23 +2026,28 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2006 | u8 *buf = (u8 *) bh->buf; | 2026 | u8 *buf = (u8 *) bh->buf; |
2007 | 2027 | ||
2008 | static char vendor_id[] = "Linux "; | 2028 | static char vendor_id[] = "Linux "; |
2009 | static char product_id[] = "File-Stor Gadget"; | 2029 | static char product_disk_id[] = "File-Stor Gadget"; |
2030 | static char product_cdrom_id[] = "File-CD Gadget "; | ||
2010 | 2031 | ||
2011 | if (!fsg->curlun) { // Unsupported LUNs are okay | 2032 | if (!fsg->curlun) { // Unsupported LUNs are okay |
2012 | fsg->bad_lun_okay = 1; | 2033 | fsg->bad_lun_okay = 1; |
2013 | memset(buf, 0, 36); | 2034 | memset(buf, 0, 36); |
2014 | buf[0] = 0x7f; // Unsupported, no device-type | 2035 | buf[0] = 0x7f; // Unsupported, no device-type |
2036 | buf[4] = 31; // Additional length | ||
2015 | return 36; | 2037 | return 36; |
2016 | } | 2038 | } |
2017 | 2039 | ||
2018 | memset(buf, 0, 8); // Non-removable, direct-access device | 2040 | memset(buf, 0, 8); |
2041 | buf[0] = (mod_data.cdrom ? TYPE_CDROM : TYPE_DISK); | ||
2019 | if (mod_data.removable) | 2042 | if (mod_data.removable) |
2020 | buf[1] = 0x80; | 2043 | buf[1] = 0x80; |
2021 | buf[2] = 2; // ANSI SCSI level 2 | 2044 | buf[2] = 2; // ANSI SCSI level 2 |
2022 | buf[3] = 2; // SCSI-2 INQUIRY data format | 2045 | buf[3] = 2; // SCSI-2 INQUIRY data format |
2023 | buf[4] = 31; // Additional length | 2046 | buf[4] = 31; // Additional length |
2024 | // No special options | 2047 | // No special options |
2025 | sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, product_id, | 2048 | sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, |
2049 | (mod_data.cdrom ? product_cdrom_id : | ||
2050 | product_disk_id), | ||
2026 | mod_data.release); | 2051 | mod_data.release); |
2027 | return 36; | 2052 | return 36; |
2028 | } | 2053 | } |
@@ -2101,6 +2126,75 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2101 | } | 2126 | } |
2102 | 2127 | ||
2103 | 2128 | ||
2129 | static void store_cdrom_address(u8 *dest, int msf, u32 addr) | ||
2130 | { | ||
2131 | if (msf) { | ||
2132 | /* Convert to Minutes-Seconds-Frames */ | ||
2133 | addr >>= 2; /* Convert to 2048-byte frames */ | ||
2134 | addr += 2*75; /* Lead-in occupies 2 seconds */ | ||
2135 | dest[3] = addr % 75; /* Frames */ | ||
2136 | addr /= 75; | ||
2137 | dest[2] = addr % 60; /* Seconds */ | ||
2138 | addr /= 60; | ||
2139 | dest[1] = addr; /* Minutes */ | ||
2140 | dest[0] = 0; /* Reserved */ | ||
2141 | } else { | ||
2142 | /* Absolute sector */ | ||
2143 | put_be32(dest, addr); | ||
2144 | } | ||
2145 | } | ||
2146 | |||
2147 | static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
2148 | { | ||
2149 | struct lun *curlun = fsg->curlun; | ||
2150 | int msf = fsg->cmnd[1] & 0x02; | ||
2151 | u32 lba = get_be32(&fsg->cmnd[2]); | ||
2152 | u8 *buf = (u8 *) bh->buf; | ||
2153 | |||
2154 | if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */ | ||
2155 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
2156 | return -EINVAL; | ||
2157 | } | ||
2158 | if (lba >= curlun->num_sectors) { | ||
2159 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | ||
2160 | return -EINVAL; | ||
2161 | } | ||
2162 | |||
2163 | memset(buf, 0, 8); | ||
2164 | buf[0] = 0x01; /* 2048 bytes of user data, rest is EC */ | ||
2165 | store_cdrom_address(&buf[4], msf, lba); | ||
2166 | return 8; | ||
2167 | } | ||
2168 | |||
2169 | |||
2170 | static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | ||
2171 | { | ||
2172 | struct lun *curlun = fsg->curlun; | ||
2173 | int msf = fsg->cmnd[1] & 0x02; | ||
2174 | int start_track = fsg->cmnd[6]; | ||
2175 | u8 *buf = (u8 *) bh->buf; | ||
2176 | |||
2177 | if ((fsg->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ | ||
2178 | start_track > 1) { | ||
2179 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | ||
2180 | return -EINVAL; | ||
2181 | } | ||
2182 | |||
2183 | memset(buf, 0, 20); | ||
2184 | buf[1] = (20-2); /* TOC data length */ | ||
2185 | buf[2] = 1; /* First track number */ | ||
2186 | buf[3] = 1; /* Last track number */ | ||
2187 | buf[5] = 0x16; /* Data track, copying allowed */ | ||
2188 | buf[6] = 0x01; /* Only track is number 1 */ | ||
2189 | store_cdrom_address(&buf[8], msf, 0); | ||
2190 | |||
2191 | buf[13] = 0x16; /* Lead-out track is data */ | ||
2192 | buf[14] = 0xAA; /* Lead-out track number */ | ||
2193 | store_cdrom_address(&buf[16], msf, curlun->num_sectors); | ||
2194 | return 20; | ||
2195 | } | ||
2196 | |||
2197 | |||
2104 | static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | 2198 | static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) |
2105 | { | 2199 | { |
2106 | struct lun *curlun = fsg->curlun; | 2200 | struct lun *curlun = fsg->curlun; |
@@ -2848,6 +2942,26 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2848 | reply = do_read_capacity(fsg, bh); | 2942 | reply = do_read_capacity(fsg, bh); |
2849 | break; | 2943 | break; |
2850 | 2944 | ||
2945 | case SC_READ_HEADER: | ||
2946 | if (!mod_data.cdrom) | ||
2947 | goto unknown_cmnd; | ||
2948 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | ||
2949 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
2950 | (3<<7) | (0x1f<<1), 1, | ||
2951 | "READ HEADER")) == 0) | ||
2952 | reply = do_read_header(fsg, bh); | ||
2953 | break; | ||
2954 | |||
2955 | case SC_READ_TOC: | ||
2956 | if (!mod_data.cdrom) | ||
2957 | goto unknown_cmnd; | ||
2958 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | ||
2959 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | ||
2960 | (7<<6) | (1<<1), 1, | ||
2961 | "READ TOC")) == 0) | ||
2962 | reply = do_read_toc(fsg, bh); | ||
2963 | break; | ||
2964 | |||
2851 | case SC_READ_FORMAT_CAPACITIES: | 2965 | case SC_READ_FORMAT_CAPACITIES: |
2852 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | 2966 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); |
2853 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2967 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
@@ -2933,6 +3047,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2933 | // Fall through | 3047 | // Fall through |
2934 | 3048 | ||
2935 | default: | 3049 | default: |
3050 | unknown_cmnd: | ||
2936 | fsg->data_size_from_cmnd = 0; | 3051 | fsg->data_size_from_cmnd = 0; |
2937 | sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); | 3052 | sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); |
2938 | if ((reply = check_command(fsg, fsg->cmnd_size, | 3053 | if ((reply = check_command(fsg, fsg->cmnd_size, |
@@ -3498,6 +3613,7 @@ static int open_backing_file(struct lun *curlun, const char *filename) | |||
3498 | struct inode *inode = NULL; | 3613 | struct inode *inode = NULL; |
3499 | loff_t size; | 3614 | loff_t size; |
3500 | loff_t num_sectors; | 3615 | loff_t num_sectors; |
3616 | loff_t min_sectors; | ||
3501 | 3617 | ||
3502 | /* R/W if we can, R/O if we must */ | 3618 | /* R/W if we can, R/O if we must */ |
3503 | ro = curlun->ro; | 3619 | ro = curlun->ro; |
@@ -3541,8 +3657,19 @@ static int open_backing_file(struct lun *curlun, const char *filename) | |||
3541 | rc = (int) size; | 3657 | rc = (int) size; |
3542 | goto out; | 3658 | goto out; |
3543 | } | 3659 | } |
3544 | num_sectors = size >> 9; // File size in 512-byte sectors | 3660 | num_sectors = size >> 9; // File size in 512-byte blocks |
3545 | if (num_sectors == 0) { | 3661 | min_sectors = 1; |
3662 | if (mod_data.cdrom) { | ||
3663 | num_sectors &= ~3; // Reduce to a multiple of 2048 | ||
3664 | min_sectors = 300*4; // Smallest track is 300 frames | ||
3665 | if (num_sectors >= 256*60*75*4) { | ||
3666 | num_sectors = (256*60*75 - 1) * 4; | ||
3667 | LINFO(curlun, "file too big: %s\n", filename); | ||
3668 | LINFO(curlun, "using only first %d blocks\n", | ||
3669 | (int) num_sectors); | ||
3670 | } | ||
3671 | } | ||
3672 | if (num_sectors < min_sectors) { | ||
3546 | LINFO(curlun, "file too small: %s\n", filename); | 3673 | LINFO(curlun, "file too small: %s\n", filename); |
3547 | rc = -ETOOSMALL; | 3674 | rc = -ETOOSMALL; |
3548 | goto out; | 3675 | goto out; |
@@ -3845,9 +3972,12 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3845 | goto out; | 3972 | goto out; |
3846 | 3973 | ||
3847 | if (mod_data.removable) { // Enable the store_xxx attributes | 3974 | if (mod_data.removable) { // Enable the store_xxx attributes |
3848 | dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644; | 3975 | dev_attr_file.attr.mode = 0644; |
3849 | dev_attr_ro.store = store_ro; | ||
3850 | dev_attr_file.store = store_file; | 3976 | dev_attr_file.store = store_file; |
3977 | if (!mod_data.cdrom) { | ||
3978 | dev_attr_ro.attr.mode = 0644; | ||
3979 | dev_attr_ro.store = store_ro; | ||
3980 | } | ||
3851 | } | 3981 | } |
3852 | 3982 | ||
3853 | /* Find out how many LUNs there should be */ | 3983 | /* Find out how many LUNs there should be */ |
@@ -3872,6 +4002,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3872 | for (i = 0; i < fsg->nluns; ++i) { | 4002 | for (i = 0; i < fsg->nluns; ++i) { |
3873 | curlun = &fsg->luns[i]; | 4003 | curlun = &fsg->luns[i]; |
3874 | curlun->ro = mod_data.ro[i]; | 4004 | curlun->ro = mod_data.ro[i]; |
4005 | if (mod_data.cdrom) | ||
4006 | curlun->ro = 1; | ||
3875 | curlun->dev.release = lun_release; | 4007 | curlun->dev.release = lun_release; |
3876 | curlun->dev.parent = &gadget->dev; | 4008 | curlun->dev.parent = &gadget->dev; |
3877 | curlun->dev.driver = &fsg_driver.driver; | 4009 | curlun->dev.driver = &fsg_driver.driver; |
@@ -4031,9 +4163,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
4031 | mod_data.protocol_name, mod_data.protocol_type); | 4163 | mod_data.protocol_name, mod_data.protocol_type); |
4032 | DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", | 4164 | DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", |
4033 | mod_data.vendor, mod_data.product, mod_data.release); | 4165 | mod_data.vendor, mod_data.product, mod_data.release); |
4034 | DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", | 4166 | DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", |
4035 | mod_data.removable, mod_data.can_stall, | 4167 | mod_data.removable, mod_data.can_stall, |
4036 | mod_data.buflen); | 4168 | mod_data.cdrom, mod_data.buflen); |
4037 | DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); | 4169 | DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); |
4038 | 4170 | ||
4039 | set_bit(REGISTERED, &fsg->atomic_bitflags); | 4171 | set_bit(REGISTERED, &fsg->atomic_bitflags); |
@@ -4050,6 +4182,7 @@ out: | |||
4050 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead | 4182 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead |
4051 | fsg_unbind(gadget); | 4183 | fsg_unbind(gadget); |
4052 | close_all_backing_files(fsg); | 4184 | close_all_backing_files(fsg); |
4185 | complete(&fsg->thread_notifier); | ||
4053 | return rc; | 4186 | return rc; |
4054 | } | 4187 | } |
4055 | 4188 | ||
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index b3408ff39fba..d6c5bcd40064 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/err.h> | ||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/list.h> | 31 | #include <linux/list.h> |
31 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
@@ -370,6 +371,9 @@ static int qe_ep_bd_init(struct qe_udc *udc, unsigned char pipe_num) | |||
370 | /* alloc multi-ram for BD rings and set the ep parameters */ | 371 | /* alloc multi-ram for BD rings and set the ep parameters */ |
371 | tmp_addr = cpm_muram_alloc(sizeof(struct qe_bd) * (bdring_len + | 372 | tmp_addr = cpm_muram_alloc(sizeof(struct qe_bd) * (bdring_len + |
372 | USB_BDRING_LEN_TX), QE_ALIGNMENT_OF_BD); | 373 | USB_BDRING_LEN_TX), QE_ALIGNMENT_OF_BD); |
374 | if (IS_ERR_VALUE(tmp_addr)) | ||
375 | return -ENOMEM; | ||
376 | |||
373 | out_be16(&epparam->rbase, (u16)tmp_addr); | 377 | out_be16(&epparam->rbase, (u16)tmp_addr); |
374 | out_be16(&epparam->tbase, (u16)(tmp_addr + | 378 | out_be16(&epparam->tbase, (u16)(tmp_addr + |
375 | (sizeof(struct qe_bd) * bdring_len))); | 379 | (sizeof(struct qe_bd) * bdring_len))); |
@@ -689,7 +693,7 @@ en_done2: | |||
689 | en_done1: | 693 | en_done1: |
690 | spin_unlock_irqrestore(&udc->lock, flags); | 694 | spin_unlock_irqrestore(&udc->lock, flags); |
691 | en_done: | 695 | en_done: |
692 | dev_dbg(udc->dev, "failed to initialize %s\n", ep->ep.name); | 696 | dev_err(udc->dev, "failed to initialize %s\n", ep->ep.name); |
693 | return -ENODEV; | 697 | return -ENODEV; |
694 | } | 698 | } |
695 | 699 | ||
@@ -2408,6 +2412,8 @@ static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev) | |||
2408 | tmp_addr = cpm_muram_alloc((USB_MAX_ENDPOINTS * | 2412 | tmp_addr = cpm_muram_alloc((USB_MAX_ENDPOINTS * |
2409 | sizeof(struct usb_ep_para)), | 2413 | sizeof(struct usb_ep_para)), |
2410 | USB_EP_PARA_ALIGNMENT); | 2414 | USB_EP_PARA_ALIGNMENT); |
2415 | if (IS_ERR_VALUE(tmp_addr)) | ||
2416 | goto cleanup; | ||
2411 | 2417 | ||
2412 | for (i = 0; i < USB_MAX_ENDPOINTS; i++) { | 2418 | for (i = 0; i < USB_MAX_ENDPOINTS; i++) { |
2413 | out_be16(&usbpram->epptr[i], (u16)tmp_addr); | 2419 | out_be16(&usbpram->epptr[i], (u16)tmp_addr); |
@@ -2513,7 +2519,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2513 | /* Initialize the udc structure including QH member and other member */ | 2519 | /* Initialize the udc structure including QH member and other member */ |
2514 | udc_controller = qe_udc_config(ofdev); | 2520 | udc_controller = qe_udc_config(ofdev); |
2515 | if (!udc_controller) { | 2521 | if (!udc_controller) { |
2516 | dev_dbg(&ofdev->dev, "udc_controll is NULL\n"); | 2522 | dev_err(&ofdev->dev, "failed to initialize\n"); |
2517 | return -ENOMEM; | 2523 | return -ENOMEM; |
2518 | } | 2524 | } |
2519 | 2525 | ||
@@ -2545,7 +2551,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2545 | 2551 | ||
2546 | device_initialize(&udc_controller->gadget.dev); | 2552 | device_initialize(&udc_controller->gadget.dev); |
2547 | 2553 | ||
2548 | strcpy(udc_controller->gadget.dev.bus_id, "gadget"); | 2554 | dev_set_name(&udc_controller->gadget.dev, "gadget"); |
2549 | 2555 | ||
2550 | udc_controller->gadget.dev.release = qe_udc_release; | 2556 | udc_controller->gadget.dev.release = qe_udc_release; |
2551 | udc_controller->gadget.dev.parent = &ofdev->dev; | 2557 | udc_controller->gadget.dev.parent = &ofdev->dev; |
@@ -2568,7 +2574,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2568 | /* create a buf for ZLP send, need to remain zeroed */ | 2574 | /* create a buf for ZLP send, need to remain zeroed */ |
2569 | udc_controller->nullbuf = kzalloc(256, GFP_KERNEL); | 2575 | udc_controller->nullbuf = kzalloc(256, GFP_KERNEL); |
2570 | if (udc_controller->nullbuf == NULL) { | 2576 | if (udc_controller->nullbuf == NULL) { |
2571 | dev_dbg(udc_controller->dev, "cannot alloc nullbuf\n"); | 2577 | dev_err(udc_controller->dev, "cannot alloc nullbuf\n"); |
2572 | ret = -ENOMEM; | 2578 | ret = -ENOMEM; |
2573 | goto err3; | 2579 | goto err3; |
2574 | } | 2580 | } |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 4e3107dd2f34..ec6d439a2aa5 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -110,7 +110,6 @@ | |||
110 | #define gadget_is_at91(g) 0 | 110 | #define gadget_is_at91(g) 0 |
111 | #endif | 111 | #endif |
112 | 112 | ||
113 | /* status unclear */ | ||
114 | #ifdef CONFIG_USB_GADGET_IMX | 113 | #ifdef CONFIG_USB_GADGET_IMX |
115 | #define gadget_is_imx(g) !strcmp("imx_udc", (g)->name) | 114 | #define gadget_is_imx(g) !strcmp("imx_udc", (g)->name) |
116 | #else | 115 | #else |
@@ -158,6 +157,11 @@ | |||
158 | #define gadget_is_fsl_qe(g) 0 | 157 | #define gadget_is_fsl_qe(g) 0 |
159 | #endif | 158 | #endif |
160 | 159 | ||
160 | #ifdef CONFIG_USB_GADGET_CI13XXX | ||
161 | #define gadget_is_ci13xxx(g) (!strcmp("ci13xxx_udc", (g)->name)) | ||
162 | #else | ||
163 | #define gadget_is_ci13xxx(g) 0 | ||
164 | #endif | ||
161 | 165 | ||
162 | // CONFIG_USB_GADGET_SX2 | 166 | // CONFIG_USB_GADGET_SX2 |
163 | // CONFIG_USB_GADGET_AU1X00 | 167 | // CONFIG_USB_GADGET_AU1X00 |
@@ -225,6 +229,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
225 | return 0x21; | 229 | return 0x21; |
226 | else if (gadget_is_fsl_qe(gadget)) | 230 | else if (gadget_is_fsl_qe(gadget)) |
227 | return 0x22; | 231 | return 0x22; |
232 | else if (gadget_is_ci13xxx(gadget)) | ||
233 | return 0x23; | ||
228 | return -ENOENT; | 234 | return -ENOENT; |
229 | } | 235 | } |
230 | 236 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 60aa04847b18..63419c4d503c 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1349,7 +1349,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1349 | int retval; | 1349 | int retval; |
1350 | 1350 | ||
1351 | if (!driver | 1351 | if (!driver |
1352 | || driver->speed != USB_SPEED_FULL | 1352 | || driver->speed < USB_SPEED_FULL |
1353 | || !driver->bind | 1353 | || !driver->bind |
1354 | || !driver->disconnect | 1354 | || !driver->disconnect |
1355 | || !driver->setup) | 1355 | || !driver->setup) |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c new file mode 100644 index 000000000000..cde8fdf15d5b --- /dev/null +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -0,0 +1,1516 @@ | |||
1 | /* | ||
2 | * driver/usb/gadget/imx_udc.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Mike Lee(eemike@gmail.com) | ||
5 | * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com> | ||
6 | * | ||
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 | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/device.h> | ||
28 | #include <linux/dma-mapping.h> | ||
29 | #include <linux/clk.h> | ||
30 | #include <linux/delay.h> | ||
31 | |||
32 | #include <linux/usb/ch9.h> | ||
33 | #include <linux/usb/gadget.h> | ||
34 | |||
35 | #include <mach/usb.h> | ||
36 | #include <mach/hardware.h> | ||
37 | |||
38 | #include "imx_udc.h" | ||
39 | |||
40 | static const char driver_name[] = "imx_udc"; | ||
41 | static const char ep0name[] = "ep0"; | ||
42 | |||
43 | void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb, | ||
44 | enum ep0_state stat); | ||
45 | |||
46 | /******************************************************************************* | ||
47 | * IMX UDC hardware related functions | ||
48 | ******************************************************************************* | ||
49 | */ | ||
50 | |||
51 | void imx_udc_enable(struct imx_udc_struct *imx_usb) | ||
52 | { | ||
53 | int temp = __raw_readl(imx_usb->base + USB_CTRL); | ||
54 | __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL); | ||
55 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
56 | } | ||
57 | |||
58 | void imx_udc_disable(struct imx_udc_struct *imx_usb) | ||
59 | { | ||
60 | int temp = __raw_readl(imx_usb->base + USB_CTRL); | ||
61 | |||
62 | __raw_writel(temp & ~(CTRL_FE_ENA | CTRL_AFE_ENA), | ||
63 | imx_usb->base + USB_CTRL); | ||
64 | |||
65 | ep0_chg_stat(__func__, imx_usb, EP0_IDLE); | ||
66 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
67 | } | ||
68 | |||
69 | void imx_udc_reset(struct imx_udc_struct *imx_usb) | ||
70 | { | ||
71 | int temp = __raw_readl(imx_usb->base + USB_ENAB); | ||
72 | |||
73 | /* set RST bit */ | ||
74 | __raw_writel(temp | ENAB_RST, imx_usb->base + USB_ENAB); | ||
75 | |||
76 | /* wait RST bit to clear */ | ||
77 | do {} while (__raw_readl(imx_usb->base + USB_ENAB) & ENAB_RST); | ||
78 | |||
79 | /* wait CFG bit to assert */ | ||
80 | do {} while (!(__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG)); | ||
81 | |||
82 | /* udc module is now ready */ | ||
83 | } | ||
84 | |||
85 | void imx_udc_config(struct imx_udc_struct *imx_usb) | ||
86 | { | ||
87 | u8 ep_conf[5]; | ||
88 | u8 i, j, cfg; | ||
89 | struct imx_ep_struct *imx_ep; | ||
90 | |||
91 | /* wait CFG bit to assert */ | ||
92 | do {} while (!(__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG)); | ||
93 | |||
94 | /* Download the endpoint buffer for endpoint 0. */ | ||
95 | for (j = 0; j < 5; j++) { | ||
96 | i = (j == 2 ? imx_usb->imx_ep[0].fifosize : 0x00); | ||
97 | __raw_writeb(i, imx_usb->base + USB_DDAT); | ||
98 | do {} while (__raw_readl(imx_usb->base + USB_DADR) & DADR_BSY); | ||
99 | } | ||
100 | |||
101 | /* Download the endpoint buffers for endpoints 1-5. | ||
102 | * We specify two configurations, one interface | ||
103 | */ | ||
104 | for (cfg = 1; cfg < 3; cfg++) { | ||
105 | for (i = 1; i < IMX_USB_NB_EP; i++) { | ||
106 | imx_ep = &imx_usb->imx_ep[i]; | ||
107 | /* EP no | Config no */ | ||
108 | ep_conf[0] = (i << 4) | (cfg << 2); | ||
109 | /* Type | Direction */ | ||
110 | ep_conf[1] = (imx_ep->bmAttributes << 3) | | ||
111 | (EP_DIR(imx_ep) << 2); | ||
112 | /* Max packet size */ | ||
113 | ep_conf[2] = imx_ep->fifosize; | ||
114 | /* TRXTYP */ | ||
115 | ep_conf[3] = 0xC0; | ||
116 | /* FIFO no */ | ||
117 | ep_conf[4] = i; | ||
118 | |||
119 | D_INI(imx_usb->dev, | ||
120 | "<%s> ep%d_conf[%d]:" | ||
121 | "[%02x-%02x-%02x-%02x-%02x]\n", | ||
122 | __func__, i, cfg, | ||
123 | ep_conf[0], ep_conf[1], ep_conf[2], | ||
124 | ep_conf[3], ep_conf[4]); | ||
125 | |||
126 | for (j = 0; j < 5; j++) { | ||
127 | __raw_writeb(ep_conf[j], | ||
128 | imx_usb->base + USB_DDAT); | ||
129 | do {} while (__raw_readl(imx_usb->base + USB_DADR) | ||
130 | & DADR_BSY); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /* wait CFG bit to clear */ | ||
136 | do {} while (__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG); | ||
137 | } | ||
138 | |||
139 | void imx_udc_init_irq(struct imx_udc_struct *imx_usb) | ||
140 | { | ||
141 | int i; | ||
142 | |||
143 | /* Mask and clear all irqs */ | ||
144 | __raw_writel(0xFFFFFFFF, imx_usb->base + USB_MASK); | ||
145 | __raw_writel(0xFFFFFFFF, imx_usb->base + USB_INTR); | ||
146 | for (i = 0; i < IMX_USB_NB_EP; i++) { | ||
147 | __raw_writel(0x1FF, imx_usb->base + USB_EP_MASK(i)); | ||
148 | __raw_writel(0x1FF, imx_usb->base + USB_EP_INTR(i)); | ||
149 | } | ||
150 | |||
151 | /* Enable USB irqs */ | ||
152 | __raw_writel(INTR_MSOF | INTR_FRAME_MATCH, imx_usb->base + USB_MASK); | ||
153 | |||
154 | /* Enable EP0 irqs */ | ||
155 | __raw_writel(0x1FF & ~(EPINTR_DEVREQ | EPINTR_MDEVREQ | EPINTR_EOT | ||
156 | | EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL), | ||
157 | imx_usb->base + USB_EP_MASK(0)); | ||
158 | } | ||
159 | |||
160 | void imx_udc_init_ep(struct imx_udc_struct *imx_usb) | ||
161 | { | ||
162 | int i, max, temp; | ||
163 | struct imx_ep_struct *imx_ep; | ||
164 | for (i = 0; i < IMX_USB_NB_EP; i++) { | ||
165 | imx_ep = &imx_usb->imx_ep[i]; | ||
166 | switch (imx_ep->fifosize) { | ||
167 | case 8: | ||
168 | max = 0; | ||
169 | break; | ||
170 | case 16: | ||
171 | max = 1; | ||
172 | break; | ||
173 | case 32: | ||
174 | max = 2; | ||
175 | break; | ||
176 | case 64: | ||
177 | max = 3; | ||
178 | break; | ||
179 | default: | ||
180 | max = 1; | ||
181 | break; | ||
182 | } | ||
183 | temp = (EP_DIR(imx_ep) << 7) | (max << 5) | ||
184 | | (imx_ep->bmAttributes << 3); | ||
185 | __raw_writel(temp, imx_usb->base + USB_EP_STAT(i)); | ||
186 | __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i)); | ||
187 | D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i, | ||
188 | __raw_readl(imx_usb->base + USB_EP_STAT(i))); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | void imx_udc_init_fifo(struct imx_udc_struct *imx_usb) | ||
193 | { | ||
194 | int i, temp; | ||
195 | struct imx_ep_struct *imx_ep; | ||
196 | for (i = 0; i < IMX_USB_NB_EP; i++) { | ||
197 | imx_ep = &imx_usb->imx_ep[i]; | ||
198 | |||
199 | /* Fifo control */ | ||
200 | temp = EP_DIR(imx_ep) ? 0x0B000000 : 0x0F000000; | ||
201 | __raw_writel(temp, imx_usb->base + USB_EP_FCTRL(i)); | ||
202 | D_INI(imx_usb->dev, "<%s> ep%d_fctrl %08x\n", __func__, i, | ||
203 | __raw_readl(imx_usb->base + USB_EP_FCTRL(i))); | ||
204 | |||
205 | /* Fifo alarm */ | ||
206 | temp = (i ? imx_ep->fifosize / 2 : 0); | ||
207 | __raw_writel(temp, imx_usb->base + USB_EP_FALRM(i)); | ||
208 | D_INI(imx_usb->dev, "<%s> ep%d_falrm %08x\n", __func__, i, | ||
209 | __raw_readl(imx_usb->base + USB_EP_FALRM(i))); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | static void imx_udc_init(struct imx_udc_struct *imx_usb) | ||
214 | { | ||
215 | /* Reset UDC */ | ||
216 | imx_udc_reset(imx_usb); | ||
217 | |||
218 | /* Download config to enpoint buffer */ | ||
219 | imx_udc_config(imx_usb); | ||
220 | |||
221 | /* Setup interrups */ | ||
222 | imx_udc_init_irq(imx_usb); | ||
223 | |||
224 | /* Setup endpoints */ | ||
225 | imx_udc_init_ep(imx_usb); | ||
226 | |||
227 | /* Setup fifos */ | ||
228 | imx_udc_init_fifo(imx_usb); | ||
229 | } | ||
230 | |||
231 | void imx_ep_irq_enable(struct imx_ep_struct *imx_ep) | ||
232 | { | ||
233 | |||
234 | int i = EP_NO(imx_ep); | ||
235 | |||
236 | __raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_MASK(i)); | ||
237 | __raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_INTR(i)); | ||
238 | __raw_writel(0x1FF & ~(EPINTR_EOT | EPINTR_EOF), | ||
239 | imx_ep->imx_usb->base + USB_EP_MASK(i)); | ||
240 | } | ||
241 | |||
242 | void imx_ep_irq_disable(struct imx_ep_struct *imx_ep) | ||
243 | { | ||
244 | |||
245 | int i = EP_NO(imx_ep); | ||
246 | |||
247 | __raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_MASK(i)); | ||
248 | __raw_writel(0x1FF, imx_ep->imx_usb->base + USB_EP_INTR(i)); | ||
249 | } | ||
250 | |||
251 | int imx_ep_empty(struct imx_ep_struct *imx_ep) | ||
252 | { | ||
253 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | ||
254 | |||
255 | return __raw_readl(imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep))) | ||
256 | & FSTAT_EMPTY; | ||
257 | } | ||
258 | |||
259 | unsigned imx_fifo_bcount(struct imx_ep_struct *imx_ep) | ||
260 | { | ||
261 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | ||
262 | |||
263 | return (__raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))) | ||
264 | & EPSTAT_BCOUNT) >> 16; | ||
265 | } | ||
266 | |||
267 | void imx_flush(struct imx_ep_struct *imx_ep) | ||
268 | { | ||
269 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | ||
270 | |||
271 | int temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | ||
272 | __raw_writel(temp | EPSTAT_FLUSH, | ||
273 | imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | ||
274 | } | ||
275 | |||
276 | void imx_ep_stall(struct imx_ep_struct *imx_ep) | ||
277 | { | ||
278 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | ||
279 | int temp, i; | ||
280 | |||
281 | D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name); | ||
282 | |||
283 | imx_flush(imx_ep); | ||
284 | |||
285 | /* Special care for ep0 */ | ||
286 | if (EP_NO(imx_ep)) { | ||
287 | temp = __raw_readl(imx_usb->base + USB_CTRL); | ||
288 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL); | ||
289 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER); | ||
290 | temp = __raw_readl(imx_usb->base + USB_CTRL); | ||
291 | __raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL); | ||
292 | } | ||
293 | else { | ||
294 | temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | ||
295 | __raw_writel(temp | EPSTAT_STALL, | ||
296 | imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | ||
297 | |||
298 | for (i = 0; i < 100; i ++) { | ||
299 | temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | ||
300 | if (!temp & EPSTAT_STALL) | ||
301 | break; | ||
302 | udelay(20); | ||
303 | } | ||
304 | if (i == 50) | ||
305 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", | ||
306 | __func__, imx_ep->ep.name); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | static int imx_udc_get_frame(struct usb_gadget *_gadget) | ||
311 | { | ||
312 | struct imx_udc_struct *imx_usb = container_of(_gadget, | ||
313 | struct imx_udc_struct, gadget); | ||
314 | |||
315 | return __raw_readl(imx_usb->base + USB_FRAME) & 0x7FF; | ||
316 | } | ||
317 | |||
318 | static int imx_udc_wakeup(struct usb_gadget *_gadget) | ||
319 | { | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | /******************************************************************************* | ||
324 | * USB request control functions | ||
325 | ******************************************************************************* | ||
326 | */ | ||
327 | |||
328 | static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | ||
329 | { | ||
330 | if (unlikely(!req)) | ||
331 | return; | ||
332 | |||
333 | req->in_use = 1; | ||
334 | list_add_tail(&req->queue, &imx_ep->queue); | ||
335 | } | ||
336 | |||
337 | static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | ||
338 | { | ||
339 | if (unlikely(!req)) | ||
340 | return; | ||
341 | |||
342 | list_del_init(&req->queue); | ||
343 | req->in_use = 0; | ||
344 | } | ||
345 | |||
346 | static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status) | ||
347 | { | ||
348 | ep_del_request(imx_ep, req); | ||
349 | |||
350 | if (likely(req->req.status == -EINPROGRESS)) | ||
351 | req->req.status = status; | ||
352 | else | ||
353 | status = req->req.status; | ||
354 | |||
355 | if (status && status != -ESHUTDOWN) | ||
356 | D_ERR(imx_ep->imx_usb->dev, | ||
357 | "<%s> complete %s req %p stat %d len %u/%u\n", __func__, | ||
358 | imx_ep->ep.name, &req->req, status, | ||
359 | req->req.actual, req->req.length); | ||
360 | |||
361 | req->req.complete(&imx_ep->ep, &req->req); | ||
362 | } | ||
363 | |||
364 | static void nuke(struct imx_ep_struct *imx_ep, int status) | ||
365 | { | ||
366 | struct imx_request *req; | ||
367 | |||
368 | while (!list_empty(&imx_ep->queue)) { | ||
369 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); | ||
370 | done(imx_ep, req, status); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | /******************************************************************************* | ||
375 | * Data tansfer over USB functions | ||
376 | ******************************************************************************* | ||
377 | */ | ||
378 | static int read_packet(struct imx_ep_struct *imx_ep, struct imx_request *req) | ||
379 | { | ||
380 | u8 *buf; | ||
381 | int bytes_ep, bufferspace, count, i; | ||
382 | |||
383 | bytes_ep = imx_fifo_bcount(imx_ep); | ||
384 | bufferspace = req->req.length - req->req.actual; | ||
385 | |||
386 | buf = req->req.buf + req->req.actual; | ||
387 | prefetchw(buf); | ||
388 | |||
389 | if (unlikely(imx_ep_empty(imx_ep))) | ||
390 | count = 0; /* zlp */ | ||
391 | else | ||
392 | count = min(bytes_ep, bufferspace); | ||
393 | |||
394 | for (i = count; i > 0; i--) | ||
395 | *buf++ = __raw_readb(imx_ep->imx_usb->base | ||
396 | + USB_EP_FDAT0(EP_NO(imx_ep))); | ||
397 | req->req.actual += count; | ||
398 | |||
399 | return count; | ||
400 | } | ||
401 | |||
402 | static int write_packet(struct imx_ep_struct *imx_ep, struct imx_request *req) | ||
403 | { | ||
404 | u8 *buf; | ||
405 | int length, count, temp; | ||
406 | |||
407 | buf = req->req.buf + req->req.actual; | ||
408 | prefetch(buf); | ||
409 | |||
410 | length = min(req->req.length - req->req.actual, (u32)imx_ep->fifosize); | ||
411 | |||
412 | if (imx_fifo_bcount(imx_ep) + length > imx_ep->fifosize) { | ||
413 | D_TRX(imx_ep->imx_usb->dev, "<%s> packet overfill %s fifo\n", | ||
414 | __func__, imx_ep->ep.name); | ||
415 | return -1; | ||
416 | } | ||
417 | |||
418 | req->req.actual += length; | ||
419 | count = length; | ||
420 | |||
421 | if (!count && req->req.zero) { /* zlp */ | ||
422 | temp = __raw_readl(imx_ep->imx_usb->base | ||
423 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
424 | __raw_writel(temp | EPSTAT_ZLPS, imx_ep->imx_usb->base | ||
425 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
426 | D_TRX(imx_ep->imx_usb->dev, "<%s> zero packet\n", __func__); | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | while (count--) { | ||
431 | if (count == 0) { /* last byte */ | ||
432 | temp = __raw_readl(imx_ep->imx_usb->base | ||
433 | + USB_EP_FCTRL(EP_NO(imx_ep))); | ||
434 | __raw_writel(temp | FCTRL_WFR, imx_ep->imx_usb->base | ||
435 | + USB_EP_FCTRL(EP_NO(imx_ep))); | ||
436 | } | ||
437 | __raw_writeb(*buf++, | ||
438 | imx_ep->imx_usb->base + USB_EP_FDAT0(EP_NO(imx_ep))); | ||
439 | } | ||
440 | |||
441 | return length; | ||
442 | } | ||
443 | |||
444 | static int read_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req) | ||
445 | { | ||
446 | int bytes = 0, | ||
447 | count, | ||
448 | completed = 0; | ||
449 | |||
450 | while (__raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep))) | ||
451 | & FSTAT_FR) { | ||
452 | count = read_packet(imx_ep, req); | ||
453 | bytes += count; | ||
454 | |||
455 | completed = (count != imx_ep->fifosize); | ||
456 | if (completed || req->req.actual == req->req.length) { | ||
457 | completed = 1; | ||
458 | break; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | if (completed || !req->req.length) { | ||
463 | done(imx_ep, req, 0); | ||
464 | D_REQ(imx_ep->imx_usb->dev, "<%s> %s req<%p> %s\n", | ||
465 | __func__, imx_ep->ep.name, req, | ||
466 | completed ? "completed" : "not completed"); | ||
467 | if (!EP_NO(imx_ep)) | ||
468 | ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE); | ||
469 | } | ||
470 | |||
471 | D_TRX(imx_ep->imx_usb->dev, "<%s> bytes read: %d\n", __func__, bytes); | ||
472 | |||
473 | return completed; | ||
474 | } | ||
475 | |||
476 | static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req) | ||
477 | { | ||
478 | int bytes = 0, | ||
479 | count, | ||
480 | completed = 0; | ||
481 | |||
482 | while (!completed) { | ||
483 | count = write_packet(imx_ep, req); | ||
484 | if (count < 0) | ||
485 | break; /* busy */ | ||
486 | bytes += count; | ||
487 | |||
488 | /* last packet "must be" short (or a zlp) */ | ||
489 | completed = (count != imx_ep->fifosize); | ||
490 | |||
491 | if (unlikely(completed)) { | ||
492 | done(imx_ep, req, 0); | ||
493 | D_REQ(imx_ep->imx_usb->dev, "<%s> %s req<%p> %s\n", | ||
494 | __func__, imx_ep->ep.name, req, | ||
495 | completed ? "completed" : "not completed"); | ||
496 | if (!EP_NO(imx_ep)) | ||
497 | ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | D_TRX(imx_ep->imx_usb->dev, "<%s> bytes sent: %d\n", __func__, bytes); | ||
502 | |||
503 | return completed; | ||
504 | } | ||
505 | |||
506 | /******************************************************************************* | ||
507 | * Endpoint handlers | ||
508 | ******************************************************************************* | ||
509 | */ | ||
510 | static int handle_ep(struct imx_ep_struct *imx_ep) | ||
511 | { | ||
512 | struct imx_request *req; | ||
513 | int completed = 0; | ||
514 | |||
515 | do { | ||
516 | if (!list_empty(&imx_ep->queue)) | ||
517 | req = list_entry(imx_ep->queue.next, | ||
518 | struct imx_request, queue); | ||
519 | else { | ||
520 | D_REQ(imx_ep->imx_usb->dev, "<%s> no request on %s\n", | ||
521 | __func__, imx_ep->ep.name); | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | if (EP_DIR(imx_ep)) /* to host */ | ||
526 | completed = write_fifo(imx_ep, req); | ||
527 | else /* to device */ | ||
528 | completed = read_fifo(imx_ep, req); | ||
529 | |||
530 | dump_ep_stat(__func__, imx_ep); | ||
531 | |||
532 | } while (completed); | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static int handle_ep0(struct imx_ep_struct *imx_ep) | ||
538 | { | ||
539 | struct imx_request *req = NULL; | ||
540 | int ret = 0; | ||
541 | |||
542 | if (!list_empty(&imx_ep->queue)) | ||
543 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); | ||
544 | |||
545 | if (req) { | ||
546 | switch (imx_ep->imx_usb->ep0state) { | ||
547 | |||
548 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ | ||
549 | write_fifo(imx_ep, req); | ||
550 | break; | ||
551 | case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR */ | ||
552 | read_fifo(imx_ep, req); | ||
553 | break; | ||
554 | default: | ||
555 | D_EP0(imx_ep->imx_usb->dev, | ||
556 | "<%s> ep0 i/o, odd state %d\n", | ||
557 | __func__, imx_ep->imx_usb->ep0state); | ||
558 | ep_del_request(imx_ep, req); | ||
559 | ret = -EL2HLT; | ||
560 | break; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | return ret; | ||
565 | } | ||
566 | |||
567 | static void handle_ep0_devreq(struct imx_udc_struct *imx_usb) | ||
568 | { | ||
569 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0]; | ||
570 | union { | ||
571 | struct usb_ctrlrequest r; | ||
572 | u8 raw[8]; | ||
573 | u32 word[2]; | ||
574 | } u; | ||
575 | int temp, i; | ||
576 | |||
577 | nuke(imx_ep, -EPROTO); | ||
578 | |||
579 | /* read SETUP packet */ | ||
580 | for (i = 0; i < 2; i++) { | ||
581 | if (imx_ep_empty(imx_ep)) { | ||
582 | D_ERR(imx_usb->dev, | ||
583 | "<%s> no setup packet received\n", __func__); | ||
584 | goto stall; | ||
585 | } | ||
586 | u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep))); | ||
587 | } | ||
588 | |||
589 | temp = imx_ep_empty(imx_ep); | ||
590 | while (!imx_ep_empty(imx_ep)) { | ||
591 | i = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep))); | ||
592 | D_ERR(imx_usb->dev, | ||
593 | "<%s> wrong to have extra bytes for setup : 0x%08x\n", | ||
594 | __func__, i); | ||
595 | } | ||
596 | if (!temp) | ||
597 | goto stall; | ||
598 | |||
599 | le16_to_cpus(&u.r.wValue); | ||
600 | le16_to_cpus(&u.r.wIndex); | ||
601 | le16_to_cpus(&u.r.wLength); | ||
602 | |||
603 | D_REQ(imx_usb->dev, "<%s> SETUP %02x.%02x v%04x i%04x l%04x\n", | ||
604 | __func__, u.r.bRequestType, u.r.bRequest, | ||
605 | u.r.wValue, u.r.wIndex, u.r.wLength); | ||
606 | |||
607 | if (imx_usb->set_config) { | ||
608 | /* NACK the host by using CMDOVER */ | ||
609 | temp = __raw_readl(imx_usb->base + USB_CTRL); | ||
610 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); | ||
611 | |||
612 | D_ERR(imx_usb->dev, | ||
613 | "<%s> set config req is pending, NACK the host\n", | ||
614 | __func__); | ||
615 | return; | ||
616 | } | ||
617 | |||
618 | if (u.r.bRequestType & USB_DIR_IN) | ||
619 | ep0_chg_stat(__func__, imx_usb, EP0_IN_DATA_PHASE); | ||
620 | else | ||
621 | ep0_chg_stat(__func__, imx_usb, EP0_OUT_DATA_PHASE); | ||
622 | |||
623 | i = imx_usb->driver->setup(&imx_usb->gadget, &u.r); | ||
624 | if (i < 0) { | ||
625 | D_ERR(imx_usb->dev, "<%s> device setup error %d\n", | ||
626 | __func__, i); | ||
627 | goto stall; | ||
628 | } | ||
629 | |||
630 | return; | ||
631 | stall: | ||
632 | D_ERR(imx_usb->dev, "<%s> protocol STALL\n", __func__); | ||
633 | imx_ep_stall(imx_ep); | ||
634 | ep0_chg_stat(__func__, imx_usb, EP0_STALL); | ||
635 | return; | ||
636 | } | ||
637 | |||
638 | /******************************************************************************* | ||
639 | * USB gadget callback functions | ||
640 | ******************************************************************************* | ||
641 | */ | ||
642 | |||
643 | static int imx_ep_enable(struct usb_ep *usb_ep, | ||
644 | const struct usb_endpoint_descriptor *desc) | ||
645 | { | ||
646 | struct imx_ep_struct *imx_ep = container_of(usb_ep, | ||
647 | struct imx_ep_struct, ep); | ||
648 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | ||
649 | unsigned long flags; | ||
650 | |||
651 | if (!usb_ep | ||
652 | || !desc | ||
653 | || !EP_NO(imx_ep) | ||
654 | || desc->bDescriptorType != USB_DT_ENDPOINT | ||
655 | || imx_ep->bEndpointAddress != desc->bEndpointAddress) { | ||
656 | D_ERR(imx_usb->dev, | ||
657 | "<%s> bad ep or descriptor\n", __func__); | ||
658 | return -EINVAL; | ||
659 | } | ||
660 | |||
661 | if (imx_ep->bmAttributes != desc->bmAttributes) { | ||
662 | D_ERR(imx_usb->dev, | ||
663 | "<%s> %s type mismatch\n", __func__, usb_ep->name); | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
667 | if (imx_ep->fifosize < le16_to_cpu(desc->wMaxPacketSize)) { | ||
668 | D_ERR(imx_usb->dev, | ||
669 | "<%s> bad %s maxpacket\n", __func__, usb_ep->name); | ||
670 | return -ERANGE; | ||
671 | } | ||
672 | |||
673 | if (!imx_usb->driver || imx_usb->gadget.speed == USB_SPEED_UNKNOWN) { | ||
674 | D_ERR(imx_usb->dev, "<%s> bogus device state\n", __func__); | ||
675 | return -ESHUTDOWN; | ||
676 | } | ||
677 | |||
678 | local_irq_save(flags); | ||
679 | |||
680 | imx_ep->stopped = 0; | ||
681 | imx_flush(imx_ep); | ||
682 | imx_ep_irq_enable(imx_ep); | ||
683 | |||
684 | local_irq_restore(flags); | ||
685 | |||
686 | D_EPX(imx_usb->dev, "<%s> ENABLED %s\n", __func__, usb_ep->name); | ||
687 | return 0; | ||
688 | } | ||
689 | |||
690 | static int imx_ep_disable(struct usb_ep *usb_ep) | ||
691 | { | ||
692 | struct imx_ep_struct *imx_ep = container_of(usb_ep, | ||
693 | struct imx_ep_struct, ep); | ||
694 | unsigned long flags; | ||
695 | |||
696 | if (!usb_ep || !EP_NO(imx_ep) || !list_empty(&imx_ep->queue)) { | ||
697 | D_ERR(imx_ep->imx_usb->dev, "<%s> %s can not be disabled\n", | ||
698 | __func__, usb_ep ? imx_ep->ep.name : NULL); | ||
699 | return -EINVAL; | ||
700 | } | ||
701 | |||
702 | local_irq_save(flags); | ||
703 | |||
704 | imx_ep->stopped = 1; | ||
705 | nuke(imx_ep, -ESHUTDOWN); | ||
706 | imx_flush(imx_ep); | ||
707 | imx_ep_irq_disable(imx_ep); | ||
708 | |||
709 | local_irq_restore(flags); | ||
710 | |||
711 | D_EPX(imx_ep->imx_usb->dev, | ||
712 | "<%s> DISABLED %s\n", __func__, usb_ep->name); | ||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | static struct usb_request *imx_ep_alloc_request | ||
717 | (struct usb_ep *usb_ep, gfp_t gfp_flags) | ||
718 | { | ||
719 | struct imx_request *req; | ||
720 | |||
721 | req = kzalloc(sizeof *req, gfp_flags); | ||
722 | if (!req || !usb_ep) | ||
723 | return 0; | ||
724 | |||
725 | INIT_LIST_HEAD(&req->queue); | ||
726 | req->in_use = 0; | ||
727 | |||
728 | return &req->req; | ||
729 | } | ||
730 | |||
731 | static void imx_ep_free_request | ||
732 | (struct usb_ep *usb_ep, struct usb_request *usb_req) | ||
733 | { | ||
734 | struct imx_request *req; | ||
735 | |||
736 | req = container_of(usb_req, struct imx_request, req); | ||
737 | WARN_ON(!list_empty(&req->queue)); | ||
738 | kfree(req); | ||
739 | } | ||
740 | |||
741 | static int imx_ep_queue | ||
742 | (struct usb_ep *usb_ep, struct usb_request *usb_req, gfp_t gfp_flags) | ||
743 | { | ||
744 | struct imx_ep_struct *imx_ep; | ||
745 | struct imx_udc_struct *imx_usb; | ||
746 | struct imx_request *req; | ||
747 | unsigned long flags; | ||
748 | int ret = 0; | ||
749 | |||
750 | imx_ep = container_of(usb_ep, struct imx_ep_struct, ep); | ||
751 | imx_usb = imx_ep->imx_usb; | ||
752 | req = container_of(usb_req, struct imx_request, req); | ||
753 | |||
754 | /* | ||
755 | Special care on IMX udc. | ||
756 | Ignore enqueue when after set configuration from the | ||
757 | host. This assume all gadget drivers reply set | ||
758 | configuration with the next ep0 req enqueue. | ||
759 | */ | ||
760 | if (imx_usb->set_config && !EP_NO(imx_ep)) { | ||
761 | imx_usb->set_config = 0; | ||
762 | D_EPX(imx_usb->dev, | ||
763 | "<%s> gadget reply set config\n", __func__); | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | if (unlikely(!usb_req || !req || !usb_req->complete || !usb_req->buf)) { | ||
768 | D_ERR(imx_usb->dev, "<%s> bad params\n", __func__); | ||
769 | return -EINVAL; | ||
770 | } | ||
771 | |||
772 | if (unlikely(!usb_ep || !imx_ep)) { | ||
773 | D_ERR(imx_usb->dev, "<%s> bad ep\n", __func__); | ||
774 | return -EINVAL; | ||
775 | } | ||
776 | |||
777 | if (!imx_usb->driver || imx_usb->gadget.speed == USB_SPEED_UNKNOWN) { | ||
778 | D_ERR(imx_usb->dev, "<%s> bogus device state\n", __func__); | ||
779 | return -ESHUTDOWN; | ||
780 | } | ||
781 | |||
782 | local_irq_save(flags); | ||
783 | |||
784 | /* Debug */ | ||
785 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", | ||
786 | __func__, EP_NO(imx_ep), | ||
787 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | ||
788 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length); | ||
789 | dump_req(__func__, imx_ep, usb_req); | ||
790 | |||
791 | if (imx_ep->stopped) { | ||
792 | usb_req->status = -ESHUTDOWN; | ||
793 | ret = -ESHUTDOWN; | ||
794 | goto out; | ||
795 | } | ||
796 | |||
797 | if (req->in_use) { | ||
798 | D_ERR(imx_usb->dev, | ||
799 | "<%s> refusing to queue req %p (already queued)\n", | ||
800 | __func__, req); | ||
801 | goto out; | ||
802 | } | ||
803 | |||
804 | usb_req->status = -EINPROGRESS; | ||
805 | usb_req->actual = 0; | ||
806 | |||
807 | ep_add_request(imx_ep, req); | ||
808 | |||
809 | if (!EP_NO(imx_ep)) | ||
810 | ret = handle_ep0(imx_ep); | ||
811 | else | ||
812 | ret = handle_ep(imx_ep); | ||
813 | out: | ||
814 | local_irq_restore(flags); | ||
815 | return ret; | ||
816 | } | ||
817 | |||
818 | static int imx_ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) | ||
819 | { | ||
820 | |||
821 | struct imx_ep_struct *imx_ep = container_of | ||
822 | (usb_ep, struct imx_ep_struct, ep); | ||
823 | struct imx_request *req; | ||
824 | unsigned long flags; | ||
825 | |||
826 | if (unlikely(!usb_ep || !EP_NO(imx_ep))) { | ||
827 | D_ERR(imx_ep->imx_usb->dev, "<%s> bad ep\n", __func__); | ||
828 | return -EINVAL; | ||
829 | } | ||
830 | |||
831 | local_irq_save(flags); | ||
832 | |||
833 | /* make sure it's actually queued on this endpoint */ | ||
834 | list_for_each_entry(req, &imx_ep->queue, queue) { | ||
835 | if (&req->req == usb_req) | ||
836 | break; | ||
837 | } | ||
838 | if (&req->req != usb_req) { | ||
839 | local_irq_restore(flags); | ||
840 | return -EINVAL; | ||
841 | } | ||
842 | |||
843 | done(imx_ep, req, -ECONNRESET); | ||
844 | |||
845 | local_irq_restore(flags); | ||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | static int imx_ep_set_halt(struct usb_ep *usb_ep, int value) | ||
850 | { | ||
851 | struct imx_ep_struct *imx_ep = container_of | ||
852 | (usb_ep, struct imx_ep_struct, ep); | ||
853 | unsigned long flags; | ||
854 | |||
855 | if (unlikely(!usb_ep || !EP_NO(imx_ep))) { | ||
856 | D_ERR(imx_ep->imx_usb->dev, "<%s> bad ep\n", __func__); | ||
857 | return -EINVAL; | ||
858 | } | ||
859 | |||
860 | local_irq_save(flags); | ||
861 | |||
862 | if ((imx_ep->bEndpointAddress & USB_DIR_IN) | ||
863 | && !list_empty(&imx_ep->queue)) { | ||
864 | local_irq_restore(flags); | ||
865 | return -EAGAIN; | ||
866 | } | ||
867 | |||
868 | imx_ep_stall(imx_ep); | ||
869 | |||
870 | local_irq_restore(flags); | ||
871 | |||
872 | D_EPX(imx_ep->imx_usb->dev, "<%s> %s halt\n", __func__, usb_ep->name); | ||
873 | return 0; | ||
874 | } | ||
875 | |||
876 | static int imx_ep_fifo_status(struct usb_ep *usb_ep) | ||
877 | { | ||
878 | struct imx_ep_struct *imx_ep = container_of | ||
879 | (usb_ep, struct imx_ep_struct, ep); | ||
880 | |||
881 | if (!usb_ep) { | ||
882 | D_ERR(imx_ep->imx_usb->dev, "<%s> bad ep\n", __func__); | ||
883 | return -ENODEV; | ||
884 | } | ||
885 | |||
886 | if (imx_ep->imx_usb->gadget.speed == USB_SPEED_UNKNOWN) | ||
887 | return 0; | ||
888 | else | ||
889 | return imx_fifo_bcount(imx_ep); | ||
890 | } | ||
891 | |||
892 | static void imx_ep_fifo_flush(struct usb_ep *usb_ep) | ||
893 | { | ||
894 | struct imx_ep_struct *imx_ep = container_of | ||
895 | (usb_ep, struct imx_ep_struct, ep); | ||
896 | unsigned long flags; | ||
897 | |||
898 | local_irq_save(flags); | ||
899 | |||
900 | if (!usb_ep || !EP_NO(imx_ep) || !list_empty(&imx_ep->queue)) { | ||
901 | D_ERR(imx_ep->imx_usb->dev, "<%s> bad ep\n", __func__); | ||
902 | local_irq_restore(flags); | ||
903 | return; | ||
904 | } | ||
905 | |||
906 | /* toggle and halt bits stay unchanged */ | ||
907 | imx_flush(imx_ep); | ||
908 | |||
909 | local_irq_restore(flags); | ||
910 | } | ||
911 | |||
912 | static struct usb_ep_ops imx_ep_ops = { | ||
913 | .enable = imx_ep_enable, | ||
914 | .disable = imx_ep_disable, | ||
915 | |||
916 | .alloc_request = imx_ep_alloc_request, | ||
917 | .free_request = imx_ep_free_request, | ||
918 | |||
919 | .queue = imx_ep_queue, | ||
920 | .dequeue = imx_ep_dequeue, | ||
921 | |||
922 | .set_halt = imx_ep_set_halt, | ||
923 | .fifo_status = imx_ep_fifo_status, | ||
924 | .fifo_flush = imx_ep_fifo_flush, | ||
925 | }; | ||
926 | |||
927 | /******************************************************************************* | ||
928 | * USB endpoint control functions | ||
929 | ******************************************************************************* | ||
930 | */ | ||
931 | |||
932 | void ep0_chg_stat(const char *label, | ||
933 | struct imx_udc_struct *imx_usb, enum ep0_state stat) | ||
934 | { | ||
935 | D_EP0(imx_usb->dev, "<%s> from %15s to %15s\n", | ||
936 | label, state_name[imx_usb->ep0state], state_name[stat]); | ||
937 | |||
938 | if (imx_usb->ep0state == stat) | ||
939 | return; | ||
940 | |||
941 | imx_usb->ep0state = stat; | ||
942 | } | ||
943 | |||
944 | static void usb_init_data(struct imx_udc_struct *imx_usb) | ||
945 | { | ||
946 | struct imx_ep_struct *imx_ep; | ||
947 | u8 i; | ||
948 | |||
949 | /* device/ep0 records init */ | ||
950 | INIT_LIST_HEAD(&imx_usb->gadget.ep_list); | ||
951 | INIT_LIST_HEAD(&imx_usb->gadget.ep0->ep_list); | ||
952 | ep0_chg_stat(__func__, imx_usb, EP0_IDLE); | ||
953 | |||
954 | /* basic endpoint records init */ | ||
955 | for (i = 0; i < IMX_USB_NB_EP; i++) { | ||
956 | imx_ep = &imx_usb->imx_ep[i]; | ||
957 | |||
958 | if (i) { | ||
959 | list_add_tail(&imx_ep->ep.ep_list, | ||
960 | &imx_usb->gadget.ep_list); | ||
961 | imx_ep->stopped = 1; | ||
962 | } else | ||
963 | imx_ep->stopped = 0; | ||
964 | |||
965 | INIT_LIST_HEAD(&imx_ep->queue); | ||
966 | } | ||
967 | } | ||
968 | |||
969 | static void udc_stop_activity(struct imx_udc_struct *imx_usb, | ||
970 | struct usb_gadget_driver *driver) | ||
971 | { | ||
972 | struct imx_ep_struct *imx_ep; | ||
973 | int i; | ||
974 | |||
975 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN) | ||
976 | driver = NULL; | ||
977 | |||
978 | /* prevent new request submissions, kill any outstanding requests */ | ||
979 | for (i = 1; i < IMX_USB_NB_EP; i++) { | ||
980 | imx_ep = &imx_usb->imx_ep[i]; | ||
981 | imx_flush(imx_ep); | ||
982 | imx_ep->stopped = 1; | ||
983 | imx_ep_irq_disable(imx_ep); | ||
984 | nuke(imx_ep, -ESHUTDOWN); | ||
985 | } | ||
986 | |||
987 | imx_usb->cfg = 0; | ||
988 | imx_usb->intf = 0; | ||
989 | imx_usb->alt = 0; | ||
990 | |||
991 | if (driver) | ||
992 | driver->disconnect(&imx_usb->gadget); | ||
993 | } | ||
994 | |||
995 | /******************************************************************************* | ||
996 | * Interrupt handlers | ||
997 | ******************************************************************************* | ||
998 | */ | ||
999 | |||
1000 | static irqreturn_t imx_udc_irq(int irq, void *dev) | ||
1001 | { | ||
1002 | struct imx_udc_struct *imx_usb = dev; | ||
1003 | struct usb_ctrlrequest u; | ||
1004 | int temp, cfg, intf, alt; | ||
1005 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
1006 | |||
1007 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | ||
1008 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
1009 | dump_intr(__func__, intr, imx_usb->dev); | ||
1010 | dump_usb_stat(__func__, imx_usb); | ||
1011 | } | ||
1012 | |||
1013 | if (!imx_usb->driver) { | ||
1014 | /*imx_udc_disable(imx_usb);*/ | ||
1015 | goto end_irq; | ||
1016 | } | ||
1017 | |||
1018 | if (intr & INTR_WAKEUP) { | ||
1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | ||
1020 | && imx_usb->driver && imx_usb->driver->resume) | ||
1021 | imx_usb->driver->resume(&imx_usb->gadget); | ||
1022 | imx_usb->set_config = 0; | ||
1023 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1024 | } | ||
1025 | |||
1026 | if (intr & INTR_SUSPEND) { | ||
1027 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
1028 | && imx_usb->driver && imx_usb->driver->suspend) | ||
1029 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
1030 | imx_usb->set_config = 0; | ||
1031 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1032 | } | ||
1033 | |||
1034 | if (intr & INTR_RESET_START) { | ||
1035 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
1036 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
1037 | imx_usb->set_config = 0; | ||
1038 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1039 | } | ||
1040 | |||
1041 | if (intr & INTR_RESET_STOP) | ||
1042 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1043 | |||
1044 | if (intr & INTR_CFG_CHG) { | ||
1045 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
1046 | temp = __raw_readl(imx_usb->base + USB_STAT); | ||
1047 | cfg = (temp & STAT_CFG) >> 5; | ||
1048 | intf = (temp & STAT_INTF) >> 3; | ||
1049 | alt = temp & STAT_ALTSET; | ||
1050 | |||
1051 | D_REQ(imx_usb->dev, | ||
1052 | "<%s> orig config C=%d, I=%d, A=%d / " | ||
1053 | "req config C=%d, I=%d, A=%d\n", | ||
1054 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, | ||
1055 | cfg, intf, alt); | ||
1056 | |||
1057 | if (cfg != 1 && cfg != 2) | ||
1058 | goto end_irq; | ||
1059 | |||
1060 | imx_usb->set_config = 0; | ||
1061 | |||
1062 | /* Config setup */ | ||
1063 | if (imx_usb->cfg != cfg) { | ||
1064 | D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__); | ||
1065 | u.bRequest = USB_REQ_SET_CONFIGURATION; | ||
1066 | u.bRequestType = USB_DIR_OUT | | ||
1067 | USB_TYPE_STANDARD | | ||
1068 | USB_RECIP_DEVICE; | ||
1069 | u.wValue = cfg; | ||
1070 | u.wIndex = 0; | ||
1071 | u.wLength = 0; | ||
1072 | imx_usb->cfg = cfg; | ||
1073 | imx_usb->set_config = 1; | ||
1074 | imx_usb->driver->setup(&imx_usb->gadget, &u); | ||
1075 | imx_usb->set_config = 0; | ||
1076 | D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__); | ||
1077 | |||
1078 | } | ||
1079 | if (imx_usb->intf != intf || imx_usb->alt != alt) { | ||
1080 | D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__); | ||
1081 | u.bRequest = USB_REQ_SET_INTERFACE; | ||
1082 | u.bRequestType = USB_DIR_OUT | | ||
1083 | USB_TYPE_STANDARD | | ||
1084 | USB_RECIP_INTERFACE; | ||
1085 | u.wValue = alt; | ||
1086 | u.wIndex = intf; | ||
1087 | u.wLength = 0; | ||
1088 | imx_usb->intf = intf; | ||
1089 | imx_usb->alt = alt; | ||
1090 | imx_usb->set_config = 1; | ||
1091 | imx_usb->driver->setup(&imx_usb->gadget, &u); | ||
1092 | imx_usb->set_config = 0; | ||
1093 | D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__); | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | if (intr & INTR_SOF) { | ||
1098 | if (imx_usb->ep0state == EP0_IDLE) { | ||
1099 | temp = __raw_readl(imx_usb->base + USB_CTRL); | ||
1100 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); | ||
1101 | } | ||
1102 | } | ||
1103 | |||
1104 | end_irq: | ||
1105 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
1106 | return IRQ_HANDLED; | ||
1107 | } | ||
1108 | |||
1109 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | ||
1110 | { | ||
1111 | struct imx_udc_struct *imx_usb = dev; | ||
1112 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); | ||
1113 | |||
1114 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); | ||
1115 | |||
1116 | if (!imx_usb->driver) { | ||
1117 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); | ||
1118 | return IRQ_HANDLED; | ||
1119 | } | ||
1120 | |||
1121 | /* DEVREQ IRQ has highest priority */ | ||
1122 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) | ||
1123 | handle_ep0_devreq(imx_usb); | ||
1124 | /* Seem i.MX is missing EOF interrupt sometimes. | ||
1125 | * Therefore we monitor both EOF and FIFO_EMPTY interrups | ||
1126 | * when transmiting, and both EOF and FIFO_FULL when | ||
1127 | * receiving data. | ||
1128 | */ | ||
1129 | else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL)) | ||
1130 | handle_ep0(&imx_usb->imx_ep[0]); | ||
1131 | |||
1132 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); | ||
1133 | |||
1134 | return IRQ_HANDLED; | ||
1135 | } | ||
1136 | |||
1137 | static irqreturn_t imx_udc_bulk_irq(int irq, void *dev) | ||
1138 | { | ||
1139 | struct imx_udc_struct *imx_usb = dev; | ||
1140 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[irq - USBD_INT0]; | ||
1141 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | ||
1142 | |||
1143 | dump_ep_intr(__func__, irq - USBD_INT0, intr, imx_usb->dev); | ||
1144 | |||
1145 | if (!imx_usb->driver) { | ||
1146 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | ||
1147 | return IRQ_HANDLED; | ||
1148 | } | ||
1149 | |||
1150 | handle_ep(imx_ep); | ||
1151 | |||
1152 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | ||
1153 | |||
1154 | return IRQ_HANDLED; | ||
1155 | } | ||
1156 | |||
1157 | irq_handler_t intr_handler(int i) | ||
1158 | { | ||
1159 | switch (i) { | ||
1160 | case 0: | ||
1161 | return imx_udc_ctrl_irq; | ||
1162 | case 1: | ||
1163 | case 2: | ||
1164 | case 3: | ||
1165 | case 4: | ||
1166 | case 5: | ||
1167 | return imx_udc_bulk_irq; | ||
1168 | default: | ||
1169 | return imx_udc_irq; | ||
1170 | } | ||
1171 | } | ||
1172 | |||
1173 | /******************************************************************************* | ||
1174 | * Static defined IMX UDC structure | ||
1175 | ******************************************************************************* | ||
1176 | */ | ||
1177 | |||
1178 | static const struct usb_gadget_ops imx_udc_ops = { | ||
1179 | .get_frame = imx_udc_get_frame, | ||
1180 | .wakeup = imx_udc_wakeup, | ||
1181 | }; | ||
1182 | |||
1183 | static struct imx_udc_struct controller = { | ||
1184 | .gadget = { | ||
1185 | .ops = &imx_udc_ops, | ||
1186 | .ep0 = &controller.imx_ep[0].ep, | ||
1187 | .name = driver_name, | ||
1188 | .dev = { | ||
1189 | .bus_id = "gadget", | ||
1190 | }, | ||
1191 | }, | ||
1192 | |||
1193 | .imx_ep[0] = { | ||
1194 | .ep = { | ||
1195 | .name = ep0name, | ||
1196 | .ops = &imx_ep_ops, | ||
1197 | .maxpacket = 32, | ||
1198 | }, | ||
1199 | .imx_usb = &controller, | ||
1200 | .fifosize = 32, | ||
1201 | .bEndpointAddress = 0, | ||
1202 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
1203 | }, | ||
1204 | .imx_ep[1] = { | ||
1205 | .ep = { | ||
1206 | .name = "ep1in-bulk", | ||
1207 | .ops = &imx_ep_ops, | ||
1208 | .maxpacket = 64, | ||
1209 | }, | ||
1210 | .imx_usb = &controller, | ||
1211 | .fifosize = 64, | ||
1212 | .bEndpointAddress = USB_DIR_IN | 1, | ||
1213 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1214 | }, | ||
1215 | .imx_ep[2] = { | ||
1216 | .ep = { | ||
1217 | .name = "ep2out-bulk", | ||
1218 | .ops = &imx_ep_ops, | ||
1219 | .maxpacket = 64, | ||
1220 | }, | ||
1221 | .imx_usb = &controller, | ||
1222 | .fifosize = 64, | ||
1223 | .bEndpointAddress = USB_DIR_OUT | 2, | ||
1224 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1225 | }, | ||
1226 | .imx_ep[3] = { | ||
1227 | .ep = { | ||
1228 | .name = "ep3out-bulk", | ||
1229 | .ops = &imx_ep_ops, | ||
1230 | .maxpacket = 32, | ||
1231 | }, | ||
1232 | .imx_usb = &controller, | ||
1233 | .fifosize = 32, | ||
1234 | .bEndpointAddress = USB_DIR_OUT | 3, | ||
1235 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1236 | }, | ||
1237 | .imx_ep[4] = { | ||
1238 | .ep = { | ||
1239 | .name = "ep4in-int", | ||
1240 | .ops = &imx_ep_ops, | ||
1241 | .maxpacket = 32, | ||
1242 | }, | ||
1243 | .imx_usb = &controller, | ||
1244 | .fifosize = 32, | ||
1245 | .bEndpointAddress = USB_DIR_IN | 4, | ||
1246 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
1247 | }, | ||
1248 | .imx_ep[5] = { | ||
1249 | .ep = { | ||
1250 | .name = "ep5out-int", | ||
1251 | .ops = &imx_ep_ops, | ||
1252 | .maxpacket = 32, | ||
1253 | }, | ||
1254 | .imx_usb = &controller, | ||
1255 | .fifosize = 32, | ||
1256 | .bEndpointAddress = USB_DIR_OUT | 5, | ||
1257 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
1258 | }, | ||
1259 | }; | ||
1260 | |||
1261 | /******************************************************************************* | ||
1262 | * USB gadged driver functions | ||
1263 | ******************************************************************************* | ||
1264 | */ | ||
1265 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1266 | { | ||
1267 | struct imx_udc_struct *imx_usb = &controller; | ||
1268 | int retval; | ||
1269 | |||
1270 | if (!driver | ||
1271 | || driver->speed < USB_SPEED_FULL | ||
1272 | || !driver->bind | ||
1273 | || !driver->disconnect | ||
1274 | || !driver->setup) | ||
1275 | return -EINVAL; | ||
1276 | if (!imx_usb) | ||
1277 | return -ENODEV; | ||
1278 | if (imx_usb->driver) | ||
1279 | return -EBUSY; | ||
1280 | |||
1281 | /* first hook up the driver ... */ | ||
1282 | imx_usb->driver = driver; | ||
1283 | imx_usb->gadget.dev.driver = &driver->driver; | ||
1284 | |||
1285 | retval = device_add(&imx_usb->gadget.dev); | ||
1286 | if (retval) | ||
1287 | goto fail; | ||
1288 | retval = driver->bind(&imx_usb->gadget); | ||
1289 | if (retval) { | ||
1290 | D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n", | ||
1291 | __func__, driver->driver.name, retval); | ||
1292 | device_del(&imx_usb->gadget.dev); | ||
1293 | |||
1294 | goto fail; | ||
1295 | } | ||
1296 | |||
1297 | D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n", | ||
1298 | __func__, driver->driver.name); | ||
1299 | |||
1300 | imx_udc_enable(imx_usb); | ||
1301 | |||
1302 | return 0; | ||
1303 | fail: | ||
1304 | imx_usb->driver = NULL; | ||
1305 | imx_usb->gadget.dev.driver = NULL; | ||
1306 | return retval; | ||
1307 | } | ||
1308 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1309 | |||
1310 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1311 | { | ||
1312 | struct imx_udc_struct *imx_usb = &controller; | ||
1313 | |||
1314 | if (!imx_usb) | ||
1315 | return -ENODEV; | ||
1316 | if (!driver || driver != imx_usb->driver || !driver->unbind) | ||
1317 | return -EINVAL; | ||
1318 | |||
1319 | udc_stop_activity(imx_usb, driver); | ||
1320 | imx_udc_disable(imx_usb); | ||
1321 | |||
1322 | driver->unbind(&imx_usb->gadget); | ||
1323 | imx_usb->gadget.dev.driver = NULL; | ||
1324 | imx_usb->driver = NULL; | ||
1325 | |||
1326 | device_del(&imx_usb->gadget.dev); | ||
1327 | |||
1328 | D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n", | ||
1329 | __func__, driver->driver.name); | ||
1330 | |||
1331 | return 0; | ||
1332 | } | ||
1333 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1334 | |||
1335 | /******************************************************************************* | ||
1336 | * Module functions | ||
1337 | ******************************************************************************* | ||
1338 | */ | ||
1339 | |||
1340 | static int __init imx_udc_probe(struct platform_device *pdev) | ||
1341 | { | ||
1342 | struct imx_udc_struct *imx_usb = &controller; | ||
1343 | struct resource *res; | ||
1344 | struct imxusb_platform_data *pdata; | ||
1345 | struct clk *clk; | ||
1346 | void __iomem *base; | ||
1347 | int ret = 0; | ||
1348 | int i, res_size; | ||
1349 | |||
1350 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1351 | if (!res) { | ||
1352 | dev_err(&pdev->dev, "can't get device resources\n"); | ||
1353 | return -ENODEV; | ||
1354 | } | ||
1355 | |||
1356 | pdata = pdev->dev.platform_data; | ||
1357 | if (!pdata) { | ||
1358 | dev_err(&pdev->dev, "driver needs platform data\n"); | ||
1359 | return -ENODEV; | ||
1360 | } | ||
1361 | |||
1362 | res_size = res->end - res->start + 1; | ||
1363 | if (!request_mem_region(res->start, res_size, res->name)) { | ||
1364 | dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", | ||
1365 | res_size, res->start); | ||
1366 | return -ENOMEM; | ||
1367 | } | ||
1368 | |||
1369 | if (pdata->init) { | ||
1370 | ret = pdata->init(&pdev->dev); | ||
1371 | if (ret) | ||
1372 | goto fail0; | ||
1373 | } | ||
1374 | |||
1375 | base = ioremap(res->start, res_size); | ||
1376 | if (!base) { | ||
1377 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
1378 | ret = -EIO; | ||
1379 | goto fail1; | ||
1380 | } | ||
1381 | |||
1382 | clk = clk_get(NULL, "usbd_clk"); | ||
1383 | if (IS_ERR(clk)) { | ||
1384 | ret = PTR_ERR(clk); | ||
1385 | dev_err(&pdev->dev, "can't get USB clock\n"); | ||
1386 | goto fail2; | ||
1387 | } | ||
1388 | clk_enable(clk); | ||
1389 | |||
1390 | if (clk_get_rate(clk) != 48000000) { | ||
1391 | D_INI(&pdev->dev, | ||
1392 | "Bad USB clock (%d Hz), changing to 48000000 Hz\n", | ||
1393 | (int)clk_get_rate(clk)); | ||
1394 | if (clk_set_rate(clk, 48000000)) { | ||
1395 | dev_err(&pdev->dev, | ||
1396 | "Unable to set correct USB clock (48MHz)\n"); | ||
1397 | ret = -EIO; | ||
1398 | goto fail3; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) { | ||
1403 | imx_usb->usbd_int[i] = platform_get_irq(pdev, i); | ||
1404 | if (imx_usb->usbd_int[i] < 0) { | ||
1405 | dev_err(&pdev->dev, "can't get irq number\n"); | ||
1406 | ret = -ENODEV; | ||
1407 | goto fail3; | ||
1408 | } | ||
1409 | } | ||
1410 | |||
1411 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) { | ||
1412 | ret = request_irq(imx_usb->usbd_int[i], intr_handler(i), | ||
1413 | IRQF_DISABLED, driver_name, imx_usb); | ||
1414 | if (ret) { | ||
1415 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | ||
1416 | imx_usb->usbd_int[i], ret); | ||
1417 | for (--i; i >= 0; i--) | ||
1418 | free_irq(imx_usb->usbd_int[i], imx_usb); | ||
1419 | goto fail3; | ||
1420 | } | ||
1421 | } | ||
1422 | |||
1423 | imx_usb->res = res; | ||
1424 | imx_usb->base = base; | ||
1425 | imx_usb->clk = clk; | ||
1426 | imx_usb->dev = &pdev->dev; | ||
1427 | |||
1428 | device_initialize(&imx_usb->gadget.dev); | ||
1429 | |||
1430 | imx_usb->gadget.dev.parent = &pdev->dev; | ||
1431 | imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
1432 | |||
1433 | platform_set_drvdata(pdev, imx_usb); | ||
1434 | |||
1435 | usb_init_data(imx_usb); | ||
1436 | imx_udc_init(imx_usb); | ||
1437 | |||
1438 | return 0; | ||
1439 | |||
1440 | fail3: | ||
1441 | clk_put(clk); | ||
1442 | clk_disable(clk); | ||
1443 | fail2: | ||
1444 | iounmap(base); | ||
1445 | fail1: | ||
1446 | if (pdata->exit) | ||
1447 | pdata->exit(&pdev->dev); | ||
1448 | fail0: | ||
1449 | release_mem_region(res->start, res_size); | ||
1450 | return ret; | ||
1451 | } | ||
1452 | |||
1453 | static int __exit imx_udc_remove(struct platform_device *pdev) | ||
1454 | { | ||
1455 | struct imx_udc_struct *imx_usb = platform_get_drvdata(pdev); | ||
1456 | struct imxusb_platform_data *pdata = pdev->dev.platform_data; | ||
1457 | int i; | ||
1458 | |||
1459 | imx_udc_disable(imx_usb); | ||
1460 | |||
1461 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) | ||
1462 | free_irq(imx_usb->usbd_int[i], imx_usb); | ||
1463 | |||
1464 | clk_put(imx_usb->clk); | ||
1465 | clk_disable(imx_usb->clk); | ||
1466 | iounmap(imx_usb->base); | ||
1467 | |||
1468 | release_mem_region(imx_usb->res->start, | ||
1469 | imx_usb->res->end - imx_usb->res->start + 1); | ||
1470 | |||
1471 | if (pdata->exit) | ||
1472 | pdata->exit(&pdev->dev); | ||
1473 | |||
1474 | platform_set_drvdata(pdev, NULL); | ||
1475 | |||
1476 | return 0; | ||
1477 | } | ||
1478 | |||
1479 | /*----------------------------------------------------------------------------*/ | ||
1480 | |||
1481 | #ifdef CONFIG_PM | ||
1482 | #define imx_udc_suspend NULL | ||
1483 | #define imx_udc_resume NULL | ||
1484 | #else | ||
1485 | #define imx_udc_suspend NULL | ||
1486 | #define imx_udc_resume NULL | ||
1487 | #endif | ||
1488 | |||
1489 | /*----------------------------------------------------------------------------*/ | ||
1490 | |||
1491 | static struct platform_driver udc_driver = { | ||
1492 | .driver = { | ||
1493 | .name = driver_name, | ||
1494 | .owner = THIS_MODULE, | ||
1495 | }, | ||
1496 | .remove = __exit_p(imx_udc_remove), | ||
1497 | .suspend = imx_udc_suspend, | ||
1498 | .resume = imx_udc_resume, | ||
1499 | }; | ||
1500 | |||
1501 | static int __init udc_init(void) | ||
1502 | { | ||
1503 | return platform_driver_probe(&udc_driver, imx_udc_probe); | ||
1504 | } | ||
1505 | module_init(udc_init); | ||
1506 | |||
1507 | static void __exit udc_exit(void) | ||
1508 | { | ||
1509 | platform_driver_unregister(&udc_driver); | ||
1510 | } | ||
1511 | module_exit(udc_exit); | ||
1512 | |||
1513 | MODULE_DESCRIPTION("IMX USB Device Controller driver"); | ||
1514 | MODULE_AUTHOR("Darius Augulis <augulis.darius@gmail.com>"); | ||
1515 | MODULE_LICENSE("GPL"); | ||
1516 | MODULE_ALIAS("platform:imx_udc"); | ||
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h new file mode 100644 index 000000000000..850076937d8d --- /dev/null +++ b/drivers/usb/gadget/imx_udc.h | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Mike Lee(eemike@gmail.com) | ||
3 | * | ||
4 | * This udc driver is now under testing and code is based on pxa2xx_udc.h | ||
5 | * Please use it with your own risk! | ||
6 | * | ||
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 | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #ifndef __LINUX_USB_GADGET_IMX_H | ||
19 | #define __LINUX_USB_GADGET_IMX_H | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | |||
23 | /* Helper macros */ | ||
24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ | ||
25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) | ||
26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | ||
27 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) | ||
28 | #define IMX_USB_NB_EP 6 | ||
29 | |||
30 | /* Driver structures */ | ||
31 | struct imx_request { | ||
32 | struct usb_request req; | ||
33 | struct list_head queue; | ||
34 | unsigned int in_use; | ||
35 | }; | ||
36 | |||
37 | enum ep0_state { | ||
38 | EP0_IDLE, | ||
39 | EP0_IN_DATA_PHASE, | ||
40 | EP0_OUT_DATA_PHASE, | ||
41 | EP0_CONFIG, | ||
42 | EP0_STALL, | ||
43 | }; | ||
44 | |||
45 | struct imx_ep_struct { | ||
46 | struct usb_ep ep; | ||
47 | struct imx_udc_struct *imx_usb; | ||
48 | struct list_head queue; | ||
49 | unsigned char stopped; | ||
50 | unsigned char fifosize; | ||
51 | unsigned char bEndpointAddress; | ||
52 | unsigned char bmAttributes; | ||
53 | }; | ||
54 | |||
55 | struct imx_udc_struct { | ||
56 | struct usb_gadget gadget; | ||
57 | struct usb_gadget_driver *driver; | ||
58 | struct device *dev; | ||
59 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; | ||
60 | struct clk *clk; | ||
61 | enum ep0_state ep0state; | ||
62 | struct resource *res; | ||
63 | void __iomem *base; | ||
64 | unsigned char set_config; | ||
65 | int cfg, | ||
66 | intf, | ||
67 | alt, | ||
68 | usbd_int[7]; | ||
69 | }; | ||
70 | |||
71 | /* USB registers */ | ||
72 | #define USB_FRAME (0x00) /* USB frame */ | ||
73 | #define USB_SPEC (0x04) /* USB Spec */ | ||
74 | #define USB_STAT (0x08) /* USB Status */ | ||
75 | #define USB_CTRL (0x0C) /* USB Control */ | ||
76 | #define USB_DADR (0x10) /* USB Desc RAM addr */ | ||
77 | #define USB_DDAT (0x14) /* USB Desc RAM/EP buffer data */ | ||
78 | #define USB_INTR (0x18) /* USB interrupt */ | ||
79 | #define USB_MASK (0x1C) /* USB Mask */ | ||
80 | #define USB_ENAB (0x24) /* USB Enable */ | ||
81 | #define USB_EP_STAT(x) (0x30 + (x*0x30)) /* USB status/control */ | ||
82 | #define USB_EP_INTR(x) (0x34 + (x*0x30)) /* USB interrupt */ | ||
83 | #define USB_EP_MASK(x) (0x38 + (x*0x30)) /* USB mask */ | ||
84 | #define USB_EP_FDAT(x) (0x3C + (x*0x30)) /* USB FIFO data */ | ||
85 | #define USB_EP_FDAT0(x) (0x3C + (x*0x30)) /* USB FIFO data */ | ||
86 | #define USB_EP_FDAT1(x) (0x3D + (x*0x30)) /* USB FIFO data */ | ||
87 | #define USB_EP_FDAT2(x) (0x3E + (x*0x30)) /* USB FIFO data */ | ||
88 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ | ||
89 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ | ||
90 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ | ||
91 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */ | ||
92 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */ | ||
93 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ | ||
94 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ | ||
95 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ | ||
96 | /* USB Control Register Bit Fields.*/ | ||
97 | #define CTRL_CMDOVER (1<<6) /* UDC status */ | ||
98 | #define CTRL_CMDERROR (1<<5) /* UDC status */ | ||
99 | #define CTRL_FE_ENA (1<<3) /* Enable Font End logic */ | ||
100 | #define CTRL_UDC_RST (1<<2) /* UDC reset */ | ||
101 | #define CTRL_AFE_ENA (1<<1) /* Analog Font end enable */ | ||
102 | #define CTRL_RESUME (1<<0) /* UDC resume */ | ||
103 | /* USB Status Register Bit Fields.*/ | ||
104 | #define STAT_RST (1<<8) | ||
105 | #define STAT_SUSP (1<<7) | ||
106 | #define STAT_CFG (3<<5) | ||
107 | #define STAT_INTF (3<<3) | ||
108 | #define STAT_ALTSET (7<<0) | ||
109 | /* USB Interrupt Status/Mask Registers Bit fields */ | ||
110 | #define INTR_WAKEUP (1<<31) /* Wake up Interrupt */ | ||
111 | #define INTR_MSOF (1<<7) /* Missed Start of Frame */ | ||
112 | #define INTR_SOF (1<<6) /* Start of Frame */ | ||
113 | #define INTR_RESET_STOP (1<<5) /* Reset Signaling stop */ | ||
114 | #define INTR_RESET_START (1<<4) /* Reset Signaling start */ | ||
115 | #define INTR_RESUME (1<<3) /* Suspend to resume */ | ||
116 | #define INTR_SUSPEND (1<<2) /* Active to suspend */ | ||
117 | #define INTR_FRAME_MATCH (1<<1) /* Frame matched */ | ||
118 | #define INTR_CFG_CHG (1<<0) /* Configuration change occurred */ | ||
119 | /* USB Enable Register Bit Fields.*/ | ||
120 | #define ENAB_RST (1<<31) /* Reset USB modules */ | ||
121 | #define ENAB_ENAB (1<<30) /* Enable USB modules*/ | ||
122 | #define ENAB_SUSPEND (1<<29) /* Suspend USB modules */ | ||
123 | #define ENAB_ENDIAN (1<<28) /* Endian of USB modules */ | ||
124 | #define ENAB_PWRMD (1<<0) /* Power mode of USB modules */ | ||
125 | /* USB Descriptor Ram Address Register bit fields */ | ||
126 | #define DADR_CFG (1<<31) /* Configuration */ | ||
127 | #define DADR_BSY (1<<30) /* Busy status */ | ||
128 | #define DADR_DADR (0x1FF) /* Descriptor Ram Address */ | ||
129 | /* USB Descriptor RAM/Endpoint Buffer Data Register bit fields */ | ||
130 | #define DDAT_DDAT (0xFF) /* Descriptor Endpoint Buffer */ | ||
131 | /* USB Endpoint Status Register bit fields */ | ||
132 | #define EPSTAT_BCOUNT (0x7F<<16) /* Endpoint FIFO byte count */ | ||
133 | #define EPSTAT_SIP (1<<8) /* Endpoint setup in progress */ | ||
134 | #define EPSTAT_DIR (1<<7) /* Endpoint transfer direction */ | ||
135 | #define EPSTAT_MAX (3<<5) /* Endpoint Max packet size */ | ||
136 | #define EPSTAT_TYP (3<<3) /* Endpoint type */ | ||
137 | #define EPSTAT_ZLPS (1<<2) /* Send zero length packet */ | ||
138 | #define EPSTAT_FLUSH (1<<1) /* Endpoint FIFO Flush */ | ||
139 | #define EPSTAT_STALL (1<<0) /* Force stall */ | ||
140 | /* USB Endpoint FIFO Status Register bit fields */ | ||
141 | #define FSTAT_FRAME_STAT (0xF<<24) /* Frame status bit [0-3] */ | ||
142 | #define FSTAT_ERR (1<<22) /* FIFO error */ | ||
143 | #define FSTAT_UF (1<<21) /* FIFO underflow */ | ||
144 | #define FSTAT_OF (1<<20) /* FIFO overflow */ | ||
145 | #define FSTAT_FR (1<<19) /* FIFO frame ready */ | ||
146 | #define FSTAT_FULL (1<<18) /* FIFO full */ | ||
147 | #define FSTAT_ALRM (1<<17) /* FIFO alarm */ | ||
148 | #define FSTAT_EMPTY (1<<16) /* FIFO empty */ | ||
149 | /* USB Endpoint FIFO Control Register bit fields */ | ||
150 | #define FCTRL_WFR (1<<29) /* Write frame end */ | ||
151 | /* USB Endpoint Interrupt Status Regsiter bit fields */ | ||
152 | #define EPINTR_FIFO_FULL (1<<8) /* fifo full */ | ||
153 | #define EPINTR_FIFO_EMPTY (1<<7) /* fifo empty */ | ||
154 | #define EPINTR_FIFO_ERROR (1<<6) /* fifo error */ | ||
155 | #define EPINTR_FIFO_HIGH (1<<5) /* fifo high */ | ||
156 | #define EPINTR_FIFO_LOW (1<<4) /* fifo low */ | ||
157 | #define EPINTR_MDEVREQ (1<<3) /* multi Device request */ | ||
158 | #define EPINTR_EOT (1<<2) /* fifo end of transfer */ | ||
159 | #define EPINTR_DEVREQ (1<<1) /* Device request */ | ||
160 | #define EPINTR_EOF (1<<0) /* fifo end of frame */ | ||
161 | |||
162 | /* Debug macros */ | ||
163 | #ifdef DEBUG | ||
164 | |||
165 | /* #define DEBUG_REQ */ | ||
166 | /* #define DEBUG_TRX */ | ||
167 | /* #define DEBUG_INIT */ | ||
168 | /* #define DEBUG_EP0 */ | ||
169 | /* #define DEBUG_EPX */ | ||
170 | /* #define DEBUG_IRQ */ | ||
171 | /* #define DEBUG_EPIRQ */ | ||
172 | /* #define DEBUG_DUMP */ | ||
173 | #define DEBUG_ERR | ||
174 | |||
175 | #ifdef DEBUG_REQ | ||
176 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) | ||
177 | #else | ||
178 | #define D_REQ(dev, args...) do {} while (0) | ||
179 | #endif /* DEBUG_REQ */ | ||
180 | |||
181 | #ifdef DEBUG_TRX | ||
182 | #define D_TRX(dev, args...) dev_dbg(dev, ## args) | ||
183 | #else | ||
184 | #define D_TRX(dev, args...) do {} while (0) | ||
185 | #endif /* DEBUG_TRX */ | ||
186 | |||
187 | #ifdef DEBUG_INIT | ||
188 | #define D_INI(dev, args...) dev_dbg(dev, ## args) | ||
189 | #else | ||
190 | #define D_INI(dev, args...) do {} while (0) | ||
191 | #endif /* DEBUG_INIT */ | ||
192 | |||
193 | #ifdef DEBUG_EP0 | ||
194 | static const char *state_name[] = { | ||
195 | "EP0_IDLE", | ||
196 | "EP0_IN_DATA_PHASE", | ||
197 | "EP0_OUT_DATA_PHASE", | ||
198 | "EP0_CONFIG", | ||
199 | "EP0_STALL" | ||
200 | }; | ||
201 | #define D_EP0(dev, args...) dev_dbg(dev, ## args) | ||
202 | #else | ||
203 | #define D_EP0(dev, args...) do {} while (0) | ||
204 | #endif /* DEBUG_EP0 */ | ||
205 | |||
206 | #ifdef DEBUG_EPX | ||
207 | #define D_EPX(dev, args...) dev_dbg(dev, ## args) | ||
208 | #else | ||
209 | #define D_EPX(dev, args...) do {} while (0) | ||
210 | #endif /* DEBUG_EP0 */ | ||
211 | |||
212 | #ifdef DEBUG_IRQ | ||
213 | static void dump_intr(const char *label, int irqreg, struct device *dev) | ||
214 | { | ||
215 | dev_dbg(dev, "<%s> USB_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, | ||
216 | (irqreg & INTR_WAKEUP) ? " wake" : "", | ||
217 | (irqreg & INTR_MSOF) ? " msof" : "", | ||
218 | (irqreg & INTR_SOF) ? " sof" : "", | ||
219 | (irqreg & INTR_RESUME) ? " resume" : "", | ||
220 | (irqreg & INTR_SUSPEND) ? " suspend" : "", | ||
221 | (irqreg & INTR_RESET_STOP) ? " noreset" : "", | ||
222 | (irqreg & INTR_RESET_START) ? " reset" : "", | ||
223 | (irqreg & INTR_FRAME_MATCH) ? " fmatch" : "", | ||
224 | (irqreg & INTR_CFG_CHG) ? " config" : ""); | ||
225 | } | ||
226 | #else | ||
227 | #define dump_intr(x, y, z) do {} while (0) | ||
228 | #endif /* DEBUG_IRQ */ | ||
229 | |||
230 | #ifdef DEBUG_EPIRQ | ||
231 | static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev) | ||
232 | { | ||
233 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, | ||
234 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", | ||
235 | (irqreg & EPINTR_FIFO_EMPTY) ? " fempty" : "", | ||
236 | (irqreg & EPINTR_FIFO_ERROR) ? " ferr" : "", | ||
237 | (irqreg & EPINTR_FIFO_HIGH) ? " fhigh" : "", | ||
238 | (irqreg & EPINTR_FIFO_LOW) ? " flow" : "", | ||
239 | (irqreg & EPINTR_MDEVREQ) ? " mreq" : "", | ||
240 | (irqreg & EPINTR_EOF) ? " eof" : "", | ||
241 | (irqreg & EPINTR_DEVREQ) ? " devreq" : "", | ||
242 | (irqreg & EPINTR_EOT) ? " eot" : ""); | ||
243 | } | ||
244 | #else | ||
245 | #define dump_ep_intr(x, y, z, i) do {} while (0) | ||
246 | #endif /* DEBUG_IRQ */ | ||
247 | |||
248 | #ifdef DEBUG_DUMP | ||
249 | static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb) | ||
250 | { | ||
251 | int temp = __raw_readl(imx_usb->base + USB_STAT); | ||
252 | |||
253 | dev_dbg(imx_usb->dev, | ||
254 | "<%s> USB_STAT=[%s%s CFG=%d, INTF=%d, ALTR=%d]\n", label, | ||
255 | (temp & STAT_RST) ? " reset" : "", | ||
256 | (temp & STAT_SUSP) ? " suspend" : "", | ||
257 | (temp & STAT_CFG) >> 5, | ||
258 | (temp & STAT_INTF) >> 3, | ||
259 | (temp & STAT_ALTSET)); | ||
260 | } | ||
261 | |||
262 | static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep) | ||
263 | { | ||
264 | int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | ||
265 | |||
266 | dev_dbg(imx_ep->imx_usb->dev, | ||
267 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | ||
268 | (temp & EPINTR_FIFO_FULL) ? " full" : "", | ||
269 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", | ||
270 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", | ||
271 | (temp & EPINTR_FIFO_HIGH) ? " fhigh" : "", | ||
272 | (temp & EPINTR_FIFO_LOW) ? " flow" : "", | ||
273 | (temp & EPINTR_MDEVREQ) ? " mreq" : "", | ||
274 | (temp & EPINTR_EOF) ? " eof" : "", | ||
275 | (temp & EPINTR_DEVREQ) ? " devreq" : "", | ||
276 | (temp & EPINTR_EOT) ? " eot" : ""); | ||
277 | |||
278 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | ||
279 | |||
280 | dev_dbg(imx_ep->imx_usb->dev, | ||
281 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep), | ||
282 | (temp & EPSTAT_SIP) ? " sip" : "", | ||
283 | (temp & EPSTAT_STALL) ? " stall" : "", | ||
284 | (temp & EPSTAT_BCOUNT) >> 16); | ||
285 | |||
286 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep))); | ||
287 | |||
288 | dev_dbg(imx_ep->imx_usb->dev, | ||
289 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | ||
290 | (temp & FSTAT_ERR) ? " ferr" : "", | ||
291 | (temp & FSTAT_UF) ? " funder" : "", | ||
292 | (temp & FSTAT_OF) ? " fover" : "", | ||
293 | (temp & FSTAT_FR) ? " fready" : "", | ||
294 | (temp & FSTAT_FULL) ? " ffull" : "", | ||
295 | (temp & FSTAT_ALRM) ? " falarm" : "", | ||
296 | (temp & FSTAT_EMPTY) ? " fempty" : ""); | ||
297 | } | ||
298 | |||
299 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req) | ||
300 | { | ||
301 | int i; | ||
302 | |||
303 | if (!req || !req->buf) { | ||
304 | dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label); | ||
305 | return; | ||
306 | } | ||
307 | |||
308 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | ||
309 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { | ||
310 | |||
311 | dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label); | ||
312 | for (i = 0; i < req->length; i++) | ||
313 | printk("%02x-", *((u8 *)req->buf + i)); | ||
314 | printk(">\n"); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | #else | ||
319 | #define dump_ep_stat(x, y) do {} while (0) | ||
320 | #define dump_usb_stat(x, y) do {} while (0) | ||
321 | #define dump_req(x, y, z) do {} while (0) | ||
322 | #endif /* DEBUG_DUMP */ | ||
323 | |||
324 | #ifdef DEBUG_ERR | ||
325 | #define D_ERR(dev, args...) dev_dbg(dev, ## args) | ||
326 | #else | ||
327 | #define D_ERR(dev, args...) do {} while (0) | ||
328 | #endif | ||
329 | |||
330 | #else | ||
331 | #define D_REQ(dev, args...) do {} while (0) | ||
332 | #define D_TRX(dev, args...) do {} while (0) | ||
333 | #define D_INI(dev, args...) do {} while (0) | ||
334 | #define D_EP0(dev, args...) do {} while (0) | ||
335 | #define D_EPX(dev, args...) do {} while (0) | ||
336 | #define dump_ep_intr(x, y, z, i) do {} while (0) | ||
337 | #define dump_intr(x, y, z) do {} while (0) | ||
338 | #define dump_ep_stat(x, y) do {} while (0) | ||
339 | #define dump_usb_stat(x, y) do {} while (0) | ||
340 | #define dump_req(x, y, z) do {} while (0) | ||
341 | #define D_ERR(dev, args...) do {} while (0) | ||
342 | #endif /* DEBUG */ | ||
343 | |||
344 | #endif /* __LINUX_USB_GADGET_IMX_H */ | ||
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index c6e7df04c69a..d554b0895603 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -1981,7 +1981,7 @@ static struct lh7a40x_udc memory = { | |||
1981 | .ep0 = &memory.ep[0].ep, | 1981 | .ep0 = &memory.ep[0].ep, |
1982 | .name = driver_name, | 1982 | .name = driver_name, |
1983 | .dev = { | 1983 | .dev = { |
1984 | .bus_id = "gadget", | 1984 | .init_name = "gadget", |
1985 | .release = nop_release, | 1985 | .release = nop_release, |
1986 | }, | 1986 | }, |
1987 | }, | 1987 | }, |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 3a8879ec2061..43dcf9e1af6b 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1546,8 +1546,6 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) | |||
1546 | { | 1546 | { |
1547 | } | 1547 | } |
1548 | 1548 | ||
1549 | #define resource_len(r) (((r)->end - (r)->start) + 1) | ||
1550 | |||
1551 | static int __init m66592_probe(struct platform_device *pdev) | 1549 | static int __init m66592_probe(struct platform_device *pdev) |
1552 | { | 1550 | { |
1553 | struct resource *res; | 1551 | struct resource *res; |
@@ -1560,11 +1558,10 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1560 | int ret = 0; | 1558 | int ret = 0; |
1561 | int i; | 1559 | int i; |
1562 | 1560 | ||
1563 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 1561 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1564 | (char *)udc_name); | ||
1565 | if (!res) { | 1562 | if (!res) { |
1566 | ret = -ENODEV; | 1563 | ret = -ENODEV; |
1567 | pr_err("platform_get_resource_byname error.\n"); | 1564 | pr_err("platform_get_resource error.\n"); |
1568 | goto clean_up; | 1565 | goto clean_up; |
1569 | } | 1566 | } |
1570 | 1567 | ||
@@ -1575,7 +1572,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1575 | goto clean_up; | 1572 | goto clean_up; |
1576 | } | 1573 | } |
1577 | 1574 | ||
1578 | reg = ioremap(res->start, resource_len(res)); | 1575 | reg = ioremap(res->start, resource_size(res)); |
1579 | if (reg == NULL) { | 1576 | if (reg == NULL) { |
1580 | ret = -ENOMEM; | 1577 | ret = -ENOMEM; |
1581 | pr_err("ioremap error.\n"); | 1578 | pr_err("ioremap error.\n"); |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 8ae70de2c37d..12c6d83b218c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -669,7 +669,7 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) | |||
669 | 669 | ||
670 | /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ | 670 | /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ |
671 | wmb (); | 671 | wmb (); |
672 | td->dmacount = cpu_to_le32p (&dmacount); | 672 | td->dmacount = cpu_to_le32(dmacount); |
673 | } | 673 | } |
674 | 674 | ||
675 | static const u32 dmactl_default = | 675 | static const u32 dmactl_default = |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 34e9e393f929..57d9641c6bf8 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -3006,7 +3006,7 @@ cleanup1: | |||
3006 | 3006 | ||
3007 | cleanup0: | 3007 | cleanup0: |
3008 | if (xceiv) | 3008 | if (xceiv) |
3009 | put_device(xceiv->dev); | 3009 | otg_put_transceiver(xceiv); |
3010 | 3010 | ||
3011 | if (cpu_is_omap16xx() || cpu_is_omap24xx()) { | 3011 | if (cpu_is_omap16xx() || cpu_is_omap24xx()) { |
3012 | clk_disable(hhc_clk); | 3012 | clk_disable(hhc_clk); |
@@ -3034,7 +3034,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev) | |||
3034 | 3034 | ||
3035 | pullup_disable(udc); | 3035 | pullup_disable(udc); |
3036 | if (udc->transceiver) { | 3036 | if (udc->transceiver) { |
3037 | put_device(udc->transceiver->dev); | 3037 | otg_put_transceiver(udc->transceiver); |
3038 | udc->transceiver = NULL; | 3038 | udc->transceiver = NULL; |
3039 | } | 3039 | } |
3040 | omap_writew(0, UDC_SYSCON1); | 3040 | omap_writew(0, UDC_SYSCON1); |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 8c5026be79d4..9b36205c5759 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -1833,7 +1833,7 @@ static struct pxa25x_udc memory = { | |||
1833 | .ep0 = &memory.ep[0].ep, | 1833 | .ep0 = &memory.ep[0].ep, |
1834 | .name = driver_name, | 1834 | .name = driver_name, |
1835 | .dev = { | 1835 | .dev = { |
1836 | .bus_id = "gadget", | 1836 | .init_name = "gadget", |
1837 | .release = nop_release, | 1837 | .release = nop_release, |
1838 | }, | 1838 | }, |
1839 | }, | 1839 | }, |
@@ -2198,7 +2198,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2198 | udc_disable(dev); | 2198 | udc_disable(dev); |
2199 | udc_reinit(dev); | 2199 | udc_reinit(dev); |
2200 | 2200 | ||
2201 | dev->vbus = is_vbus_present(); | 2201 | dev->vbus = !!is_vbus_present(); |
2202 | 2202 | ||
2203 | /* irq setup after old hardware state is cleaned up */ | 2203 | /* irq setup after old hardware state is cleaned up */ |
2204 | retval = request_irq(irq, pxa25x_udc_irq, | 2204 | retval = request_irq(irq, pxa25x_udc_irq, |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 944e4ff641df..990f40f988d4 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -430,7 +430,6 @@ static void pio_irq_enable(struct pxa_ep *ep) | |||
430 | /** | 430 | /** |
431 | * pio_irq_disable - Disables irq generation for one endpoint | 431 | * pio_irq_disable - Disables irq generation for one endpoint |
432 | * @ep: udc endpoint | 432 | * @ep: udc endpoint |
433 | * @index: endpoint number | ||
434 | */ | 433 | */ |
435 | static void pio_irq_disable(struct pxa_ep *ep) | 434 | static void pio_irq_disable(struct pxa_ep *ep) |
436 | { | 435 | { |
@@ -586,7 +585,6 @@ static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in) | |||
586 | * inc_ep_stats_bytes - Update ep stats counts | 585 | * inc_ep_stats_bytes - Update ep stats counts |
587 | * @ep: physical endpoint | 586 | * @ep: physical endpoint |
588 | * @count: bytes transfered on endpoint | 587 | * @count: bytes transfered on endpoint |
589 | * @req: usb request | ||
590 | * @is_in: ep direction (USB_DIR_IN or 0) | 588 | * @is_in: ep direction (USB_DIR_IN or 0) |
591 | */ | 589 | */ |
592 | static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in) | 590 | static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in) |
@@ -2162,7 +2160,7 @@ static struct pxa_udc memory = { | |||
2162 | .ep0 = &memory.udc_usb_ep[0].usb_ep, | 2160 | .ep0 = &memory.udc_usb_ep[0].usb_ep, |
2163 | .name = driver_name, | 2161 | .name = driver_name, |
2164 | .dev = { | 2162 | .dev = { |
2165 | .bus_id = "gadget", | 2163 | .init_name = "gadget", |
2166 | }, | 2164 | }, |
2167 | }, | 2165 | }, |
2168 | 2166 | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 8d8d65165983..9a2b8920532d 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/gpio.h> | ||
39 | 40 | ||
40 | #include <linux/debugfs.h> | 41 | #include <linux/debugfs.h> |
41 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
@@ -51,7 +52,6 @@ | |||
51 | #include <mach/irqs.h> | 52 | #include <mach/irqs.h> |
52 | 53 | ||
53 | #include <mach/hardware.h> | 54 | #include <mach/hardware.h> |
54 | #include <mach/regs-gpio.h> | ||
55 | 55 | ||
56 | #include <plat/regs-udc.h> | 56 | #include <plat/regs-udc.h> |
57 | #include <plat/udc.h> | 57 | #include <plat/udc.h> |
@@ -1510,11 +1510,7 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev) | |||
1510 | 1510 | ||
1511 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | 1511 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); |
1512 | 1512 | ||
1513 | /* some cpus cannot read from an line configured to IRQ! */ | 1513 | value = gpio_get_value(udc_info->vbus_pin) ? 1 : 0; |
1514 | s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_INPUT); | ||
1515 | value = s3c2410_gpio_getpin(udc_info->vbus_pin); | ||
1516 | s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_SFN2); | ||
1517 | |||
1518 | if (udc_info->vbus_pin_inverted) | 1514 | if (udc_info->vbus_pin_inverted) |
1519 | value = !value; | 1515 | value = !value; |
1520 | 1516 | ||
@@ -1727,7 +1723,7 @@ static struct s3c2410_udc memory = { | |||
1727 | .ep0 = &memory.ep[0].ep, | 1723 | .ep0 = &memory.ep[0].ep, |
1728 | .name = gadget_name, | 1724 | .name = gadget_name, |
1729 | .dev = { | 1725 | .dev = { |
1730 | .bus_id = "gadget", | 1726 | .init_name = "gadget", |
1731 | }, | 1727 | }, |
1732 | }, | 1728 | }, |
1733 | 1729 | ||
@@ -1802,7 +1798,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) | |||
1802 | struct s3c2410_udc *udc = &memory; | 1798 | struct s3c2410_udc *udc = &memory; |
1803 | struct device *dev = &pdev->dev; | 1799 | struct device *dev = &pdev->dev; |
1804 | int retval; | 1800 | int retval; |
1805 | unsigned int irq; | 1801 | int irq; |
1806 | 1802 | ||
1807 | dev_dbg(dev, "%s()\n", __func__); | 1803 | dev_dbg(dev, "%s()\n", __func__); |
1808 | 1804 | ||
@@ -1861,7 +1857,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) | |||
1861 | 1857 | ||
1862 | /* irq setup after old hardware state is cleaned up */ | 1858 | /* irq setup after old hardware state is cleaned up */ |
1863 | retval = request_irq(IRQ_USBD, s3c2410_udc_irq, | 1859 | retval = request_irq(IRQ_USBD, s3c2410_udc_irq, |
1864 | IRQF_DISABLED, gadget_name, udc); | 1860 | IRQF_DISABLED, gadget_name, udc); |
1865 | 1861 | ||
1866 | if (retval != 0) { | 1862 | if (retval != 0) { |
1867 | dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval); | 1863 | dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval); |
@@ -1872,17 +1868,28 @@ static int s3c2410_udc_probe(struct platform_device *pdev) | |||
1872 | dev_dbg(dev, "got irq %i\n", IRQ_USBD); | 1868 | dev_dbg(dev, "got irq %i\n", IRQ_USBD); |
1873 | 1869 | ||
1874 | if (udc_info && udc_info->vbus_pin > 0) { | 1870 | if (udc_info && udc_info->vbus_pin > 0) { |
1875 | irq = s3c2410_gpio_getirq(udc_info->vbus_pin); | 1871 | retval = gpio_request(udc_info->vbus_pin, "udc vbus"); |
1872 | if (retval < 0) { | ||
1873 | dev_err(dev, "cannot claim vbus pin\n"); | ||
1874 | goto err_int; | ||
1875 | } | ||
1876 | |||
1877 | irq = gpio_to_irq(udc_info->vbus_pin); | ||
1878 | if (irq < 0) { | ||
1879 | dev_err(dev, "no irq for gpio vbus pin\n"); | ||
1880 | goto err_gpio_claim; | ||
1881 | } | ||
1882 | |||
1876 | retval = request_irq(irq, s3c2410_udc_vbus_irq, | 1883 | retval = request_irq(irq, s3c2410_udc_vbus_irq, |
1877 | IRQF_DISABLED | IRQF_TRIGGER_RISING | 1884 | IRQF_DISABLED | IRQF_TRIGGER_RISING |
1878 | | IRQF_TRIGGER_FALLING | IRQF_SHARED, | 1885 | | IRQF_TRIGGER_FALLING | IRQF_SHARED, |
1879 | gadget_name, udc); | 1886 | gadget_name, udc); |
1880 | 1887 | ||
1881 | if (retval != 0) { | 1888 | if (retval != 0) { |
1882 | dev_err(dev, "can't get vbus irq %i, err %d\n", | 1889 | dev_err(dev, "can't get vbus irq %d, err %d\n", |
1883 | irq, retval); | 1890 | irq, retval); |
1884 | retval = -EBUSY; | 1891 | retval = -EBUSY; |
1885 | goto err_int; | 1892 | goto err_gpio_claim; |
1886 | } | 1893 | } |
1887 | 1894 | ||
1888 | dev_dbg(dev, "got irq %i\n", irq); | 1895 | dev_dbg(dev, "got irq %i\n", irq); |
@@ -1902,6 +1909,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev) | |||
1902 | 1909 | ||
1903 | return 0; | 1910 | return 0; |
1904 | 1911 | ||
1912 | err_gpio_claim: | ||
1913 | if (udc_info && udc_info->vbus_pin > 0) | ||
1914 | gpio_free(udc_info->vbus_pin); | ||
1905 | err_int: | 1915 | err_int: |
1906 | free_irq(IRQ_USBD, udc); | 1916 | free_irq(IRQ_USBD, udc); |
1907 | err_map: | 1917 | err_map: |
@@ -1927,7 +1937,7 @@ static int s3c2410_udc_remove(struct platform_device *pdev) | |||
1927 | debugfs_remove(udc->regs_info); | 1937 | debugfs_remove(udc->regs_info); |
1928 | 1938 | ||
1929 | if (udc_info && udc_info->vbus_pin > 0) { | 1939 | if (udc_info && udc_info->vbus_pin > 0) { |
1930 | irq = s3c2410_gpio_getirq(udc_info->vbus_pin); | 1940 | irq = gpio_to_irq(udc_info->vbus_pin); |
1931 | free_irq(irq, udc); | 1941 | free_irq(irq, udc); |
1932 | } | 1942 | } |
1933 | 1943 | ||