diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-07 22:23:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-07 22:23:21 -0500 |
commit | c96e2c92072d3e78954c961f53d8c7352f7abbd7 (patch) | |
tree | d844f26f926ff40e98e9eae0e11fd71acad81df4 | |
parent | f2aca47dc3c2d0c2d5dbd972558557e74232bbce (diff) | |
parent | 64358164f5bfe5e11d4040c1eb674c29e1436ce5 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (70 commits)
USB: remove duplicate device id from zc0301
USB: remove duplicate device id from usb_storage
USB: remove duplicate device id from keyspan
USB: remove duplicate device id from ftdi_sio
USB: remove duplicate device id from visor
USB: a bit more coding style cleanup
usbcore: trivial whitespace fixes
usb-storage: use first bulk endpoints, not last
EHCI: fix interrupt-driven remote wakeup
USB: switch ehci-hcd to new polling scheme
USB: autosuspend for usb printer driver
USB Input: Added kernel module to support all GTCO CalComp USB InterWrite School products
USB: Sierra Wireless auto set D0
USB: usb ethernet gadget recognizes HUSB2DEV
USB: list atmel husb2_udc gadget controller
USB: gadgetfs AIO tweaks
USB: gadgetfs behaves better on userspace init bug
USB: gadgetfs race fix
USB: gadgetfs simplifications
USB: gadgetfs cleanups
...
139 files changed, 5820 insertions, 1563 deletions
diff --git a/Documentation/usb/proc_usb_info.txt b/Documentation/usb/proc_usb_info.txt index 22c5331260ca..077e9032d0cd 100644 --- a/Documentation/usb/proc_usb_info.txt +++ b/Documentation/usb/proc_usb_info.txt | |||
@@ -213,15 +213,16 @@ C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA | |||
213 | 213 | ||
214 | Interface descriptor info (can be multiple per Config): | 214 | Interface descriptor info (can be multiple per Config): |
215 | 215 | ||
216 | I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss | 216 | I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss |
217 | | | | | | | | |__Driver name | 217 | | | | | | | | | |__Driver name |
218 | | | | | | | | or "(none)" | 218 | | | | | | | | | or "(none)" |
219 | | | | | | | |__InterfaceProtocol | 219 | | | | | | | | |__InterfaceProtocol |
220 | | | | | | |__InterfaceSubClass | 220 | | | | | | | |__InterfaceSubClass |
221 | | | | | |__InterfaceClass | 221 | | | | | | |__InterfaceClass |
222 | | | | |__NumberOfEndpoints | 222 | | | | | |__NumberOfEndpoints |
223 | | | |__AlternateSettingNumber | 223 | | | | |__AlternateSettingNumber |
224 | | |__InterfaceNumber | 224 | | | |__InterfaceNumber |
225 | | |__ "*" indicates the active altsetting (others are " ") | ||
225 | |__Interface info tag | 226 | |__Interface info tag |
226 | 227 | ||
227 | A given interface may have one or more "alternate" settings. | 228 | A given interface may have one or more "alternate" settings. |
@@ -277,7 +278,7 @@ of the USB devices on a system's root hub. (See more below | |||
277 | on how to do this.) | 278 | on how to do this.) |
278 | 279 | ||
279 | The Interface lines can be used to determine what driver is | 280 | The Interface lines can be used to determine what driver is |
280 | being used for each device. | 281 | being used for each device, and which altsetting it activated. |
281 | 282 | ||
282 | The Configuration lines could be used to list maximum power | 283 | The Configuration lines could be used to list maximum power |
283 | (in milliamps) that a system's USB devices are using. | 284 | (in milliamps) that a system's USB devices are using. |
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt index e65ec828d7aa..0f6808abd612 100644 --- a/Documentation/usb/usbmon.txt +++ b/Documentation/usb/usbmon.txt | |||
@@ -77,7 +77,7 @@ that the file size is not excessive for your favourite editor. | |||
77 | 77 | ||
78 | The '1t' type data consists of a stream of events, such as URB submission, | 78 | The '1t' type data consists of a stream of events, such as URB submission, |
79 | URB callback, submission error. Every event is a text line, which consists | 79 | URB callback, submission error. Every event is a text line, which consists |
80 | of whitespace separated words. The number of position of words may depend | 80 | of whitespace separated words. The number or position of words may depend |
81 | on the event type, but there is a set of words, common for all types. | 81 | on the event type, but there is a set of words, common for all types. |
82 | 82 | ||
83 | Here is the list of words, from left to right: | 83 | Here is the list of words, from left to right: |
@@ -170,4 +170,152 @@ dd65f0e8 4128379808 C Bo:005:02 0 31 > | |||
170 | 170 | ||
171 | * Raw binary format and API | 171 | * Raw binary format and API |
172 | 172 | ||
173 | TBD | 173 | The overall architecture of the API is about the same as the one above, |
174 | only the events are delivered in binary format. Each event is sent in | ||
175 | the following structure (its name is made up, so that we can refer to it): | ||
176 | |||
177 | struct usbmon_packet { | ||
178 | u64 id; /* 0: URB ID - from submission to callback */ | ||
179 | unsigned char type; /* 8: Same as text; extensible. */ | ||
180 | unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */ | ||
181 | unsigned char epnum; /* Endpoint number and transfer direction */ | ||
182 | unsigned char devnum; /* Device address */ | ||
183 | u16 busnum; /* 12: Bus number */ | ||
184 | char flag_setup; /* 14: Same as text */ | ||
185 | char flag_data; /* 15: Same as text; Binary zero is OK. */ | ||
186 | s64 ts_sec; /* 16: gettimeofday */ | ||
187 | s32 ts_usec; /* 24: gettimeofday */ | ||
188 | int status; /* 28: */ | ||
189 | unsigned int length; /* 32: Length of data (submitted or actual) */ | ||
190 | unsigned int len_cap; /* 36: Delivered length */ | ||
191 | unsigned char setup[8]; /* 40: Only for Control 'S' */ | ||
192 | }; /* 48 bytes total */ | ||
193 | |||
194 | These events can be received from a character device by reading with read(2), | ||
195 | with an ioctl(2), or by accessing the buffer with mmap. | ||
196 | |||
197 | The character device is usually called /dev/usbmonN, where N is the USB bus | ||
198 | number. Number zero (/dev/usbmon0) is special and means "all buses". | ||
199 | However, this feature is not implemented yet. Note that specific naming | ||
200 | policy is set by your Linux distribution. | ||
201 | |||
202 | If you create /dev/usbmon0 by hand, make sure that it is owned by root | ||
203 | and has mode 0600. Otherwise, unpriviledged users will be able to snoop | ||
204 | keyboard traffic. | ||
205 | |||
206 | The following ioctl calls are available, with MON_IOC_MAGIC 0x92: | ||
207 | |||
208 | MON_IOCQ_URB_LEN, defined as _IO(MON_IOC_MAGIC, 1) | ||
209 | |||
210 | This call returns the length of data in the next event. Note that majority of | ||
211 | events contain no data, so if this call returns zero, it does not mean that | ||
212 | no events are available. | ||
213 | |||
214 | MON_IOCG_STATS, defined as _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) | ||
215 | |||
216 | The argument is a pointer to the following structure: | ||
217 | |||
218 | struct mon_bin_stats { | ||
219 | u32 queued; | ||
220 | u32 dropped; | ||
221 | }; | ||
222 | |||
223 | The member "queued" refers to the number of events currently queued in the | ||
224 | buffer (and not to the number of events processed since the last reset). | ||
225 | |||
226 | The member "dropped" is the number of events lost since the last call | ||
227 | to MON_IOCG_STATS. | ||
228 | |||
229 | MON_IOCT_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 4) | ||
230 | |||
231 | This call sets the buffer size. The argument is the size in bytes. | ||
232 | The size may be rounded down to the next chunk (or page). If the requested | ||
233 | size is out of [unspecified] bounds for this kernel, the call fails with | ||
234 | -EINVAL. | ||
235 | |||
236 | MON_IOCQ_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 5) | ||
237 | |||
238 | This call returns the current size of the buffer in bytes. | ||
239 | |||
240 | MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg) | ||
241 | |||
242 | This call waits for events to arrive if none were in the kernel buffer, | ||
243 | then returns the first event. Its argument is a pointer to the following | ||
244 | structure: | ||
245 | |||
246 | struct mon_get_arg { | ||
247 | struct usbmon_packet *hdr; | ||
248 | void *data; | ||
249 | size_t alloc; /* Length of data (can be zero) */ | ||
250 | }; | ||
251 | |||
252 | Before the call, hdr, data, and alloc should be filled. Upon return, the area | ||
253 | pointed by hdr contains the next event structure, and the data buffer contains | ||
254 | the data, if any. The event is removed from the kernel buffer. | ||
255 | |||
256 | MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg) | ||
257 | |||
258 | This ioctl is primarily used when the application accesses the buffer | ||
259 | with mmap(2). Its argument is a pointer to the following structure: | ||
260 | |||
261 | struct mon_mfetch_arg { | ||
262 | uint32_t *offvec; /* Vector of events fetched */ | ||
263 | uint32_t nfetch; /* Number of events to fetch (out: fetched) */ | ||
264 | uint32_t nflush; /* Number of events to flush */ | ||
265 | }; | ||
266 | |||
267 | The ioctl operates in 3 stages. | ||
268 | |||
269 | First, it removes and discards up to nflush events from the kernel buffer. | ||
270 | The actual number of events discarded is returned in nflush. | ||
271 | |||
272 | Second, it waits for an event to be present in the buffer, unless the pseudo- | ||
273 | device is open with O_NONBLOCK. | ||
274 | |||
275 | Third, it extracts up to nfetch offsets into the mmap buffer, and stores | ||
276 | them into the offvec. The actual number of event offsets is stored into | ||
277 | the nfetch. | ||
278 | |||
279 | MON_IOCH_MFLUSH, defined as _IO(MON_IOC_MAGIC, 8) | ||
280 | |||
281 | This call removes a number of events from the kernel buffer. Its argument | ||
282 | is the number of events to remove. If the buffer contains fewer events | ||
283 | than requested, all events present are removed, and no error is reported. | ||
284 | This works when no events are available too. | ||
285 | |||
286 | FIONBIO | ||
287 | |||
288 | The ioctl FIONBIO may be implemented in the future, if there's a need. | ||
289 | |||
290 | In addition to ioctl(2) and read(2), the special file of binary API can | ||
291 | be polled with select(2) and poll(2). But lseek(2) does not work. | ||
292 | |||
293 | * Memory-mapped access of the kernel buffer for the binary API | ||
294 | |||
295 | The basic idea is simple: | ||
296 | |||
297 | To prepare, map the buffer by getting the current size, then using mmap(2). | ||
298 | Then, execute a loop similar to the one written in pseudo-code below: | ||
299 | |||
300 | struct mon_mfetch_arg fetch; | ||
301 | struct usbmon_packet *hdr; | ||
302 | int nflush = 0; | ||
303 | for (;;) { | ||
304 | fetch.offvec = vec; // Has N 32-bit words | ||
305 | fetch.nfetch = N; // Or less than N | ||
306 | fetch.nflush = nflush; | ||
307 | ioctl(fd, MON_IOCX_MFETCH, &fetch); // Process errors, too | ||
308 | nflush = fetch.nfetch; // This many packets to flush when done | ||
309 | for (i = 0; i < nflush; i++) { | ||
310 | hdr = (struct ubsmon_packet *) &mmap_area[vec[i]]; | ||
311 | if (hdr->type == '@') // Filler packet | ||
312 | continue; | ||
313 | caddr_t data = &mmap_area[vec[i]] + 64; | ||
314 | process_packet(hdr, data); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | Thus, the main idea is to execute only one ioctl per N events. | ||
319 | |||
320 | Although the buffer is circular, the returned headers and data do not cross | ||
321 | the end of the buffer, so the above pseudo-code does not need any gathering. | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d6abe495c6b0..c1e01b22addc 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -529,6 +529,11 @@ config PPC_PS3 | |||
529 | bool "Sony PS3 (incomplete)" | 529 | bool "Sony PS3 (incomplete)" |
530 | depends on PPC_MULTIPLATFORM && PPC64 | 530 | depends on PPC_MULTIPLATFORM && PPC64 |
531 | select PPC_CELL | 531 | select PPC_CELL |
532 | select USB_ARCH_HAS_OHCI | ||
533 | select USB_OHCI_LITTLE_ENDIAN | ||
534 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
535 | select USB_ARCH_HAS_EHCI | ||
536 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
532 | help | 537 | help |
533 | This option enables support for the Sony PS3 game console | 538 | This option enables support for the Sony PS3 game console |
534 | and other platforms using the PS3 hypervisor. | 539 | and other platforms using the PS3 hypervisor. |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index ccdf3e90862b..9fafadb92510 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/usb_ch9.h> | 30 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb_gadget.h> | 31 | #include <linux/usb_gadget.h> |
32 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
33 | #include <linux/usb/otg.h> | 33 | #include <linux/usb/otg.h> |
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h index 4363a915b1f4..3daf049a288a 100644 --- a/drivers/media/video/zc0301/zc0301_sensor.h +++ b/drivers/media/video/zc0301/zc0301_sensor.h | |||
@@ -75,7 +75,6 @@ static const struct usb_device_id zc0301_id_table[] = { \ | |||
75 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ | 75 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ |
76 | { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \ | 76 | { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \ |
77 | { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \ | 77 | { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \ |
78 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ | ||
79 | { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ | 78 | { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ |
80 | { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \ | 79 | { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \ |
81 | { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ | 80 | { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 8ed6c75adf0f..638b8009b3bc 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/stat.h> | 36 | #include <linux/stat.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <linux/usb_ch9.h> | 39 | #include <linux/usb/ch9.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | 41 | ||
42 | #include "usbatm.h" | 42 | #include "usbatm.h" |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 6377db1b446d..63e50a1f1396 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -398,6 +398,9 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
398 | retval = 0; | 398 | retval = 0; |
399 | #endif | 399 | #endif |
400 | 400 | ||
401 | retval = usb_autopm_get_interface(intf); | ||
402 | if (retval < 0) | ||
403 | goto out; | ||
401 | usblp->used = 1; | 404 | usblp->used = 1; |
402 | file->private_data = usblp; | 405 | file->private_data = usblp; |
403 | 406 | ||
@@ -442,6 +445,7 @@ static int usblp_release(struct inode *inode, struct file *file) | |||
442 | usblp->used = 0; | 445 | usblp->used = 0; |
443 | if (usblp->present) { | 446 | if (usblp->present) { |
444 | usblp_unlink_urbs(usblp); | 447 | usblp_unlink_urbs(usblp); |
448 | usb_autopm_put_interface(usblp->intf); | ||
445 | } else /* finish cleanup from disconnect */ | 449 | } else /* finish cleanup from disconnect */ |
446 | usblp_cleanup (usblp); | 450 | usblp_cleanup (usblp); |
447 | mutex_unlock (&usblp_mutex); | 451 | mutex_unlock (&usblp_mutex); |
@@ -1203,14 +1207,9 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | |||
1203 | { | 1207 | { |
1204 | struct usblp *usblp = usb_get_intfdata (intf); | 1208 | struct usblp *usblp = usb_get_intfdata (intf); |
1205 | 1209 | ||
1206 | /* this races against normal access and open */ | ||
1207 | mutex_lock (&usblp_mutex); | ||
1208 | mutex_lock (&usblp->mut); | ||
1209 | /* we take no more IO */ | 1210 | /* we take no more IO */ |
1210 | usblp->sleeping = 1; | 1211 | usblp->sleeping = 1; |
1211 | usblp_unlink_urbs(usblp); | 1212 | usblp_unlink_urbs(usblp); |
1212 | mutex_unlock (&usblp->mut); | ||
1213 | mutex_unlock (&usblp_mutex); | ||
1214 | 1213 | ||
1215 | return 0; | 1214 | return 0; |
1216 | } | 1215 | } |
@@ -1220,15 +1219,9 @@ static int usblp_resume (struct usb_interface *intf) | |||
1220 | struct usblp *usblp = usb_get_intfdata (intf); | 1219 | struct usblp *usblp = usb_get_intfdata (intf); |
1221 | int r; | 1220 | int r; |
1222 | 1221 | ||
1223 | mutex_lock (&usblp_mutex); | ||
1224 | mutex_lock (&usblp->mut); | ||
1225 | |||
1226 | usblp->sleeping = 0; | 1222 | usblp->sleeping = 0; |
1227 | r = handle_bidir (usblp); | 1223 | r = handle_bidir (usblp); |
1228 | 1224 | ||
1229 | mutex_unlock (&usblp->mut); | ||
1230 | mutex_unlock (&usblp_mutex); | ||
1231 | |||
1232 | return r; | 1225 | return r; |
1233 | } | 1226 | } |
1234 | 1227 | ||
@@ -1251,6 +1244,7 @@ static struct usb_driver usblp_driver = { | |||
1251 | .suspend = usblp_suspend, | 1244 | .suspend = usblp_suspend, |
1252 | .resume = usblp_resume, | 1245 | .resume = usblp_resume, |
1253 | .id_table = usblp_ids, | 1246 | .id_table = usblp_ids, |
1247 | .supports_autosuspend = 1, | ||
1254 | }; | 1248 | }; |
1255 | 1249 | ||
1256 | static int __init usblp_init(void) | 1250 | static int __init usblp_init(void) |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 3e66b2a9974a..2fc0f88a3d86 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -33,19 +33,6 @@ config USB_DEVICEFS | |||
33 | 33 | ||
34 | Most users want to say Y here. | 34 | Most users want to say Y here. |
35 | 35 | ||
36 | config USB_BANDWIDTH | ||
37 | bool "Enforce USB bandwidth allocation (EXPERIMENTAL)" | ||
38 | depends on USB && EXPERIMENTAL | ||
39 | help | ||
40 | If you say Y here, the USB subsystem enforces USB bandwidth | ||
41 | allocation and will prevent some device opens from succeeding | ||
42 | if they would cause USB bandwidth usage to go above 90% of | ||
43 | the bus bandwidth. | ||
44 | |||
45 | If you say N here, these conditions will cause warning messages | ||
46 | about USB bandwidth usage to be logged and some devices or | ||
47 | drivers may not work correctly. | ||
48 | |||
49 | config USB_DYNAMIC_MINORS | 36 | config USB_DYNAMIC_MINORS |
50 | bool "Dynamic USB minor allocation (EXPERIMENTAL)" | 37 | bool "Dynamic USB minor allocation (EXPERIMENTAL)" |
51 | depends on USB && EXPERIMENTAL | 38 | depends on USB && EXPERIMENTAL |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index c3915dc28608..ead2475406b8 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -49,9 +49,9 @@ static const size_t pool_max [HCD_BUFFER_POOLS] = { | |||
49 | * | 49 | * |
50 | * Call hcd_buffer_destroy() to clean up after using those pools. | 50 | * Call hcd_buffer_destroy() to clean up after using those pools. |
51 | */ | 51 | */ |
52 | int hcd_buffer_create (struct usb_hcd *hcd) | 52 | int hcd_buffer_create(struct usb_hcd *hcd) |
53 | { | 53 | { |
54 | char name [16]; | 54 | char name[16]; |
55 | int i, size; | 55 | int i, size; |
56 | 56 | ||
57 | if (!hcd->self.controller->dma_mask) | 57 | if (!hcd->self.controller->dma_mask) |
@@ -60,11 +60,11 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
60 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 60 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
61 | if (!(size = pool_max [i])) | 61 | if (!(size = pool_max [i])) |
62 | continue; | 62 | continue; |
63 | snprintf (name, sizeof name, "buffer-%d", size); | 63 | snprintf(name, sizeof name, "buffer-%d", size); |
64 | hcd->pool [i] = dma_pool_create (name, hcd->self.controller, | 64 | hcd->pool[i] = dma_pool_create(name, hcd->self.controller, |
65 | size, size, 0); | 65 | size, size, 0); |
66 | if (!hcd->pool [i]) { | 66 | if (!hcd->pool [i]) { |
67 | hcd_buffer_destroy (hcd); | 67 | hcd_buffer_destroy(hcd); |
68 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | } | 69 | } |
70 | } | 70 | } |
@@ -79,14 +79,14 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
79 | * | 79 | * |
80 | * This frees the buffer pools created by hcd_buffer_create(). | 80 | * This frees the buffer pools created by hcd_buffer_create(). |
81 | */ | 81 | */ |
82 | void hcd_buffer_destroy (struct usb_hcd *hcd) | 82 | void hcd_buffer_destroy(struct usb_hcd *hcd) |
83 | { | 83 | { |
84 | int i; | 84 | int i; |
85 | 85 | ||
86 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 86 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
87 | struct dma_pool *pool = hcd->pool [i]; | 87 | struct dma_pool *pool = hcd->pool[i]; |
88 | if (pool) { | 88 | if (pool) { |
89 | dma_pool_destroy (pool); | 89 | dma_pool_destroy(pool); |
90 | hcd->pool[i] = NULL; | 90 | hcd->pool[i] = NULL; |
91 | } | 91 | } |
92 | } | 92 | } |
@@ -97,8 +97,8 @@ void hcd_buffer_destroy (struct usb_hcd *hcd) | |||
97 | * better sharing and to leverage mm/slab.c intelligence. | 97 | * better sharing and to leverage mm/slab.c intelligence. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | void *hcd_buffer_alloc ( | 100 | void *hcd_buffer_alloc( |
101 | struct usb_bus *bus, | 101 | struct usb_bus *bus, |
102 | size_t size, | 102 | size_t size, |
103 | gfp_t mem_flags, | 103 | gfp_t mem_flags, |
104 | dma_addr_t *dma | 104 | dma_addr_t *dma |
@@ -110,18 +110,18 @@ void *hcd_buffer_alloc ( | |||
110 | /* some USB hosts just use PIO */ | 110 | /* some USB hosts just use PIO */ |
111 | if (!bus->controller->dma_mask) { | 111 | if (!bus->controller->dma_mask) { |
112 | *dma = ~(dma_addr_t) 0; | 112 | *dma = ~(dma_addr_t) 0; |
113 | return kmalloc (size, mem_flags); | 113 | return kmalloc(size, mem_flags); |
114 | } | 114 | } |
115 | 115 | ||
116 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 116 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
117 | if (size <= pool_max [i]) | 117 | if (size <= pool_max [i]) |
118 | return dma_pool_alloc (hcd->pool [i], mem_flags, dma); | 118 | return dma_pool_alloc(hcd->pool [i], mem_flags, dma); |
119 | } | 119 | } |
120 | return dma_alloc_coherent (hcd->self.controller, size, dma, 0); | 120 | return dma_alloc_coherent(hcd->self.controller, size, dma, 0); |
121 | } | 121 | } |
122 | 122 | ||
123 | void hcd_buffer_free ( | 123 | void hcd_buffer_free( |
124 | struct usb_bus *bus, | 124 | struct usb_bus *bus, |
125 | size_t size, | 125 | size_t size, |
126 | void *addr, | 126 | void *addr, |
127 | dma_addr_t dma | 127 | dma_addr_t dma |
@@ -134,15 +134,15 @@ void hcd_buffer_free ( | |||
134 | return; | 134 | return; |
135 | 135 | ||
136 | if (!bus->controller->dma_mask) { | 136 | if (!bus->controller->dma_mask) { |
137 | kfree (addr); | 137 | kfree(addr); |
138 | return; | 138 | return; |
139 | } | 139 | } |
140 | 140 | ||
141 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 141 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
142 | if (size <= pool_max [i]) { | 142 | if (size <= pool_max [i]) { |
143 | dma_pool_free (hcd->pool [i], addr, dma); | 143 | dma_pool_free(hcd->pool [i], addr, dma); |
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | dma_free_coherent (hcd->self.controller, size, addr, dma); | 147 | dma_free_coherent(hcd->self.controller, size, addr, dma); |
148 | } | 148 | } |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index ea398e5d50af..a47c30b2d764 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -104,7 +104,7 @@ static const char *format_config = | |||
104 | 104 | ||
105 | static const char *format_iface = | 105 | static const char *format_iface = |
106 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ | 106 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ |
107 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; | 107 | "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; |
108 | 108 | ||
109 | static const char *format_endpt = | 109 | static const char *format_endpt = |
110 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ | 110 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ |
@@ -164,10 +164,10 @@ static const char *class_decode(const int class) | |||
164 | for (ix = 0; clas_info[ix].class != -1; ix++) | 164 | for (ix = 0; clas_info[ix].class != -1; ix++) |
165 | if (clas_info[ix].class == class) | 165 | if (clas_info[ix].class == class) |
166 | break; | 166 | break; |
167 | return (clas_info[ix].class_name); | 167 | return clas_info[ix].class_name; |
168 | } | 168 | } |
169 | 169 | ||
170 | static char *usb_dump_endpoint_descriptor ( | 170 | static char *usb_dump_endpoint_descriptor( |
171 | int speed, | 171 | int speed, |
172 | char *start, | 172 | char *start, |
173 | char *end, | 173 | char *end, |
@@ -212,9 +212,9 @@ static char *usb_dump_endpoint_descriptor ( | |||
212 | break; | 212 | break; |
213 | case USB_ENDPOINT_XFER_INT: | 213 | case USB_ENDPOINT_XFER_INT: |
214 | type = "Int."; | 214 | type = "Int."; |
215 | if (speed == USB_SPEED_HIGH) { | 215 | if (speed == USB_SPEED_HIGH) |
216 | interval = 1 << (desc->bInterval - 1); | 216 | interval = 1 << (desc->bInterval - 1); |
217 | } else | 217 | else |
218 | interval = desc->bInterval; | 218 | interval = desc->bInterval; |
219 | break; | 219 | break; |
220 | default: /* "can't happen" */ | 220 | default: /* "can't happen" */ |
@@ -242,15 +242,19 @@ static char *usb_dump_interface_descriptor(char *start, char *end, | |||
242 | { | 242 | { |
243 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; | 243 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; |
244 | const char *driver_name = ""; | 244 | const char *driver_name = ""; |
245 | int active = 0; | ||
245 | 246 | ||
246 | if (start > end) | 247 | if (start > end) |
247 | return start; | 248 | return start; |
248 | down_read(&usb_bus_type.subsys.rwsem); | 249 | down_read(&usb_bus_type.subsys.rwsem); |
249 | if (iface) | 250 | if (iface) { |
250 | driver_name = (iface->dev.driver | 251 | driver_name = (iface->dev.driver |
251 | ? iface->dev.driver->name | 252 | ? iface->dev.driver->name |
252 | : "(none)"); | 253 | : "(none)"); |
254 | active = (desc == &iface->cur_altsetting->desc); | ||
255 | } | ||
253 | start += sprintf(start, format_iface, | 256 | start += sprintf(start, format_iface, |
257 | active ? '*' : ' ', /* mark active altsetting */ | ||
254 | desc->bInterfaceNumber, | 258 | desc->bInterfaceNumber, |
255 | desc->bAlternateSetting, | 259 | desc->bAlternateSetting, |
256 | desc->bNumEndpoints, | 260 | desc->bNumEndpoints, |
@@ -343,7 +347,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb | |||
343 | 347 | ||
344 | if (start > end) | 348 | if (start > end) |
345 | return start; | 349 | return start; |
346 | start += sprintf (start, format_device1, | 350 | start += sprintf(start, format_device1, |
347 | bcdUSB >> 8, bcdUSB & 0xff, | 351 | bcdUSB >> 8, bcdUSB & 0xff, |
348 | desc->bDeviceClass, | 352 | desc->bDeviceClass, |
349 | class_decode (desc->bDeviceClass), | 353 | class_decode (desc->bDeviceClass), |
@@ -363,7 +367,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb | |||
363 | /* | 367 | /* |
364 | * Dump the different strings that this device holds. | 368 | * Dump the different strings that this device holds. |
365 | */ | 369 | */ |
366 | static char *usb_dump_device_strings (char *start, char *end, struct usb_device *dev) | 370 | static char *usb_dump_device_strings(char *start, char *end, struct usb_device *dev) |
367 | { | 371 | { |
368 | if (start > end) | 372 | if (start > end) |
369 | return start; | 373 | return start; |
@@ -395,7 +399,7 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev) | |||
395 | if (start > end) | 399 | if (start > end) |
396 | return start; | 400 | return start; |
397 | 401 | ||
398 | start = usb_dump_device_strings (start, end, dev); | 402 | start = usb_dump_device_strings(start, end, dev); |
399 | 403 | ||
400 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { | 404 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { |
401 | if (start > end) | 405 | if (start > end) |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4b3a6ab29bd3..2087766f9e88 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -522,19 +522,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
522 | 522 | ||
523 | static struct usb_device *usbdev_lookup_minor(int minor) | 523 | static struct usb_device *usbdev_lookup_minor(int minor) |
524 | { | 524 | { |
525 | struct class_device *class_dev; | 525 | struct device *device; |
526 | struct usb_device *dev = NULL; | 526 | struct usb_device *udev = NULL; |
527 | 527 | ||
528 | down(&usb_device_class->sem); | 528 | down(&usb_device_class->sem); |
529 | list_for_each_entry(class_dev, &usb_device_class->children, node) { | 529 | list_for_each_entry(device, &usb_device_class->devices, node) { |
530 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | 530 | if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { |
531 | dev = class_dev->class_data; | 531 | udev = device->platform_data; |
532 | break; | 532 | break; |
533 | } | 533 | } |
534 | } | 534 | } |
535 | up(&usb_device_class->sem); | 535 | up(&usb_device_class->sem); |
536 | 536 | ||
537 | return dev; | 537 | return udev; |
538 | }; | 538 | }; |
539 | 539 | ||
540 | /* | 540 | /* |
@@ -570,6 +570,7 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
570 | ps->dev = dev; | 570 | ps->dev = dev; |
571 | ps->file = file; | 571 | ps->file = file; |
572 | spin_lock_init(&ps->lock); | 572 | spin_lock_init(&ps->lock); |
573 | INIT_LIST_HEAD(&ps->list); | ||
573 | INIT_LIST_HEAD(&ps->async_pending); | 574 | INIT_LIST_HEAD(&ps->async_pending); |
574 | INIT_LIST_HEAD(&ps->async_completed); | 575 | INIT_LIST_HEAD(&ps->async_completed); |
575 | init_waitqueue_head(&ps->wait); | 576 | init_waitqueue_head(&ps->wait); |
@@ -1596,19 +1597,19 @@ static int usbdev_add(struct usb_device *dev) | |||
1596 | { | 1597 | { |
1597 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1598 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1598 | 1599 | ||
1599 | dev->class_dev = class_device_create(usb_device_class, NULL, | 1600 | dev->usbfs_dev = device_create(usb_device_class, &dev->dev, |
1600 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, | 1601 | MKDEV(USB_DEVICE_MAJOR, minor), |
1601 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); | 1602 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); |
1602 | if (IS_ERR(dev->class_dev)) | 1603 | if (IS_ERR(dev->usbfs_dev)) |
1603 | return PTR_ERR(dev->class_dev); | 1604 | return PTR_ERR(dev->usbfs_dev); |
1604 | 1605 | ||
1605 | dev->class_dev->class_data = dev; | 1606 | dev->usbfs_dev->platform_data = dev; |
1606 | return 0; | 1607 | return 0; |
1607 | } | 1608 | } |
1608 | 1609 | ||
1609 | static void usbdev_remove(struct usb_device *dev) | 1610 | static void usbdev_remove(struct usb_device *dev) |
1610 | { | 1611 | { |
1611 | class_device_unregister(dev->class_dev); | 1612 | device_unregister(dev->usbfs_dev); |
1612 | } | 1613 | } |
1613 | 1614 | ||
1614 | static int usbdev_notify(struct notifier_block *self, unsigned long action, | 1615 | static int usbdev_notify(struct notifier_block *self, unsigned long action, |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d505926aa9cc..600d1bc8272a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -28,24 +28,16 @@ | |||
28 | #include "hcd.h" | 28 | #include "hcd.h" |
29 | #include "usb.h" | 29 | #include "usb.h" |
30 | 30 | ||
31 | static int usb_match_one_id(struct usb_interface *interface, | ||
32 | const struct usb_device_id *id); | ||
33 | |||
34 | struct usb_dynid { | ||
35 | struct list_head node; | ||
36 | struct usb_device_id id; | ||
37 | }; | ||
38 | |||
39 | #ifdef CONFIG_HOTPLUG | 31 | #ifdef CONFIG_HOTPLUG |
40 | 32 | ||
41 | /* | 33 | /* |
42 | * Adds a new dynamic USBdevice ID to this driver, | 34 | * Adds a new dynamic USBdevice ID to this driver, |
43 | * and cause the driver to probe for all devices again. | 35 | * and cause the driver to probe for all devices again. |
44 | */ | 36 | */ |
45 | static ssize_t store_new_id(struct device_driver *driver, | 37 | ssize_t usb_store_new_id(struct usb_dynids *dynids, |
46 | const char *buf, size_t count) | 38 | struct device_driver *driver, |
39 | const char *buf, size_t count) | ||
47 | { | 40 | { |
48 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
49 | struct usb_dynid *dynid; | 41 | struct usb_dynid *dynid; |
50 | u32 idVendor = 0; | 42 | u32 idVendor = 0; |
51 | u32 idProduct = 0; | 43 | u32 idProduct = 0; |
@@ -65,9 +57,9 @@ static ssize_t store_new_id(struct device_driver *driver, | |||
65 | dynid->id.idProduct = idProduct; | 57 | dynid->id.idProduct = idProduct; |
66 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 58 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
67 | 59 | ||
68 | spin_lock(&usb_drv->dynids.lock); | 60 | spin_lock(&dynids->lock); |
69 | list_add_tail(&usb_drv->dynids.list, &dynid->node); | 61 | list_add_tail(&dynids->list, &dynid->node); |
70 | spin_unlock(&usb_drv->dynids.lock); | 62 | spin_unlock(&dynids->lock); |
71 | 63 | ||
72 | if (get_driver(driver)) { | 64 | if (get_driver(driver)) { |
73 | retval = driver_attach(driver); | 65 | retval = driver_attach(driver); |
@@ -78,6 +70,15 @@ static ssize_t store_new_id(struct device_driver *driver, | |||
78 | return retval; | 70 | return retval; |
79 | return count; | 71 | return count; |
80 | } | 72 | } |
73 | EXPORT_SYMBOL_GPL(usb_store_new_id); | ||
74 | |||
75 | static ssize_t store_new_id(struct device_driver *driver, | ||
76 | const char *buf, size_t count) | ||
77 | { | ||
78 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
79 | |||
80 | return usb_store_new_id(&usb_drv->dynids, driver, buf, count); | ||
81 | } | ||
81 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | 82 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); |
82 | 83 | ||
83 | static int usb_create_newid_file(struct usb_driver *usb_drv) | 84 | static int usb_create_newid_file(struct usb_driver *usb_drv) |
@@ -365,8 +366,8 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
365 | EXPORT_SYMBOL(usb_driver_release_interface); | 366 | EXPORT_SYMBOL(usb_driver_release_interface); |
366 | 367 | ||
367 | /* returns 0 if no match, 1 if match */ | 368 | /* returns 0 if no match, 1 if match */ |
368 | static int usb_match_one_id(struct usb_interface *interface, | 369 | int usb_match_one_id(struct usb_interface *interface, |
369 | const struct usb_device_id *id) | 370 | const struct usb_device_id *id) |
370 | { | 371 | { |
371 | struct usb_host_interface *intf; | 372 | struct usb_host_interface *intf; |
372 | struct usb_device *dev; | 373 | struct usb_device *dev; |
@@ -432,6 +433,8 @@ static int usb_match_one_id(struct usb_interface *interface, | |||
432 | 433 | ||
433 | return 1; | 434 | return 1; |
434 | } | 435 | } |
436 | EXPORT_SYMBOL_GPL(usb_match_one_id); | ||
437 | |||
435 | /** | 438 | /** |
436 | * usb_match_id - find first usb_device_id matching device or interface | 439 | * usb_match_id - find first usb_device_id matching device or interface |
437 | * @interface: the interface of interest | 440 | * @interface: the interface of interest |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index f794f07cfb33..01c857ac27af 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -194,14 +194,13 @@ int usb_register_dev(struct usb_interface *intf, | |||
194 | ++temp; | 194 | ++temp; |
195 | else | 195 | else |
196 | temp = name; | 196 | temp = name; |
197 | intf->class_dev = class_device_create(usb_class->class, NULL, | 197 | intf->usb_dev = device_create(usb_class->class, &intf->dev, |
198 | MKDEV(USB_MAJOR, minor), | 198 | MKDEV(USB_MAJOR, minor), "%s", temp); |
199 | &intf->dev, "%s", temp); | 199 | if (IS_ERR(intf->usb_dev)) { |
200 | if (IS_ERR(intf->class_dev)) { | ||
201 | spin_lock (&minor_lock); | 200 | spin_lock (&minor_lock); |
202 | usb_minors[intf->minor] = NULL; | 201 | usb_minors[intf->minor] = NULL; |
203 | spin_unlock (&minor_lock); | 202 | spin_unlock (&minor_lock); |
204 | retval = PTR_ERR(intf->class_dev); | 203 | retval = PTR_ERR(intf->usb_dev); |
205 | } | 204 | } |
206 | exit: | 205 | exit: |
207 | return retval; | 206 | return retval; |
@@ -242,8 +241,8 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
242 | spin_unlock (&minor_lock); | 241 | spin_unlock (&minor_lock); |
243 | 242 | ||
244 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); | 243 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); |
245 | class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); | 244 | device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); |
246 | intf->class_dev = NULL; | 245 | intf->usb_dev = NULL; |
247 | intf->minor = -1; | 246 | intf->minor = -1; |
248 | destroy_usb_class(); | 247 | destroy_usb_class(); |
249 | } | 248 | } |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index ebb20ff7ac58..b531a4fd30c2 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -25,6 +25,20 @@ static inline const char *plural(int n) | |||
25 | return (n == 1 ? "" : "s"); | 25 | return (n == 1 ? "" : "s"); |
26 | } | 26 | } |
27 | 27 | ||
28 | static int is_rndis(struct usb_interface_descriptor *desc) | ||
29 | { | ||
30 | return desc->bInterfaceClass == USB_CLASS_COMM | ||
31 | && desc->bInterfaceSubClass == 2 | ||
32 | && desc->bInterfaceProtocol == 0xff; | ||
33 | } | ||
34 | |||
35 | static int is_activesync(struct usb_interface_descriptor *desc) | ||
36 | { | ||
37 | return desc->bInterfaceClass == USB_CLASS_MISC | ||
38 | && desc->bInterfaceSubClass == 1 | ||
39 | && desc->bInterfaceProtocol == 1; | ||
40 | } | ||
41 | |||
28 | static int choose_configuration(struct usb_device *udev) | 42 | static int choose_configuration(struct usb_device *udev) |
29 | { | 43 | { |
30 | int i; | 44 | int i; |
@@ -87,14 +101,12 @@ static int choose_configuration(struct usb_device *udev) | |||
87 | continue; | 101 | continue; |
88 | } | 102 | } |
89 | 103 | ||
90 | /* If the first config's first interface is COMM/2/0xff | 104 | /* When the first config's first interface is one of Microsoft's |
91 | * (MSFT RNDIS), rule it out unless Linux has host-side | 105 | * pet nonstandard Ethernet-over-USB protocols, ignore it unless |
92 | * RNDIS support. */ | 106 | * this kernel has enabled the necessary host side driver. |
93 | if (i == 0 && desc | 107 | */ |
94 | && desc->bInterfaceClass == USB_CLASS_COMM | 108 | if (i == 0 && desc && (is_rndis(desc) || is_activesync(desc))) { |
95 | && desc->bInterfaceSubClass == 2 | 109 | #if !defined(CONFIG_USB_NET_RNDIS_HOST) && !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) |
96 | && desc->bInterfaceProtocol == 0xff) { | ||
97 | #ifndef CONFIG_USB_NET_RNDIS_HOST | ||
98 | continue; | 110 | continue; |
99 | #else | 111 | #else |
100 | best = c; | 112 | best = c; |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 10064af65d17..b26c19e8d19f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -45,8 +45,6 @@ | |||
45 | #include "hub.h" | 45 | #include "hub.h" |
46 | 46 | ||
47 | 47 | ||
48 | // #define USB_BANDWIDTH_MESSAGES | ||
49 | |||
50 | /*-------------------------------------------------------------------------*/ | 48 | /*-------------------------------------------------------------------------*/ |
51 | 49 | ||
52 | /* | 50 | /* |
@@ -891,136 +889,6 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) | |||
891 | } | 889 | } |
892 | EXPORT_SYMBOL (usb_calc_bus_time); | 890 | EXPORT_SYMBOL (usb_calc_bus_time); |
893 | 891 | ||
894 | /* | ||
895 | * usb_check_bandwidth(): | ||
896 | * | ||
897 | * old_alloc is from host_controller->bandwidth_allocated in microseconds; | ||
898 | * bustime is from calc_bus_time(), but converted to microseconds. | ||
899 | * | ||
900 | * returns <bustime in us> if successful, | ||
901 | * or -ENOSPC if bandwidth request fails. | ||
902 | * | ||
903 | * FIXME: | ||
904 | * This initial implementation does not use Endpoint.bInterval | ||
905 | * in managing bandwidth allocation. | ||
906 | * It probably needs to be expanded to use Endpoint.bInterval. | ||
907 | * This can be done as a later enhancement (correction). | ||
908 | * | ||
909 | * This will also probably require some kind of | ||
910 | * frame allocation tracking...meaning, for example, | ||
911 | * that if multiple drivers request interrupts every 10 USB frames, | ||
912 | * they don't all have to be allocated at | ||
913 | * frame numbers N, N+10, N+20, etc. Some of them could be at | ||
914 | * N+11, N+21, N+31, etc., and others at | ||
915 | * N+12, N+22, N+32, etc. | ||
916 | * | ||
917 | * Similarly for isochronous transfers... | ||
918 | * | ||
919 | * Individual HCDs can schedule more directly ... this logic | ||
920 | * is not correct for high speed transfers. | ||
921 | */ | ||
922 | int usb_check_bandwidth (struct usb_device *dev, struct urb *urb) | ||
923 | { | ||
924 | unsigned int pipe = urb->pipe; | ||
925 | long bustime; | ||
926 | int is_in = usb_pipein (pipe); | ||
927 | int is_iso = usb_pipeisoc (pipe); | ||
928 | int old_alloc = dev->bus->bandwidth_allocated; | ||
929 | int new_alloc; | ||
930 | |||
931 | |||
932 | bustime = NS_TO_US (usb_calc_bus_time (dev->speed, is_in, is_iso, | ||
933 | usb_maxpacket (dev, pipe, !is_in))); | ||
934 | if (is_iso) | ||
935 | bustime /= urb->number_of_packets; | ||
936 | |||
937 | new_alloc = old_alloc + (int) bustime; | ||
938 | if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC) { | ||
939 | #ifdef DEBUG | ||
940 | char *mode = | ||
941 | #ifdef CONFIG_USB_BANDWIDTH | ||
942 | ""; | ||
943 | #else | ||
944 | "would have "; | ||
945 | #endif | ||
946 | dev_dbg (&dev->dev, "usb_check_bandwidth %sFAILED: %d + %ld = %d usec\n", | ||
947 | mode, old_alloc, bustime, new_alloc); | ||
948 | #endif | ||
949 | #ifdef CONFIG_USB_BANDWIDTH | ||
950 | bustime = -ENOSPC; /* report error */ | ||
951 | #endif | ||
952 | } | ||
953 | |||
954 | return bustime; | ||
955 | } | ||
956 | EXPORT_SYMBOL (usb_check_bandwidth); | ||
957 | |||
958 | |||
959 | /** | ||
960 | * usb_claim_bandwidth - records bandwidth for a periodic transfer | ||
961 | * @dev: source/target of request | ||
962 | * @urb: request (urb->dev == dev) | ||
963 | * @bustime: bandwidth consumed, in (average) microseconds per frame | ||
964 | * @isoc: true iff the request is isochronous | ||
965 | * | ||
966 | * Bus bandwidth reservations are recorded purely for diagnostic purposes. | ||
967 | * HCDs are expected not to overcommit periodic bandwidth, and to record such | ||
968 | * reservations whenever endpoints are added to the periodic schedule. | ||
969 | * | ||
970 | * FIXME averaging per-frame is suboptimal. Better to sum over the HCD's | ||
971 | * entire periodic schedule ... 32 frames for OHCI, 1024 for UHCI, settable | ||
972 | * for EHCI (256/512/1024 frames, default 1024) and have the bus expose how | ||
973 | * large its periodic schedule is. | ||
974 | */ | ||
975 | void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) | ||
976 | { | ||
977 | dev->bus->bandwidth_allocated += bustime; | ||
978 | if (isoc) | ||
979 | dev->bus->bandwidth_isoc_reqs++; | ||
980 | else | ||
981 | dev->bus->bandwidth_int_reqs++; | ||
982 | urb->bandwidth = bustime; | ||
983 | |||
984 | #ifdef USB_BANDWIDTH_MESSAGES | ||
985 | dev_dbg (&dev->dev, "bandwidth alloc increased by %d (%s) to %d for %d requesters\n", | ||
986 | bustime, | ||
987 | isoc ? "ISOC" : "INTR", | ||
988 | dev->bus->bandwidth_allocated, | ||
989 | dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); | ||
990 | #endif | ||
991 | } | ||
992 | EXPORT_SYMBOL (usb_claim_bandwidth); | ||
993 | |||
994 | |||
995 | /** | ||
996 | * usb_release_bandwidth - reverses effect of usb_claim_bandwidth() | ||
997 | * @dev: source/target of request | ||
998 | * @urb: request (urb->dev == dev) | ||
999 | * @isoc: true iff the request is isochronous | ||
1000 | * | ||
1001 | * This records that previously allocated bandwidth has been released. | ||
1002 | * Bandwidth is released when endpoints are removed from the host controller's | ||
1003 | * periodic schedule. | ||
1004 | */ | ||
1005 | void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, int isoc) | ||
1006 | { | ||
1007 | dev->bus->bandwidth_allocated -= urb->bandwidth; | ||
1008 | if (isoc) | ||
1009 | dev->bus->bandwidth_isoc_reqs--; | ||
1010 | else | ||
1011 | dev->bus->bandwidth_int_reqs--; | ||
1012 | |||
1013 | #ifdef USB_BANDWIDTH_MESSAGES | ||
1014 | dev_dbg (&dev->dev, "bandwidth alloc reduced by %d (%s) to %d for %d requesters\n", | ||
1015 | urb->bandwidth, | ||
1016 | isoc ? "ISOC" : "INTR", | ||
1017 | dev->bus->bandwidth_allocated, | ||
1018 | dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); | ||
1019 | #endif | ||
1020 | urb->bandwidth = 0; | ||
1021 | } | ||
1022 | EXPORT_SYMBOL (usb_release_bandwidth); | ||
1023 | |||
1024 | 892 | ||
1025 | /*-------------------------------------------------------------------------*/ | 893 | /*-------------------------------------------------------------------------*/ |
1026 | 894 | ||
@@ -1034,11 +902,6 @@ static void urb_unlink (struct urb *urb) | |||
1034 | { | 902 | { |
1035 | unsigned long flags; | 903 | unsigned long flags; |
1036 | 904 | ||
1037 | /* Release any periodic transfer bandwidth */ | ||
1038 | if (urb->bandwidth) | ||
1039 | usb_release_bandwidth (urb->dev, urb, | ||
1040 | usb_pipeisoc (urb->pipe)); | ||
1041 | |||
1042 | /* clear all state linking urb to this dev (and hcd) */ | 905 | /* clear all state linking urb to this dev (and hcd) */ |
1043 | 906 | ||
1044 | spin_lock_irqsave (&hcd_data_lock, flags); | 907 | spin_lock_irqsave (&hcd_data_lock, flags); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 8f8df0d4382e..2a269ca20517 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -308,10 +308,6 @@ extern void usb_destroy_configuration(struct usb_device *dev); | |||
308 | #define NS_TO_US(ns) ((ns + 500L) / 1000L) | 308 | #define NS_TO_US(ns) ((ns + 500L) / 1000L) |
309 | /* convert & round nanoseconds to microseconds */ | 309 | /* convert & round nanoseconds to microseconds */ |
310 | 310 | ||
311 | extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, | ||
312 | int bustime, int isoc); | ||
313 | extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, | ||
314 | int isoc); | ||
315 | 311 | ||
316 | /* | 312 | /* |
317 | * Full/low speed bandwidth allocation constants/support. | 313 | * Full/low speed bandwidth allocation constants/support. |
@@ -324,8 +320,6 @@ extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, | |||
324 | #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) | 320 | #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) |
325 | #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) | 321 | #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) |
326 | 322 | ||
327 | extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); | ||
328 | |||
329 | /* | 323 | /* |
330 | * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed | 324 | * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed |
331 | * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed | 325 | * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1988224b362b..590ec82d0515 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -87,9 +87,6 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); | |||
87 | 87 | ||
88 | static struct task_struct *khubd_task; | 88 | static struct task_struct *khubd_task; |
89 | 89 | ||
90 | /* multithreaded probe logic */ | ||
91 | static int multithread_probe = 0; | ||
92 | |||
93 | /* cycle leds on hubs that aren't blinking for attention */ | 90 | /* cycle leds on hubs that aren't blinking for attention */ |
94 | static int blinkenlights = 0; | 91 | static int blinkenlights = 0; |
95 | module_param (blinkenlights, bool, S_IRUGO); | 92 | module_param (blinkenlights, bool, S_IRUGO); |
@@ -1256,9 +1253,28 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1256 | static int __usb_port_suspend(struct usb_device *, int port1); | 1253 | static int __usb_port_suspend(struct usb_device *, int port1); |
1257 | #endif | 1254 | #endif |
1258 | 1255 | ||
1259 | static int __usb_new_device(void *void_data) | 1256 | /** |
1257 | * usb_new_device - perform initial device setup (usbcore-internal) | ||
1258 | * @udev: newly addressed device (in ADDRESS state) | ||
1259 | * | ||
1260 | * This is called with devices which have been enumerated, but not yet | ||
1261 | * configured. The device descriptor is available, but not descriptors | ||
1262 | * for any device configuration. The caller must have locked either | ||
1263 | * the parent hub (if udev is a normal device) or else the | ||
1264 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1265 | * udev has already been installed, but udev is not yet visible through | ||
1266 | * sysfs or other filesystem code. | ||
1267 | * | ||
1268 | * It will return if the device is configured properly or not. Zero if | ||
1269 | * the interface was registered with the driver core; else a negative | ||
1270 | * errno value. | ||
1271 | * | ||
1272 | * This call is synchronous, and may not be used in an interrupt context. | ||
1273 | * | ||
1274 | * Only the hub driver or root-hub registrar should ever call this. | ||
1275 | */ | ||
1276 | int usb_new_device(struct usb_device *udev) | ||
1260 | { | 1277 | { |
1261 | struct usb_device *udev = void_data; | ||
1262 | int err; | 1278 | int err; |
1263 | 1279 | ||
1264 | /* Lock ourself into memory in order to keep a probe sequence | 1280 | /* Lock ourself into memory in order to keep a probe sequence |
@@ -1375,44 +1391,6 @@ fail: | |||
1375 | goto exit; | 1391 | goto exit; |
1376 | } | 1392 | } |
1377 | 1393 | ||
1378 | /** | ||
1379 | * usb_new_device - perform initial device setup (usbcore-internal) | ||
1380 | * @udev: newly addressed device (in ADDRESS state) | ||
1381 | * | ||
1382 | * This is called with devices which have been enumerated, but not yet | ||
1383 | * configured. The device descriptor is available, but not descriptors | ||
1384 | * for any device configuration. The caller must have locked either | ||
1385 | * the parent hub (if udev is a normal device) or else the | ||
1386 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1387 | * udev has already been installed, but udev is not yet visible through | ||
1388 | * sysfs or other filesystem code. | ||
1389 | * | ||
1390 | * The return value for this function depends on if the | ||
1391 | * multithread_probe variable is set or not. If it's set, it will | ||
1392 | * return a if the probe thread was successfully created or not. If the | ||
1393 | * variable is not set, it will return if the device is configured | ||
1394 | * properly or not. interfaces, in sysfs); else a negative errno value. | ||
1395 | * | ||
1396 | * This call is synchronous, and may not be used in an interrupt context. | ||
1397 | * | ||
1398 | * Only the hub driver or root-hub registrar should ever call this. | ||
1399 | */ | ||
1400 | int usb_new_device(struct usb_device *udev) | ||
1401 | { | ||
1402 | struct task_struct *probe_task; | ||
1403 | int ret = 0; | ||
1404 | |||
1405 | if (multithread_probe) { | ||
1406 | probe_task = kthread_run(__usb_new_device, udev, | ||
1407 | "usb-probe-%s", udev->devnum); | ||
1408 | if (IS_ERR(probe_task)) | ||
1409 | ret = PTR_ERR(probe_task); | ||
1410 | } else | ||
1411 | ret = __usb_new_device(udev); | ||
1412 | |||
1413 | return ret; | ||
1414 | } | ||
1415 | |||
1416 | static int hub_port_status(struct usb_hub *hub, int port1, | 1394 | static int hub_port_status(struct usb_hub *hub, int port1, |
1417 | u16 *status, u16 *change) | 1395 | u16 *status, u16 *change) |
1418 | { | 1396 | { |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 149aa8bfb1fe..8aca3574c2b5 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1545,11 +1545,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) | |||
1545 | INIT_WORK(&req->work, driver_set_config_work); | 1545 | INIT_WORK(&req->work, driver_set_config_work); |
1546 | 1546 | ||
1547 | usb_get_dev(udev); | 1547 | usb_get_dev(udev); |
1548 | if (!schedule_work(&req->work)) { | 1548 | schedule_work(&req->work); |
1549 | usb_put_dev(udev); | ||
1550 | kfree(req); | ||
1551 | return -EINVAL; | ||
1552 | } | ||
1553 | return 0; | 1549 | return 0; |
1554 | } | 1550 | } |
1555 | EXPORT_SYMBOL_GPL(usb_driver_set_configuration); | 1551 | EXPORT_SYMBOL_GPL(usb_driver_set_configuration); |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 55d8f575206d..4eaa0ee8e72f 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -16,16 +16,16 @@ | |||
16 | 16 | ||
17 | /* Active configuration fields */ | 17 | /* Active configuration fields */ |
18 | #define usb_actconfig_show(field, multiplier, format_string) \ | 18 | #define usb_actconfig_show(field, multiplier, format_string) \ |
19 | static ssize_t show_##field (struct device *dev, \ | 19 | static ssize_t show_##field(struct device *dev, \ |
20 | struct device_attribute *attr, char *buf) \ | 20 | struct device_attribute *attr, char *buf) \ |
21 | { \ | 21 | { \ |
22 | struct usb_device *udev; \ | 22 | struct usb_device *udev; \ |
23 | struct usb_host_config *actconfig; \ | 23 | struct usb_host_config *actconfig; \ |
24 | \ | 24 | \ |
25 | udev = to_usb_device (dev); \ | 25 | udev = to_usb_device(dev); \ |
26 | actconfig = udev->actconfig; \ | 26 | actconfig = udev->actconfig; \ |
27 | if (actconfig) \ | 27 | if (actconfig) \ |
28 | return sprintf (buf, format_string, \ | 28 | return sprintf(buf, format_string, \ |
29 | actconfig->desc.field * multiplier); \ | 29 | actconfig->desc.field * multiplier); \ |
30 | else \ | 30 | else \ |
31 | return 0; \ | 31 | return 0; \ |
@@ -35,9 +35,9 @@ static ssize_t show_##field (struct device *dev, \ | |||
35 | usb_actconfig_show(field, multiplier, format_string) \ | 35 | usb_actconfig_show(field, multiplier, format_string) \ |
36 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 36 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
37 | 37 | ||
38 | usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") | 38 | usb_actconfig_attr(bNumInterfaces, 1, "%2d\n") |
39 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") | 39 | usb_actconfig_attr(bmAttributes, 1, "%2x\n") |
40 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") | 40 | usb_actconfig_attr(bMaxPower, 2, "%3dmA\n") |
41 | 41 | ||
42 | static ssize_t show_configuration_string(struct device *dev, | 42 | static ssize_t show_configuration_string(struct device *dev, |
43 | struct device_attribute *attr, char *buf) | 43 | struct device_attribute *attr, char *buf) |
@@ -45,7 +45,7 @@ static ssize_t show_configuration_string(struct device *dev, | |||
45 | struct usb_device *udev; | 45 | struct usb_device *udev; |
46 | struct usb_host_config *actconfig; | 46 | struct usb_host_config *actconfig; |
47 | 47 | ||
48 | udev = to_usb_device (dev); | 48 | udev = to_usb_device(dev); |
49 | actconfig = udev->actconfig; | 49 | actconfig = udev->actconfig; |
50 | if ((!actconfig) || (!actconfig->string)) | 50 | if ((!actconfig) || (!actconfig->string)) |
51 | return 0; | 51 | return 0; |
@@ -57,16 +57,16 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | |||
57 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); | 57 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); |
58 | 58 | ||
59 | static ssize_t | 59 | static ssize_t |
60 | set_bConfigurationValue (struct device *dev, struct device_attribute *attr, | 60 | set_bConfigurationValue(struct device *dev, struct device_attribute *attr, |
61 | const char *buf, size_t count) | 61 | const char *buf, size_t count) |
62 | { | 62 | { |
63 | struct usb_device *udev = to_usb_device (dev); | 63 | struct usb_device *udev = to_usb_device(dev); |
64 | int config, value; | 64 | int config, value; |
65 | 65 | ||
66 | if (sscanf (buf, "%u", &config) != 1 || config > 255) | 66 | if (sscanf(buf, "%u", &config) != 1 || config > 255) |
67 | return -EINVAL; | 67 | return -EINVAL; |
68 | usb_lock_device(udev); | 68 | usb_lock_device(udev); |
69 | value = usb_set_configuration (udev, config); | 69 | value = usb_set_configuration(udev, config); |
70 | usb_unlock_device(udev); | 70 | usb_unlock_device(udev); |
71 | return (value < 0) ? value : count; | 71 | return (value < 0) ? value : count; |
72 | } | 72 | } |
@@ -81,7 +81,7 @@ static ssize_t show_##name(struct device *dev, \ | |||
81 | { \ | 81 | { \ |
82 | struct usb_device *udev; \ | 82 | struct usb_device *udev; \ |
83 | \ | 83 | \ |
84 | udev = to_usb_device (dev); \ | 84 | udev = to_usb_device(dev); \ |
85 | return sprintf(buf, "%s\n", udev->name); \ | 85 | return sprintf(buf, "%s\n", udev->name); \ |
86 | } \ | 86 | } \ |
87 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); | 87 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); |
@@ -91,12 +91,12 @@ usb_string_attr(manufacturer); | |||
91 | usb_string_attr(serial); | 91 | usb_string_attr(serial); |
92 | 92 | ||
93 | static ssize_t | 93 | static ssize_t |
94 | show_speed (struct device *dev, struct device_attribute *attr, char *buf) | 94 | show_speed(struct device *dev, struct device_attribute *attr, char *buf) |
95 | { | 95 | { |
96 | struct usb_device *udev; | 96 | struct usb_device *udev; |
97 | char *speed; | 97 | char *speed; |
98 | 98 | ||
99 | udev = to_usb_device (dev); | 99 | udev = to_usb_device(dev); |
100 | 100 | ||
101 | switch (udev->speed) { | 101 | switch (udev->speed) { |
102 | case USB_SPEED_LOW: | 102 | case USB_SPEED_LOW: |
@@ -112,22 +112,22 @@ show_speed (struct device *dev, struct device_attribute *attr, char *buf) | |||
112 | default: | 112 | default: |
113 | speed = "unknown"; | 113 | speed = "unknown"; |
114 | } | 114 | } |
115 | return sprintf (buf, "%s\n", speed); | 115 | return sprintf(buf, "%s\n", speed); |
116 | } | 116 | } |
117 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); | 117 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); |
118 | 118 | ||
119 | static ssize_t | 119 | static ssize_t |
120 | show_devnum (struct device *dev, struct device_attribute *attr, char *buf) | 120 | show_devnum(struct device *dev, struct device_attribute *attr, char *buf) |
121 | { | 121 | { |
122 | struct usb_device *udev; | 122 | struct usb_device *udev; |
123 | 123 | ||
124 | udev = to_usb_device (dev); | 124 | udev = to_usb_device(dev); |
125 | return sprintf (buf, "%d\n", udev->devnum); | 125 | return sprintf(buf, "%d\n", udev->devnum); |
126 | } | 126 | } |
127 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); | 127 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); |
128 | 128 | ||
129 | static ssize_t | 129 | static ssize_t |
130 | show_version (struct device *dev, struct device_attribute *attr, char *buf) | 130 | show_version(struct device *dev, struct device_attribute *attr, char *buf) |
131 | { | 131 | { |
132 | struct usb_device *udev; | 132 | struct usb_device *udev; |
133 | u16 bcdUSB; | 133 | u16 bcdUSB; |
@@ -139,25 +139,25 @@ show_version (struct device *dev, struct device_attribute *attr, char *buf) | |||
139 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | 139 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); |
140 | 140 | ||
141 | static ssize_t | 141 | static ssize_t |
142 | show_maxchild (struct device *dev, struct device_attribute *attr, char *buf) | 142 | show_maxchild(struct device *dev, struct device_attribute *attr, char *buf) |
143 | { | 143 | { |
144 | struct usb_device *udev; | 144 | struct usb_device *udev; |
145 | 145 | ||
146 | udev = to_usb_device (dev); | 146 | udev = to_usb_device(dev); |
147 | return sprintf (buf, "%d\n", udev->maxchild); | 147 | return sprintf(buf, "%d\n", udev->maxchild); |
148 | } | 148 | } |
149 | static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); | 149 | static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); |
150 | 150 | ||
151 | /* Descriptor fields */ | 151 | /* Descriptor fields */ |
152 | #define usb_descriptor_attr_le16(field, format_string) \ | 152 | #define usb_descriptor_attr_le16(field, format_string) \ |
153 | static ssize_t \ | 153 | static ssize_t \ |
154 | show_##field (struct device *dev, struct device_attribute *attr, \ | 154 | show_##field(struct device *dev, struct device_attribute *attr, \ |
155 | char *buf) \ | 155 | char *buf) \ |
156 | { \ | 156 | { \ |
157 | struct usb_device *udev; \ | 157 | struct usb_device *udev; \ |
158 | \ | 158 | \ |
159 | udev = to_usb_device (dev); \ | 159 | udev = to_usb_device(dev); \ |
160 | return sprintf (buf, format_string, \ | 160 | return sprintf(buf, format_string, \ |
161 | le16_to_cpu(udev->descriptor.field)); \ | 161 | le16_to_cpu(udev->descriptor.field)); \ |
162 | } \ | 162 | } \ |
163 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 163 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
@@ -168,21 +168,21 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") | |||
168 | 168 | ||
169 | #define usb_descriptor_attr(field, format_string) \ | 169 | #define usb_descriptor_attr(field, format_string) \ |
170 | static ssize_t \ | 170 | static ssize_t \ |
171 | show_##field (struct device *dev, struct device_attribute *attr, \ | 171 | show_##field(struct device *dev, struct device_attribute *attr, \ |
172 | char *buf) \ | 172 | char *buf) \ |
173 | { \ | 173 | { \ |
174 | struct usb_device *udev; \ | 174 | struct usb_device *udev; \ |
175 | \ | 175 | \ |
176 | udev = to_usb_device (dev); \ | 176 | udev = to_usb_device(dev); \ |
177 | return sprintf (buf, format_string, udev->descriptor.field); \ | 177 | return sprintf(buf, format_string, udev->descriptor.field); \ |
178 | } \ | 178 | } \ |
179 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 179 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
180 | 180 | ||
181 | usb_descriptor_attr (bDeviceClass, "%02x\n") | 181 | usb_descriptor_attr(bDeviceClass, "%02x\n") |
182 | usb_descriptor_attr (bDeviceSubClass, "%02x\n") | 182 | usb_descriptor_attr(bDeviceSubClass, "%02x\n") |
183 | usb_descriptor_attr (bDeviceProtocol, "%02x\n") | 183 | usb_descriptor_attr(bDeviceProtocol, "%02x\n") |
184 | usb_descriptor_attr (bNumConfigurations, "%d\n") | 184 | usb_descriptor_attr(bNumConfigurations, "%d\n") |
185 | usb_descriptor_attr (bMaxPacketSize0, "%d\n") | 185 | usb_descriptor_attr(bMaxPacketSize0, "%d\n") |
186 | 186 | ||
187 | static struct attribute *dev_attrs[] = { | 187 | static struct attribute *dev_attrs[] = { |
188 | /* current configuration's attributes */ | 188 | /* current configuration's attributes */ |
@@ -220,17 +220,17 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) | |||
220 | return retval; | 220 | return retval; |
221 | 221 | ||
222 | if (udev->manufacturer) { | 222 | if (udev->manufacturer) { |
223 | retval = device_create_file (dev, &dev_attr_manufacturer); | 223 | retval = device_create_file(dev, &dev_attr_manufacturer); |
224 | if (retval) | 224 | if (retval) |
225 | goto error; | 225 | goto error; |
226 | } | 226 | } |
227 | if (udev->product) { | 227 | if (udev->product) { |
228 | retval = device_create_file (dev, &dev_attr_product); | 228 | retval = device_create_file(dev, &dev_attr_product); |
229 | if (retval) | 229 | if (retval) |
230 | goto error; | 230 | goto error; |
231 | } | 231 | } |
232 | if (udev->serial) { | 232 | if (udev->serial) { |
233 | retval = device_create_file (dev, &dev_attr_serial); | 233 | retval = device_create_file(dev, &dev_attr_serial); |
234 | if (retval) | 234 | if (retval) |
235 | goto error; | 235 | goto error; |
236 | } | 236 | } |
@@ -246,7 +246,7 @@ error: | |||
246 | return retval; | 246 | return retval; |
247 | } | 247 | } |
248 | 248 | ||
249 | void usb_remove_sysfs_dev_files (struct usb_device *udev) | 249 | void usb_remove_sysfs_dev_files(struct usb_device *udev) |
250 | { | 250 | { |
251 | struct device *dev = &udev->dev; | 251 | struct device *dev = &udev->dev; |
252 | 252 | ||
@@ -264,22 +264,22 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) | |||
264 | /* Interface fields */ | 264 | /* Interface fields */ |
265 | #define usb_intf_attr(field, format_string) \ | 265 | #define usb_intf_attr(field, format_string) \ |
266 | static ssize_t \ | 266 | static ssize_t \ |
267 | show_##field (struct device *dev, struct device_attribute *attr, \ | 267 | show_##field(struct device *dev, struct device_attribute *attr, \ |
268 | char *buf) \ | 268 | char *buf) \ |
269 | { \ | 269 | { \ |
270 | struct usb_interface *intf = to_usb_interface (dev); \ | 270 | struct usb_interface *intf = to_usb_interface(dev); \ |
271 | \ | 271 | \ |
272 | return sprintf (buf, format_string, \ | 272 | return sprintf(buf, format_string, \ |
273 | intf->cur_altsetting->desc.field); \ | 273 | intf->cur_altsetting->desc.field); \ |
274 | } \ | 274 | } \ |
275 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 275 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
276 | 276 | ||
277 | usb_intf_attr (bInterfaceNumber, "%02x\n") | 277 | usb_intf_attr(bInterfaceNumber, "%02x\n") |
278 | usb_intf_attr (bAlternateSetting, "%2d\n") | 278 | usb_intf_attr(bAlternateSetting, "%2d\n") |
279 | usb_intf_attr (bNumEndpoints, "%02x\n") | 279 | usb_intf_attr(bNumEndpoints, "%02x\n") |
280 | usb_intf_attr (bInterfaceClass, "%02x\n") | 280 | usb_intf_attr(bInterfaceClass, "%02x\n") |
281 | usb_intf_attr (bInterfaceSubClass, "%02x\n") | 281 | usb_intf_attr(bInterfaceSubClass, "%02x\n") |
282 | usb_intf_attr (bInterfaceProtocol, "%02x\n") | 282 | usb_intf_attr(bInterfaceProtocol, "%02x\n") |
283 | 283 | ||
284 | static ssize_t show_interface_string(struct device *dev, | 284 | static ssize_t show_interface_string(struct device *dev, |
285 | struct device_attribute *attr, char *buf) | 285 | struct device_attribute *attr, char *buf) |
@@ -288,8 +288,8 @@ static ssize_t show_interface_string(struct device *dev, | |||
288 | struct usb_device *udev; | 288 | struct usb_device *udev; |
289 | int len; | 289 | int len; |
290 | 290 | ||
291 | intf = to_usb_interface (dev); | 291 | intf = to_usb_interface(dev); |
292 | udev = interface_to_usbdev (intf); | 292 | udev = interface_to_usbdev(intf); |
293 | len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); | 293 | len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); |
294 | if (len < 0) | 294 | if (len < 0) |
295 | return 0; | 295 | return 0; |
@@ -384,7 +384,7 @@ error: | |||
384 | return retval; | 384 | return retval; |
385 | } | 385 | } |
386 | 386 | ||
387 | void usb_remove_sysfs_intf_files (struct usb_interface *intf) | 387 | void usb_remove_sysfs_intf_files(struct usb_interface *intf) |
388 | { | 388 | { |
389 | usb_remove_intf_ep_files(intf); | 389 | usb_remove_intf_ep_files(intf); |
390 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); | 390 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 9801d08edacf..94ea9727ff55 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -235,16 +235,15 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
235 | 235 | ||
236 | urb->status = -EINPROGRESS; | 236 | urb->status = -EINPROGRESS; |
237 | urb->actual_length = 0; | 237 | urb->actual_length = 0; |
238 | urb->bandwidth = 0; | ||
239 | 238 | ||
240 | /* Lots of sanity checks, so HCDs can rely on clean data | 239 | /* Lots of sanity checks, so HCDs can rely on clean data |
241 | * and don't need to duplicate tests | 240 | * and don't need to duplicate tests |
242 | */ | 241 | */ |
243 | pipe = urb->pipe; | 242 | pipe = urb->pipe; |
244 | temp = usb_pipetype (pipe); | 243 | temp = usb_pipetype(pipe); |
245 | is_out = usb_pipeout (pipe); | 244 | is_out = usb_pipeout(pipe); |
246 | 245 | ||
247 | if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED) | 246 | if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED) |
248 | return -ENODEV; | 247 | return -ENODEV; |
249 | 248 | ||
250 | /* FIXME there should be a sharable lock protecting us against | 249 | /* FIXME there should be a sharable lock protecting us against |
@@ -253,11 +252,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
253 | * checks get made.) | 252 | * checks get made.) |
254 | */ | 253 | */ |
255 | 254 | ||
256 | max = usb_maxpacket (dev, pipe, is_out); | 255 | max = usb_maxpacket(dev, pipe, is_out); |
257 | if (max <= 0) { | 256 | if (max <= 0) { |
258 | dev_dbg(&dev->dev, | 257 | dev_dbg(&dev->dev, |
259 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", | 258 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", |
260 | usb_pipeendpoint (pipe), is_out ? "out" : "in", | 259 | usb_pipeendpoint(pipe), is_out ? "out" : "in", |
261 | __FUNCTION__, max); | 260 | __FUNCTION__, max); |
262 | return -EMSGSIZE; | 261 | return -EMSGSIZE; |
263 | } | 262 | } |
@@ -279,11 +278,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
279 | if (urb->number_of_packets <= 0) | 278 | if (urb->number_of_packets <= 0) |
280 | return -EINVAL; | 279 | return -EINVAL; |
281 | for (n = 0; n < urb->number_of_packets; n++) { | 280 | for (n = 0; n < urb->number_of_packets; n++) { |
282 | len = urb->iso_frame_desc [n].length; | 281 | len = urb->iso_frame_desc[n].length; |
283 | if (len < 0 || len > max) | 282 | if (len < 0 || len > max) |
284 | return -EMSGSIZE; | 283 | return -EMSGSIZE; |
285 | urb->iso_frame_desc [n].status = -EXDEV; | 284 | urb->iso_frame_desc[n].status = -EXDEV; |
286 | urb->iso_frame_desc [n].actual_length = 0; | 285 | urb->iso_frame_desc[n].actual_length = 0; |
287 | } | 286 | } |
288 | } | 287 | } |
289 | 288 | ||
@@ -322,7 +321,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
322 | 321 | ||
323 | /* fail if submitter gave bogus flags */ | 322 | /* fail if submitter gave bogus flags */ |
324 | if (urb->transfer_flags != orig_flags) { | 323 | if (urb->transfer_flags != orig_flags) { |
325 | err ("BOGUS urb flags, %x --> %x", | 324 | err("BOGUS urb flags, %x --> %x", |
326 | orig_flags, urb->transfer_flags); | 325 | orig_flags, urb->transfer_flags); |
327 | return -EINVAL; | 326 | return -EINVAL; |
328 | } | 327 | } |
@@ -373,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
373 | urb->interval = temp; | 372 | urb->interval = temp; |
374 | } | 373 | } |
375 | 374 | ||
376 | return usb_hcd_submit_urb (urb, mem_flags); | 375 | return usb_hcd_submit_urb(urb, mem_flags); |
377 | } | 376 | } |
378 | 377 | ||
379 | /*-------------------------------------------------------------------*/ | 378 | /*-------------------------------------------------------------------*/ |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 02426d0b9a34..3db721cd557a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -233,7 +233,7 @@ static void usb_autosuspend_work(struct work_struct *work) | |||
233 | * @parent: hub to which device is connected; null to allocate a root hub | 233 | * @parent: hub to which device is connected; null to allocate a root hub |
234 | * @bus: bus used to access the device | 234 | * @bus: bus used to access the device |
235 | * @port1: one-based index of port; ignored for root hubs | 235 | * @port1: one-based index of port; ignored for root hubs |
236 | * Context: !in_interrupt () | 236 | * Context: !in_interrupt() |
237 | * | 237 | * |
238 | * Only hub drivers (including virtual root hub drivers for host | 238 | * Only hub drivers (including virtual root hub drivers for host |
239 | * controllers) should ever call this. | 239 | * controllers) should ever call this. |
@@ -277,22 +277,22 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
277 | * as stable: bus->busnum changes easily from modprobe order, | 277 | * as stable: bus->busnum changes easily from modprobe order, |
278 | * cardbus or pci hotplugging, and so on. | 278 | * cardbus or pci hotplugging, and so on. |
279 | */ | 279 | */ |
280 | if (unlikely (!parent)) { | 280 | if (unlikely(!parent)) { |
281 | dev->devpath [0] = '0'; | 281 | dev->devpath[0] = '0'; |
282 | 282 | ||
283 | dev->dev.parent = bus->controller; | 283 | dev->dev.parent = bus->controller; |
284 | sprintf (&dev->dev.bus_id[0], "usb%d", bus->busnum); | 284 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); |
285 | } else { | 285 | } else { |
286 | /* match any labeling on the hubs; it's one-based */ | 286 | /* match any labeling on the hubs; it's one-based */ |
287 | if (parent->devpath [0] == '0') | 287 | if (parent->devpath[0] == '0') |
288 | snprintf (dev->devpath, sizeof dev->devpath, | 288 | snprintf(dev->devpath, sizeof dev->devpath, |
289 | "%d", port1); | 289 | "%d", port1); |
290 | else | 290 | else |
291 | snprintf (dev->devpath, sizeof dev->devpath, | 291 | snprintf(dev->devpath, sizeof dev->devpath, |
292 | "%s.%d", parent->devpath, port1); | 292 | "%s.%d", parent->devpath, port1); |
293 | 293 | ||
294 | dev->dev.parent = &parent->dev; | 294 | dev->dev.parent = &parent->dev; |
295 | sprintf (&dev->dev.bus_id[0], "%d-%s", | 295 | sprintf(&dev->dev.bus_id[0], "%d-%s", |
296 | bus->busnum, dev->devpath); | 296 | bus->busnum, dev->devpath); |
297 | 297 | ||
298 | /* hub driver sets up TT records */ | 298 | /* hub driver sets up TT records */ |
@@ -463,7 +463,7 @@ static struct usb_device *match_device(struct usb_device *dev, | |||
463 | /* see if this device matches */ | 463 | /* see if this device matches */ |
464 | if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) && | 464 | if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) && |
465 | (product_id == le16_to_cpu(dev->descriptor.idProduct))) { | 465 | (product_id == le16_to_cpu(dev->descriptor.idProduct))) { |
466 | dev_dbg (&dev->dev, "matched this device!\n"); | 466 | dev_dbg(&dev->dev, "matched this device!\n"); |
467 | ret_dev = usb_get_dev(dev); | 467 | ret_dev = usb_get_dev(dev); |
468 | goto exit; | 468 | goto exit; |
469 | } | 469 | } |
@@ -535,7 +535,7 @@ exit: | |||
535 | */ | 535 | */ |
536 | int usb_get_current_frame_number(struct usb_device *dev) | 536 | int usb_get_current_frame_number(struct usb_device *dev) |
537 | { | 537 | { |
538 | return usb_hcd_get_frame_number (dev); | 538 | return usb_hcd_get_frame_number(dev); |
539 | } | 539 | } |
540 | 540 | ||
541 | /*-------------------------------------------------------------------*/ | 541 | /*-------------------------------------------------------------------*/ |
@@ -593,7 +593,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
593 | * | 593 | * |
594 | * When the buffer is no longer used, free it with usb_buffer_free(). | 594 | * When the buffer is no longer used, free it with usb_buffer_free(). |
595 | */ | 595 | */ |
596 | void *usb_buffer_alloc ( | 596 | void *usb_buffer_alloc( |
597 | struct usb_device *dev, | 597 | struct usb_device *dev, |
598 | size_t size, | 598 | size_t size, |
599 | gfp_t mem_flags, | 599 | gfp_t mem_flags, |
@@ -602,7 +602,7 @@ void *usb_buffer_alloc ( | |||
602 | { | 602 | { |
603 | if (!dev || !dev->bus) | 603 | if (!dev || !dev->bus) |
604 | return NULL; | 604 | return NULL; |
605 | return hcd_buffer_alloc (dev->bus, size, mem_flags, dma); | 605 | return hcd_buffer_alloc(dev->bus, size, mem_flags, dma); |
606 | } | 606 | } |
607 | 607 | ||
608 | /** | 608 | /** |
@@ -616,7 +616,7 @@ void *usb_buffer_alloc ( | |||
616 | * been allocated using usb_buffer_alloc(), and the parameters must match | 616 | * been allocated using usb_buffer_alloc(), and the parameters must match |
617 | * those provided in that allocation request. | 617 | * those provided in that allocation request. |
618 | */ | 618 | */ |
619 | void usb_buffer_free ( | 619 | void usb_buffer_free( |
620 | struct usb_device *dev, | 620 | struct usb_device *dev, |
621 | size_t size, | 621 | size_t size, |
622 | void *addr, | 622 | void *addr, |
@@ -627,7 +627,7 @@ void usb_buffer_free ( | |||
627 | return; | 627 | return; |
628 | if (!addr) | 628 | if (!addr) |
629 | return; | 629 | return; |
630 | hcd_buffer_free (dev->bus, size, addr, dma); | 630 | hcd_buffer_free(dev->bus, size, addr, dma); |
631 | } | 631 | } |
632 | 632 | ||
633 | /** | 633 | /** |
@@ -647,7 +647,7 @@ void usb_buffer_free ( | |||
647 | * Reverse the effect of this call with usb_buffer_unmap(). | 647 | * Reverse the effect of this call with usb_buffer_unmap(). |
648 | */ | 648 | */ |
649 | #if 0 | 649 | #if 0 |
650 | struct urb *usb_buffer_map (struct urb *urb) | 650 | struct urb *usb_buffer_map(struct urb *urb) |
651 | { | 651 | { |
652 | struct usb_bus *bus; | 652 | struct usb_bus *bus; |
653 | struct device *controller; | 653 | struct device *controller; |
@@ -659,14 +659,14 @@ struct urb *usb_buffer_map (struct urb *urb) | |||
659 | return NULL; | 659 | return NULL; |
660 | 660 | ||
661 | if (controller->dma_mask) { | 661 | if (controller->dma_mask) { |
662 | urb->transfer_dma = dma_map_single (controller, | 662 | urb->transfer_dma = dma_map_single(controller, |
663 | urb->transfer_buffer, urb->transfer_buffer_length, | 663 | urb->transfer_buffer, urb->transfer_buffer_length, |
664 | usb_pipein (urb->pipe) | 664 | usb_pipein(urb->pipe) |
665 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 665 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
666 | if (usb_pipecontrol (urb->pipe)) | 666 | if (usb_pipecontrol(urb->pipe)) |
667 | urb->setup_dma = dma_map_single (controller, | 667 | urb->setup_dma = dma_map_single(controller, |
668 | urb->setup_packet, | 668 | urb->setup_packet, |
669 | sizeof (struct usb_ctrlrequest), | 669 | sizeof(struct usb_ctrlrequest), |
670 | DMA_TO_DEVICE); | 670 | DMA_TO_DEVICE); |
671 | // FIXME generic api broken like pci, can't report errors | 671 | // FIXME generic api broken like pci, can't report errors |
672 | // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; | 672 | // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; |
@@ -689,7 +689,7 @@ struct urb *usb_buffer_map (struct urb *urb) | |||
689 | * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) | 689 | * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) |
690 | * @urb: urb whose transfer_buffer/setup_packet will be synchronized | 690 | * @urb: urb whose transfer_buffer/setup_packet will be synchronized |
691 | */ | 691 | */ |
692 | void usb_buffer_dmasync (struct urb *urb) | 692 | void usb_buffer_dmasync(struct urb *urb) |
693 | { | 693 | { |
694 | struct usb_bus *bus; | 694 | struct usb_bus *bus; |
695 | struct device *controller; | 695 | struct device *controller; |
@@ -702,14 +702,14 @@ void usb_buffer_dmasync (struct urb *urb) | |||
702 | return; | 702 | return; |
703 | 703 | ||
704 | if (controller->dma_mask) { | 704 | if (controller->dma_mask) { |
705 | dma_sync_single (controller, | 705 | dma_sync_single(controller, |
706 | urb->transfer_dma, urb->transfer_buffer_length, | 706 | urb->transfer_dma, urb->transfer_buffer_length, |
707 | usb_pipein (urb->pipe) | 707 | usb_pipein(urb->pipe) |
708 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 708 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
709 | if (usb_pipecontrol (urb->pipe)) | 709 | if (usb_pipecontrol(urb->pipe)) |
710 | dma_sync_single (controller, | 710 | dma_sync_single(controller, |
711 | urb->setup_dma, | 711 | urb->setup_dma, |
712 | sizeof (struct usb_ctrlrequest), | 712 | sizeof(struct usb_ctrlrequest), |
713 | DMA_TO_DEVICE); | 713 | DMA_TO_DEVICE); |
714 | } | 714 | } |
715 | } | 715 | } |
@@ -722,7 +722,7 @@ void usb_buffer_dmasync (struct urb *urb) | |||
722 | * Reverses the effect of usb_buffer_map(). | 722 | * Reverses the effect of usb_buffer_map(). |
723 | */ | 723 | */ |
724 | #if 0 | 724 | #if 0 |
725 | void usb_buffer_unmap (struct urb *urb) | 725 | void usb_buffer_unmap(struct urb *urb) |
726 | { | 726 | { |
727 | struct usb_bus *bus; | 727 | struct usb_bus *bus; |
728 | struct device *controller; | 728 | struct device *controller; |
@@ -735,14 +735,14 @@ void usb_buffer_unmap (struct urb *urb) | |||
735 | return; | 735 | return; |
736 | 736 | ||
737 | if (controller->dma_mask) { | 737 | if (controller->dma_mask) { |
738 | dma_unmap_single (controller, | 738 | dma_unmap_single(controller, |
739 | urb->transfer_dma, urb->transfer_buffer_length, | 739 | urb->transfer_dma, urb->transfer_buffer_length, |
740 | usb_pipein (urb->pipe) | 740 | usb_pipein(urb->pipe) |
741 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 741 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
742 | if (usb_pipecontrol (urb->pipe)) | 742 | if (usb_pipecontrol(urb->pipe)) |
743 | dma_unmap_single (controller, | 743 | dma_unmap_single(controller, |
744 | urb->setup_dma, | 744 | urb->setup_dma, |
745 | sizeof (struct usb_ctrlrequest), | 745 | sizeof(struct usb_ctrlrequest), |
746 | DMA_TO_DEVICE); | 746 | DMA_TO_DEVICE); |
747 | } | 747 | } |
748 | urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP | 748 | urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP |
@@ -783,15 +783,15 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
783 | struct device *controller; | 783 | struct device *controller; |
784 | 784 | ||
785 | if (!dev | 785 | if (!dev |
786 | || usb_pipecontrol (pipe) | 786 | || usb_pipecontrol(pipe) |
787 | || !(bus = dev->bus) | 787 | || !(bus = dev->bus) |
788 | || !(controller = bus->controller) | 788 | || !(controller = bus->controller) |
789 | || !controller->dma_mask) | 789 | || !controller->dma_mask) |
790 | return -1; | 790 | return -1; |
791 | 791 | ||
792 | // FIXME generic api broken like pci, can't report errors | 792 | // FIXME generic api broken like pci, can't report errors |
793 | return dma_map_sg (controller, sg, nents, | 793 | return dma_map_sg(controller, sg, nents, |
794 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 794 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
795 | } | 795 | } |
796 | 796 | ||
797 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 797 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
@@ -823,8 +823,8 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | |||
823 | || !controller->dma_mask) | 823 | || !controller->dma_mask) |
824 | return; | 824 | return; |
825 | 825 | ||
826 | dma_sync_sg (controller, sg, n_hw_ents, | 826 | dma_sync_sg(controller, sg, n_hw_ents, |
827 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 827 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
828 | } | 828 | } |
829 | #endif | 829 | #endif |
830 | 830 | ||
@@ -849,8 +849,8 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | |||
849 | || !controller->dma_mask) | 849 | || !controller->dma_mask) |
850 | return; | 850 | return; |
851 | 851 | ||
852 | dma_unmap_sg (controller, sg, n_hw_ents, | 852 | dma_unmap_sg(controller, sg, n_hw_ents, |
853 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 853 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
854 | } | 854 | } |
855 | 855 | ||
856 | /* format to disable USB on kernel command line is: nousb */ | 856 | /* format to disable USB on kernel command line is: nousb */ |
@@ -871,7 +871,7 @@ static int __init usb_init(void) | |||
871 | { | 871 | { |
872 | int retval; | 872 | int retval; |
873 | if (nousb) { | 873 | if (nousb) { |
874 | pr_info ("%s: USB support disabled\n", usbcore_name); | 874 | pr_info("%s: USB support disabled\n", usbcore_name); |
875 | return 0; | 875 | return 0; |
876 | } | 876 | } |
877 | 877 | ||
@@ -971,19 +971,19 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor); | |||
971 | EXPORT_SYMBOL(usb_find_device); | 971 | EXPORT_SYMBOL(usb_find_device); |
972 | EXPORT_SYMBOL(usb_get_current_frame_number); | 972 | EXPORT_SYMBOL(usb_get_current_frame_number); |
973 | 973 | ||
974 | EXPORT_SYMBOL (usb_buffer_alloc); | 974 | EXPORT_SYMBOL(usb_buffer_alloc); |
975 | EXPORT_SYMBOL (usb_buffer_free); | 975 | EXPORT_SYMBOL(usb_buffer_free); |
976 | 976 | ||
977 | #if 0 | 977 | #if 0 |
978 | EXPORT_SYMBOL (usb_buffer_map); | 978 | EXPORT_SYMBOL(usb_buffer_map); |
979 | EXPORT_SYMBOL (usb_buffer_dmasync); | 979 | EXPORT_SYMBOL(usb_buffer_dmasync); |
980 | EXPORT_SYMBOL (usb_buffer_unmap); | 980 | EXPORT_SYMBOL(usb_buffer_unmap); |
981 | #endif | 981 | #endif |
982 | 982 | ||
983 | EXPORT_SYMBOL (usb_buffer_map_sg); | 983 | EXPORT_SYMBOL(usb_buffer_map_sg); |
984 | #if 0 | 984 | #if 0 |
985 | EXPORT_SYMBOL (usb_buffer_dmasync_sg); | 985 | EXPORT_SYMBOL(usb_buffer_dmasync_sg); |
986 | #endif | 986 | #endif |
987 | EXPORT_SYMBOL (usb_buffer_unmap_sg); | 987 | EXPORT_SYMBOL(usb_buffer_unmap_sg); |
988 | 988 | ||
989 | MODULE_LICENSE("GPL"); | 989 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 812c733ba8ce..f39050145f1f 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/clk.h> | 41 | #include <linux/clk.h> |
42 | #include <linux/usb_ch9.h> | 42 | #include <linux/usb/ch9.h> |
43 | #include <linux/usb_gadget.h> | 43 | #include <linux/usb_gadget.h> |
44 | 44 | ||
45 | #include <asm/byteorder.h> | 45 | #include <asm/byteorder.h> |
@@ -1807,16 +1807,13 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1807 | || !wake | 1807 | || !wake |
1808 | || at91_suspend_entering_slow_clock()) { | 1808 | || at91_suspend_entering_slow_clock()) { |
1809 | pullup(udc, 0); | 1809 | pullup(udc, 0); |
1810 | disable_irq_wake(udc->udp_irq); | 1810 | wake = 0; |
1811 | } else | 1811 | } else |
1812 | enable_irq_wake(udc->udp_irq); | 1812 | enable_irq_wake(udc->udp_irq); |
1813 | 1813 | ||
1814 | if (udc->board.vbus_pin > 0) { | 1814 | udc->active_suspend = wake; |
1815 | if (wake) | 1815 | if (udc->board.vbus_pin > 0 && wake) |
1816 | enable_irq_wake(udc->board.vbus_pin); | 1816 | enable_irq_wake(udc->board.vbus_pin); |
1817 | else | ||
1818 | disable_irq_wake(udc->board.vbus_pin); | ||
1819 | } | ||
1820 | return 0; | 1817 | return 0; |
1821 | } | 1818 | } |
1822 | 1819 | ||
@@ -1824,8 +1821,14 @@ static int at91udc_resume(struct platform_device *pdev) | |||
1824 | { | 1821 | { |
1825 | struct at91_udc *udc = platform_get_drvdata(pdev); | 1822 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1826 | 1823 | ||
1824 | if (udc->board.vbus_pin > 0 && udc->active_suspend) | ||
1825 | disable_irq_wake(udc->board.vbus_pin); | ||
1826 | |||
1827 | /* maybe reconnect to host; if so, clocks on */ | 1827 | /* maybe reconnect to host; if so, clocks on */ |
1828 | pullup(udc, 1); | 1828 | if (udc->active_suspend) |
1829 | disable_irq_wake(udc->udp_irq); | ||
1830 | else | ||
1831 | pullup(udc, 1); | ||
1829 | return 0; | 1832 | return 0; |
1830 | } | 1833 | } |
1831 | #else | 1834 | #else |
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 677089baa59d..7e34e2f864f9 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -136,6 +136,7 @@ struct at91_udc { | |||
136 | unsigned wait_for_addr_ack:1; | 136 | unsigned wait_for_addr_ack:1; |
137 | unsigned wait_for_config_ack:1; | 137 | unsigned wait_for_config_ack:1; |
138 | unsigned selfpowered:1; | 138 | unsigned selfpowered:1; |
139 | unsigned active_suspend:1; | ||
139 | u8 addr; | 140 | u8 addr; |
140 | struct at91_udc_data board; | 141 | struct at91_udc_data board; |
141 | struct clk *iclk, *fclk; | 142 | struct clk *iclk, *fclk; |
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 83b4866df9af..d18901b92cda 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | 26 | ||
27 | #include <linux/usb_ch9.h> | 27 | #include <linux/usb/ch9.h> |
28 | #include <linux/usb_gadget.h> | 28 | #include <linux/usb_gadget.h> |
29 | 29 | ||
30 | 30 | ||
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 53d584589c26..f28af06905a5 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | 29 | ||
30 | #include <linux/usb_ch9.h> | 30 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb_gadget.h> | 31 | #include <linux/usb_gadget.h> |
32 | 32 | ||
33 | #include "gadget_chips.h" | 33 | #include "gadget_chips.h" |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index d15bf22b9a03..22e3c9443641 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | #include <asm/unaligned.h> | 48 | #include <asm/unaligned.h> |
49 | 49 | ||
50 | #include <linux/usb_ch9.h> | 50 | #include <linux/usb/ch9.h> |
51 | #include <linux/usb/cdc.h> | 51 | #include <linux/usb/cdc.h> |
52 | #include <linux/usb_gadget.h> | 52 | #include <linux/usb_gadget.h> |
53 | 53 | ||
@@ -72,9 +72,18 @@ | |||
72 | * | 72 | * |
73 | * There's some hardware that can't talk CDC. We make that hardware | 73 | * There's some hardware that can't talk CDC. We make that hardware |
74 | * implement a "minimalist" vendor-agnostic CDC core: same framing, but | 74 | * implement a "minimalist" vendor-agnostic CDC core: same framing, but |
75 | * link-level setup only requires activating the configuration. | 75 | * link-level setup only requires activating the configuration. Only the |
76 | * Linux supports it, but other host operating systems may not. | 76 | * endpoint descriptors, and product/vendor IDs, are relevant; no control |
77 | * (This is a subset of CDC Ethernet.) | 77 | * operations are available. Linux supports it, but other host operating |
78 | * systems may not. (This is a subset of CDC Ethernet.) | ||
79 | * | ||
80 | * It turns out that if you add a few descriptors to that "CDC Subset", | ||
81 | * (Windows) host side drivers from MCCI can treat it as one submode of | ||
82 | * a proprietary scheme called "SAFE" ... without needing to know about | ||
83 | * specific product/vendor IDs. So we do that, making it easier to use | ||
84 | * those MS-Windows drivers. Those added descriptors make it resemble a | ||
85 | * CDC MDLM device, but they don't change device behavior at all. (See | ||
86 | * MCCI Engineering report 950198 "SAFE Networking Functions".) | ||
78 | * | 87 | * |
79 | * A third option is also in use. Rather than CDC Ethernet, or something | 88 | * A third option is also in use. Rather than CDC Ethernet, or something |
80 | * simpler, Microsoft pushes their own approach: RNDIS. The published | 89 | * simpler, Microsoft pushes their own approach: RNDIS. The published |
@@ -254,6 +263,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
254 | #define DEV_CONFIG_CDC | 263 | #define DEV_CONFIG_CDC |
255 | #endif | 264 | #endif |
256 | 265 | ||
266 | #ifdef CONFIG_USB_GADGET_S3C2410 | ||
267 | #define DEV_CONFIG_CDC | ||
268 | #endif | ||
269 | |||
257 | #ifdef CONFIG_USB_GADGET_AT91 | 270 | #ifdef CONFIG_USB_GADGET_AT91 |
258 | #define DEV_CONFIG_CDC | 271 | #define DEV_CONFIG_CDC |
259 | #endif | 272 | #endif |
@@ -266,6 +279,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
266 | #define DEV_CONFIG_CDC | 279 | #define DEV_CONFIG_CDC |
267 | #endif | 280 | #endif |
268 | 281 | ||
282 | #ifdef CONFIG_USB_GADGET_HUSB2DEV | ||
283 | #define DEV_CONFIG_CDC | ||
284 | #endif | ||
285 | |||
269 | 286 | ||
270 | /* For CDC-incapable hardware, choose the simple cdc subset. | 287 | /* For CDC-incapable hardware, choose the simple cdc subset. |
271 | * Anything that talks bulk (without notable bugs) can do this. | 288 | * Anything that talks bulk (without notable bugs) can do this. |
@@ -283,9 +300,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
283 | #define DEV_CONFIG_SUBSET | 300 | #define DEV_CONFIG_SUBSET |
284 | #endif | 301 | #endif |
285 | 302 | ||
286 | #ifdef CONFIG_USB_GADGET_S3C2410 | ||
287 | #define DEV_CONFIG_CDC | ||
288 | #endif | ||
289 | 303 | ||
290 | /*-------------------------------------------------------------------------*/ | 304 | /*-------------------------------------------------------------------------*/ |
291 | 305 | ||
@@ -487,8 +501,17 @@ rndis_config = { | |||
487 | * endpoint. Both have a "data" interface and two bulk endpoints. | 501 | * endpoint. Both have a "data" interface and two bulk endpoints. |
488 | * There are also differences in how control requests are handled. | 502 | * There are also differences in how control requests are handled. |
489 | * | 503 | * |
490 | * RNDIS shares a lot with CDC-Ethernet, since it's a variant of | 504 | * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the |
491 | * the CDC-ACM (modem) spec. | 505 | * CDC-ACM (modem) spec. Unfortunately MSFT's RNDIS driver is buggy; it |
506 | * may hang or oops. Since bugfixes (or accurate specs, letting Linux | ||
507 | * work around those bugs) are unlikely to ever come from MSFT, you may | ||
508 | * wish to avoid using RNDIS. | ||
509 | * | ||
510 | * MCCI offers an alternative to RNDIS if you need to connect to Windows | ||
511 | * but have hardware that can't support CDC Ethernet. We add descriptors | ||
512 | * to present the CDC Subset as a (nonconformant) CDC MDLM variant called | ||
513 | * "SAFE". That borrows from both CDC Ethernet and CDC MDLM. You can | ||
514 | * get those drivers from MCCI, or bundled with various products. | ||
492 | */ | 515 | */ |
493 | 516 | ||
494 | #ifdef DEV_CONFIG_CDC | 517 | #ifdef DEV_CONFIG_CDC |
@@ -522,8 +545,6 @@ rndis_control_intf = { | |||
522 | }; | 545 | }; |
523 | #endif | 546 | #endif |
524 | 547 | ||
525 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
526 | |||
527 | static const struct usb_cdc_header_desc header_desc = { | 548 | static const struct usb_cdc_header_desc header_desc = { |
528 | .bLength = sizeof header_desc, | 549 | .bLength = sizeof header_desc, |
529 | .bDescriptorType = USB_DT_CS_INTERFACE, | 550 | .bDescriptorType = USB_DT_CS_INTERFACE, |
@@ -532,6 +553,8 @@ static const struct usb_cdc_header_desc header_desc = { | |||
532 | .bcdCDC = __constant_cpu_to_le16 (0x0110), | 553 | .bcdCDC = __constant_cpu_to_le16 (0x0110), |
533 | }; | 554 | }; |
534 | 555 | ||
556 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
557 | |||
535 | static const struct usb_cdc_union_desc union_desc = { | 558 | static const struct usb_cdc_union_desc union_desc = { |
536 | .bLength = sizeof union_desc, | 559 | .bLength = sizeof union_desc, |
537 | .bDescriptorType = USB_DT_CS_INTERFACE, | 560 | .bDescriptorType = USB_DT_CS_INTERFACE, |
@@ -564,7 +587,40 @@ static const struct usb_cdc_acm_descriptor acm_descriptor = { | |||
564 | 587 | ||
565 | #endif | 588 | #endif |
566 | 589 | ||
567 | #ifdef DEV_CONFIG_CDC | 590 | #ifndef DEV_CONFIG_CDC |
591 | |||
592 | /* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various | ||
593 | * ways: data endpoints live in the control interface, there's no data | ||
594 | * interface, and it's not used to talk to a cell phone radio. | ||
595 | */ | ||
596 | |||
597 | static const struct usb_cdc_mdlm_desc mdlm_desc = { | ||
598 | .bLength = sizeof mdlm_desc, | ||
599 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
600 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, | ||
601 | |||
602 | .bcdVersion = __constant_cpu_to_le16(0x0100), | ||
603 | .bGUID = { | ||
604 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, | ||
605 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, | ||
606 | }, | ||
607 | }; | ||
608 | |||
609 | /* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we | ||
610 | * can't really use its struct. All we do here is say that we're using | ||
611 | * the submode of "SAFE" which directly matches the CDC Subset. | ||
612 | */ | ||
613 | static const u8 mdlm_detail_desc[] = { | ||
614 | 6, | ||
615 | USB_DT_CS_INTERFACE, | ||
616 | USB_CDC_MDLM_DETAIL_TYPE, | ||
617 | |||
618 | 0, /* "SAFE" */ | ||
619 | 0, /* network control capabilities (none) */ | ||
620 | 0, /* network data capabilities ("raw" encapsulation) */ | ||
621 | }; | ||
622 | |||
623 | #endif | ||
568 | 624 | ||
569 | static const struct usb_cdc_ether_desc ether_desc = { | 625 | static const struct usb_cdc_ether_desc ether_desc = { |
570 | .bLength = sizeof ether_desc, | 626 | .bLength = sizeof ether_desc, |
@@ -579,7 +635,6 @@ static const struct usb_cdc_ether_desc ether_desc = { | |||
579 | .bNumberPowerFilters = 0, | 635 | .bNumberPowerFilters = 0, |
580 | }; | 636 | }; |
581 | 637 | ||
582 | #endif | ||
583 | 638 | ||
584 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | 639 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
585 | 640 | ||
@@ -672,6 +727,9 @@ rndis_data_intf = { | |||
672 | /* | 727 | /* |
673 | * "Simple" CDC-subset option is a simple vendor-neutral model that most | 728 | * "Simple" CDC-subset option is a simple vendor-neutral model that most |
674 | * full speed controllers can handle: one interface, two bulk endpoints. | 729 | * full speed controllers can handle: one interface, two bulk endpoints. |
730 | * | ||
731 | * To assist host side drivers, we fancy it up a bit, and add descriptors | ||
732 | * so some host side drivers will understand it as a "SAFE" variant. | ||
675 | */ | 733 | */ |
676 | 734 | ||
677 | static const struct usb_interface_descriptor | 735 | static const struct usb_interface_descriptor |
@@ -682,8 +740,8 @@ subset_data_intf = { | |||
682 | .bInterfaceNumber = 0, | 740 | .bInterfaceNumber = 0, |
683 | .bAlternateSetting = 0, | 741 | .bAlternateSetting = 0, |
684 | .bNumEndpoints = 2, | 742 | .bNumEndpoints = 2, |
685 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 743 | .bInterfaceClass = USB_CLASS_COMM, |
686 | .bInterfaceSubClass = 0, | 744 | .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, |
687 | .bInterfaceProtocol = 0, | 745 | .bInterfaceProtocol = 0, |
688 | .iInterface = STRING_DATA, | 746 | .iInterface = STRING_DATA, |
689 | }; | 747 | }; |
@@ -731,10 +789,15 @@ static const struct usb_descriptor_header *fs_eth_function [11] = { | |||
731 | static inline void __init fs_subset_descriptors(void) | 789 | static inline void __init fs_subset_descriptors(void) |
732 | { | 790 | { |
733 | #ifdef DEV_CONFIG_SUBSET | 791 | #ifdef DEV_CONFIG_SUBSET |
792 | /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ | ||
734 | fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; | 793 | fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; |
735 | fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; | 794 | fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; |
736 | fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; | 795 | fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; |
737 | fs_eth_function[4] = NULL; | 796 | fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; |
797 | fs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; | ||
798 | fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc; | ||
799 | fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc; | ||
800 | fs_eth_function[8] = NULL; | ||
738 | #else | 801 | #else |
739 | fs_eth_function[1] = NULL; | 802 | fs_eth_function[1] = NULL; |
740 | #endif | 803 | #endif |
@@ -828,10 +891,15 @@ static const struct usb_descriptor_header *hs_eth_function [11] = { | |||
828 | static inline void __init hs_subset_descriptors(void) | 891 | static inline void __init hs_subset_descriptors(void) |
829 | { | 892 | { |
830 | #ifdef DEV_CONFIG_SUBSET | 893 | #ifdef DEV_CONFIG_SUBSET |
894 | /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ | ||
831 | hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; | 895 | hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; |
832 | hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; | 896 | hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; |
833 | hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; | 897 | hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; |
834 | hs_eth_function[4] = NULL; | 898 | hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; |
899 | hs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; | ||
900 | hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc; | ||
901 | hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc; | ||
902 | hs_eth_function[8] = NULL; | ||
835 | #else | 903 | #else |
836 | hs_eth_function[1] = NULL; | 904 | hs_eth_function[1] = NULL; |
837 | #endif | 905 | #endif |
@@ -878,10 +946,8 @@ static char manufacturer [50]; | |||
878 | static char product_desc [40] = DRIVER_DESC; | 946 | static char product_desc [40] = DRIVER_DESC; |
879 | static char serial_number [20]; | 947 | static char serial_number [20]; |
880 | 948 | ||
881 | #ifdef DEV_CONFIG_CDC | ||
882 | /* address that the host will use ... usually assigned at random */ | 949 | /* address that the host will use ... usually assigned at random */ |
883 | static char ethaddr [2 * ETH_ALEN + 1]; | 950 | static char ethaddr [2 * ETH_ALEN + 1]; |
884 | #endif | ||
885 | 951 | ||
886 | /* static strings, in UTF-8 */ | 952 | /* static strings, in UTF-8 */ |
887 | static struct usb_string strings [] = { | 953 | static struct usb_string strings [] = { |
@@ -889,9 +955,9 @@ static struct usb_string strings [] = { | |||
889 | { STRING_PRODUCT, product_desc, }, | 955 | { STRING_PRODUCT, product_desc, }, |
890 | { STRING_SERIALNUMBER, serial_number, }, | 956 | { STRING_SERIALNUMBER, serial_number, }, |
891 | { STRING_DATA, "Ethernet Data", }, | 957 | { STRING_DATA, "Ethernet Data", }, |
958 | { STRING_ETHADDR, ethaddr, }, | ||
892 | #ifdef DEV_CONFIG_CDC | 959 | #ifdef DEV_CONFIG_CDC |
893 | { STRING_CDC, "CDC Ethernet", }, | 960 | { STRING_CDC, "CDC Ethernet", }, |
894 | { STRING_ETHADDR, ethaddr, }, | ||
895 | { STRING_CONTROL, "CDC Communications Control", }, | 961 | { STRING_CONTROL, "CDC Communications Control", }, |
896 | #endif | 962 | #endif |
897 | #ifdef DEV_CONFIG_SUBSET | 963 | #ifdef DEV_CONFIG_SUBSET |
@@ -986,10 +1052,10 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags) | |||
986 | } | 1052 | } |
987 | #endif | 1053 | #endif |
988 | 1054 | ||
989 | dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); | 1055 | dev->in = ep_desc(gadget, &hs_source_desc, &fs_source_desc); |
990 | dev->in_ep->driver_data = dev; | 1056 | dev->in_ep->driver_data = dev; |
991 | 1057 | ||
992 | dev->out = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc); | 1058 | dev->out = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); |
993 | dev->out_ep->driver_data = dev; | 1059 | dev->out_ep->driver_data = dev; |
994 | 1060 | ||
995 | /* With CDC, the host isn't allowed to use these two data | 1061 | /* With CDC, the host isn't allowed to use these two data |
@@ -2278,10 +2344,10 @@ eth_bind (struct usb_gadget *gadget) | |||
2278 | "RNDIS/%s", driver_desc); | 2344 | "RNDIS/%s", driver_desc); |
2279 | 2345 | ||
2280 | /* CDC subset ... recognized by Linux since 2.4.10, but Windows | 2346 | /* CDC subset ... recognized by Linux since 2.4.10, but Windows |
2281 | * drivers aren't widely available. | 2347 | * drivers aren't widely available. (That may be improved by |
2348 | * supporting one submode of the "SAFE" variant of MDLM.) | ||
2282 | */ | 2349 | */ |
2283 | } else if (!cdc) { | 2350 | } else if (!cdc) { |
2284 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | ||
2285 | device_desc.idVendor = | 2351 | device_desc.idVendor = |
2286 | __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); | 2352 | __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); |
2287 | device_desc.idProduct = | 2353 | device_desc.idProduct = |
@@ -2352,6 +2418,10 @@ autoconf_fail: | |||
2352 | if (!cdc) { | 2418 | if (!cdc) { |
2353 | eth_config.bNumInterfaces = 1; | 2419 | eth_config.bNumInterfaces = 1; |
2354 | eth_config.iConfiguration = STRING_SUBSET; | 2420 | eth_config.iConfiguration = STRING_SUBSET; |
2421 | |||
2422 | /* use functions to set these up, in case we're built to work | ||
2423 | * with multiple controllers and must override CDC Ethernet. | ||
2424 | */ | ||
2355 | fs_subset_descriptors(); | 2425 | fs_subset_descriptors(); |
2356 | hs_subset_descriptors(); | 2426 | hs_subset_descriptors(); |
2357 | } | 2427 | } |
@@ -2415,22 +2485,20 @@ autoconf_fail: | |||
2415 | 2485 | ||
2416 | /* Module params for these addresses should come from ID proms. | 2486 | /* Module params for these addresses should come from ID proms. |
2417 | * The host side address is used with CDC and RNDIS, and commonly | 2487 | * The host side address is used with CDC and RNDIS, and commonly |
2418 | * ends up in a persistent config database. | 2488 | * ends up in a persistent config database. It's not clear if |
2489 | * host side code for the SAFE thing cares -- its original BLAN | ||
2490 | * thing didn't, Sharp never assigned those addresses on Zaurii. | ||
2419 | */ | 2491 | */ |
2420 | if (get_ether_addr(dev_addr, net->dev_addr)) | 2492 | if (get_ether_addr(dev_addr, net->dev_addr)) |
2421 | dev_warn(&gadget->dev, | 2493 | dev_warn(&gadget->dev, |
2422 | "using random %s ethernet address\n", "self"); | 2494 | "using random %s ethernet address\n", "self"); |
2423 | if (cdc || rndis) { | 2495 | if (get_ether_addr(host_addr, dev->host_mac)) |
2424 | if (get_ether_addr(host_addr, dev->host_mac)) | 2496 | dev_warn(&gadget->dev, |
2425 | dev_warn(&gadget->dev, | 2497 | "using random %s ethernet address\n", "host"); |
2426 | "using random %s ethernet address\n", "host"); | 2498 | snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", |
2427 | #ifdef DEV_CONFIG_CDC | 2499 | dev->host_mac [0], dev->host_mac [1], |
2428 | snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", | 2500 | dev->host_mac [2], dev->host_mac [3], |
2429 | dev->host_mac [0], dev->host_mac [1], | 2501 | dev->host_mac [4], dev->host_mac [5]); |
2430 | dev->host_mac [2], dev->host_mac [3], | ||
2431 | dev->host_mac [4], dev->host_mac [5]); | ||
2432 | #endif | ||
2433 | } | ||
2434 | 2502 | ||
2435 | if (rndis) { | 2503 | if (rndis) { |
2436 | status = rndis_init(); | 2504 | status = rndis_init(); |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 72f2ae96fbf3..f04a29a46646 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -253,7 +253,7 @@ | |||
253 | #include <linux/freezer.h> | 253 | #include <linux/freezer.h> |
254 | #include <linux/utsname.h> | 254 | #include <linux/utsname.h> |
255 | 255 | ||
256 | #include <linux/usb_ch9.h> | 256 | #include <linux/usb/ch9.h> |
257 | #include <linux/usb_gadget.h> | 257 | #include <linux/usb_gadget.h> |
258 | 258 | ||
259 | #include "gadget_chips.h" | 259 | #include "gadget_chips.h" |
@@ -1148,7 +1148,7 @@ static int ep0_queue(struct fsg_dev *fsg) | |||
1148 | 1148 | ||
1149 | static void ep0_complete(struct usb_ep *ep, struct usb_request *req) | 1149 | static void ep0_complete(struct usb_ep *ep, struct usb_request *req) |
1150 | { | 1150 | { |
1151 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1151 | struct fsg_dev *fsg = ep->driver_data; |
1152 | 1152 | ||
1153 | if (req->actual > 0) | 1153 | if (req->actual > 0) |
1154 | dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); | 1154 | dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); |
@@ -1170,8 +1170,8 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req) | |||
1170 | 1170 | ||
1171 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | 1171 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) |
1172 | { | 1172 | { |
1173 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1173 | struct fsg_dev *fsg = ep->driver_data; |
1174 | struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; | 1174 | struct fsg_buffhd *bh = req->context; |
1175 | 1175 | ||
1176 | if (req->status || req->actual != req->length) | 1176 | if (req->status || req->actual != req->length) |
1177 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, | 1177 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, |
@@ -1190,8 +1190,8 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1190 | 1190 | ||
1191 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1191 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
1192 | { | 1192 | { |
1193 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1193 | struct fsg_dev *fsg = ep->driver_data; |
1194 | struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; | 1194 | struct fsg_buffhd *bh = req->context; |
1195 | 1195 | ||
1196 | dump_msg(fsg, "bulk-out", req->buf, req->actual); | 1196 | dump_msg(fsg, "bulk-out", req->buf, req->actual); |
1197 | if (req->status || req->actual != bh->bulk_out_intended_length) | 1197 | if (req->status || req->actual != bh->bulk_out_intended_length) |
@@ -1214,8 +1214,8 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
1214 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | 1214 | #ifdef CONFIG_USB_FILE_STORAGE_TEST |
1215 | static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | 1215 | static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) |
1216 | { | 1216 | { |
1217 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1217 | struct fsg_dev *fsg = ep->driver_data; |
1218 | struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; | 1218 | struct fsg_buffhd *bh = req->context; |
1219 | 1219 | ||
1220 | if (req->status || req->actual != req->length) | 1220 | if (req->status || req->actual != req->length) |
1221 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, | 1221 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, |
@@ -2577,7 +2577,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2577 | } | 2577 | } |
2578 | 2578 | ||
2579 | if (transport_is_bbb()) { | 2579 | if (transport_is_bbb()) { |
2580 | struct bulk_cs_wrap *csw = (struct bulk_cs_wrap *) bh->buf; | 2580 | struct bulk_cs_wrap *csw = bh->buf; |
2581 | 2581 | ||
2582 | /* Store and send the Bulk-only CSW */ | 2582 | /* Store and send the Bulk-only CSW */ |
2583 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); | 2583 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); |
@@ -2596,8 +2596,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2596 | return 0; | 2596 | return 0; |
2597 | 2597 | ||
2598 | } else { // USB_PR_CBI | 2598 | } else { // USB_PR_CBI |
2599 | struct interrupt_data *buf = (struct interrupt_data *) | 2599 | struct interrupt_data *buf = bh->buf; |
2600 | bh->buf; | ||
2601 | 2600 | ||
2602 | /* Store and send the Interrupt data. UFI sends the ASC | 2601 | /* Store and send the Interrupt data. UFI sends the ASC |
2603 | * and ASCQ bytes. Everything else sends a Type (which | 2602 | * and ASCQ bytes. Everything else sends a Type (which |
@@ -2982,7 +2981,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2982 | static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | 2981 | static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) |
2983 | { | 2982 | { |
2984 | struct usb_request *req = bh->outreq; | 2983 | struct usb_request *req = bh->outreq; |
2985 | struct bulk_cb_wrap *cbw = (struct bulk_cb_wrap *) req->buf; | 2984 | struct bulk_cb_wrap *cbw = req->buf; |
2986 | 2985 | ||
2987 | /* Was this a real packet? */ | 2986 | /* Was this a real packet? */ |
2988 | if (req->status) | 2987 | if (req->status) |
@@ -3428,7 +3427,7 @@ static void handle_exception(struct fsg_dev *fsg) | |||
3428 | 3427 | ||
3429 | static int fsg_main_thread(void *fsg_) | 3428 | static int fsg_main_thread(void *fsg_) |
3430 | { | 3429 | { |
3431 | struct fsg_dev *fsg = (struct fsg_dev *) fsg_; | 3430 | struct fsg_dev *fsg = fsg_; |
3432 | 3431 | ||
3433 | /* Allow the thread to be killed by a signal, but set the signal mask | 3432 | /* Allow the thread to be killed by a signal, but set the signal mask |
3434 | * to block everything but INT, TERM, KILL, and USR1. */ | 3433 | * to block everything but INT, TERM, KILL, and USR1. */ |
@@ -3600,7 +3599,7 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char * | |||
3600 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) | 3599 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) |
3601 | { | 3600 | { |
3602 | struct lun *curlun = dev_to_lun(dev); | 3601 | struct lun *curlun = dev_to_lun(dev); |
3603 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3602 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3604 | char *p; | 3603 | char *p; |
3605 | ssize_t rc; | 3604 | ssize_t rc; |
3606 | 3605 | ||
@@ -3629,7 +3628,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const | |||
3629 | { | 3628 | { |
3630 | ssize_t rc = count; | 3629 | ssize_t rc = count; |
3631 | struct lun *curlun = dev_to_lun(dev); | 3630 | struct lun *curlun = dev_to_lun(dev); |
3632 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3631 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3633 | int i; | 3632 | int i; |
3634 | 3633 | ||
3635 | if (sscanf(buf, "%d", &i) != 1) | 3634 | if (sscanf(buf, "%d", &i) != 1) |
@@ -3652,7 +3651,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const | |||
3652 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 3651 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
3653 | { | 3652 | { |
3654 | struct lun *curlun = dev_to_lun(dev); | 3653 | struct lun *curlun = dev_to_lun(dev); |
3655 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3654 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3656 | int rc = 0; | 3655 | int rc = 0; |
3657 | 3656 | ||
3658 | if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) { | 3657 | if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) { |
@@ -3700,7 +3699,7 @@ static void fsg_release(struct kref *ref) | |||
3700 | 3699 | ||
3701 | static void lun_release(struct device *dev) | 3700 | static void lun_release(struct device *dev) |
3702 | { | 3701 | { |
3703 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3702 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3704 | 3703 | ||
3705 | kref_put(&fsg->ref, fsg_release); | 3704 | kref_put(&fsg->ref, fsg_release); |
3706 | } | 3705 | } |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index aa80f0910720..2e3d6620d216 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -75,6 +75,12 @@ | |||
75 | #define gadget_is_pxa27x(g) 0 | 75 | #define gadget_is_pxa27x(g) 0 |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #ifdef CONFIG_USB_GADGET_HUSB2DEV | ||
79 | #define gadget_is_husb2dev(g) !strcmp("husb2_udc", (g)->name) | ||
80 | #else | ||
81 | #define gadget_is_husb2dev(g) 0 | ||
82 | #endif | ||
83 | |||
78 | #ifdef CONFIG_USB_GADGET_S3C2410 | 84 | #ifdef CONFIG_USB_GADGET_S3C2410 |
79 | #define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name) | 85 | #define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name) |
80 | #else | 86 | #else |
@@ -169,5 +175,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
169 | return 0x16; | 175 | return 0x16; |
170 | else if (gadget_is_mpc8272(gadget)) | 176 | else if (gadget_is_mpc8272(gadget)) |
171 | return 0x17; | 177 | return 0x17; |
178 | else if (gadget_is_husb2dev(gadget)) | ||
179 | return 0x18; | ||
172 | return -ENOENT; | 180 | return -ENOENT; |
173 | } | 181 | } |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index f1a679656c96..d08a8d0e6427 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <sound/initval.h> | 35 | #include <sound/initval.h> |
36 | #include <sound/rawmidi.h> | 36 | #include <sound/rawmidi.h> |
37 | 37 | ||
38 | #include <linux/usb_ch9.h> | 38 | #include <linux/usb/ch9.h> |
39 | #include <linux/usb_gadget.h> | 39 | #include <linux/usb_gadget.h> |
40 | #include <linux/usb/audio.h> | 40 | #include <linux/usb/audio.h> |
41 | #include <linux/usb/midi.h> | 41 | #include <linux/usb/midi.h> |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index d0ef1d6b3fac..e873cf488246 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/device.h> | 41 | #include <linux/device.h> |
42 | #include <linux/usb_ch9.h> | 42 | #include <linux/usb/ch9.h> |
43 | #include <linux/usb_gadget.h> | 43 | #include <linux/usb_gadget.h> |
44 | 44 | ||
45 | #include <asm/byteorder.h> | 45 | #include <asm/byteorder.h> |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3fb1044a4db0..34296e79edcf 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -20,7 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | 22 | ||
23 | // #define DEBUG /* data to help fault diagnosis */ | 23 | // #define DEBUG /* data to help fault diagnosis */ |
24 | // #define VERBOSE /* extra debug messages (success too) */ | 24 | // #define VERBOSE /* extra debug messages (success too) */ |
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -59,11 +59,11 @@ | |||
59 | * may serve as a source of device events, used to handle all control | 59 | * may serve as a source of device events, used to handle all control |
60 | * requests other than basic enumeration. | 60 | * requests other than basic enumeration. |
61 | * | 61 | * |
62 | * - Then either immediately, or after a SET_CONFIGURATION control request, | 62 | * - Then, after a SET_CONFIGURATION control request, ep_config() is |
63 | * ep_config() is called when each /dev/gadget/ep* file is configured | 63 | * called when each /dev/gadget/ep* file is configured (by writing |
64 | * (by writing endpoint descriptors). Afterwards these files are used | 64 | * endpoint descriptors). Afterwards these files are used to write() |
65 | * to write() IN data or to read() OUT data. To halt the endpoint, a | 65 | * IN data or to read() OUT data. To halt the endpoint, a "wrong |
66 | * "wrong direction" request is issued (like reading an IN endpoint). | 66 | * direction" request is issued (like reading an IN endpoint). |
67 | * | 67 | * |
68 | * Unlike "usbfs" the only ioctl()s are for things that are rare, and maybe | 68 | * Unlike "usbfs" the only ioctl()s are for things that are rare, and maybe |
69 | * not possible on all hardware. For example, precise fault handling with | 69 | * not possible on all hardware. For example, precise fault handling with |
@@ -98,16 +98,16 @@ enum ep0_state { | |||
98 | * must always write descriptors to initialize the device, then | 98 | * must always write descriptors to initialize the device, then |
99 | * the device becomes UNCONNECTED until enumeration. | 99 | * the device becomes UNCONNECTED until enumeration. |
100 | */ | 100 | */ |
101 | STATE_OPENED, | 101 | STATE_DEV_OPENED, |
102 | 102 | ||
103 | /* From then on, ep0 fd is in either of two basic modes: | 103 | /* From then on, ep0 fd is in either of two basic modes: |
104 | * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it | 104 | * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it |
105 | * - SETUP: read/write will transfer control data and succeed; | 105 | * - SETUP: read/write will transfer control data and succeed; |
106 | * or if "wrong direction", performs protocol stall | 106 | * or if "wrong direction", performs protocol stall |
107 | */ | 107 | */ |
108 | STATE_UNCONNECTED, | 108 | STATE_DEV_UNCONNECTED, |
109 | STATE_CONNECTED, | 109 | STATE_DEV_CONNECTED, |
110 | STATE_SETUP, | 110 | STATE_DEV_SETUP, |
111 | 111 | ||
112 | /* UNBOUND means the driver closed ep0, so the device won't be | 112 | /* UNBOUND means the driver closed ep0, so the device won't be |
113 | * accessible again (DEV_DISABLED) until all fds are closed. | 113 | * accessible again (DEV_DISABLED) until all fds are closed. |
@@ -121,7 +121,7 @@ enum ep0_state { | |||
121 | struct dev_data { | 121 | struct dev_data { |
122 | spinlock_t lock; | 122 | spinlock_t lock; |
123 | atomic_t count; | 123 | atomic_t count; |
124 | enum ep0_state state; | 124 | enum ep0_state state; /* P: lock */ |
125 | struct usb_gadgetfs_event event [N_EVENT]; | 125 | struct usb_gadgetfs_event event [N_EVENT]; |
126 | unsigned ev_next; | 126 | unsigned ev_next; |
127 | struct fasync_struct *fasync; | 127 | struct fasync_struct *fasync; |
@@ -188,7 +188,6 @@ static struct dev_data *dev_new (void) | |||
188 | enum ep_state { | 188 | enum ep_state { |
189 | STATE_EP_DISABLED = 0, | 189 | STATE_EP_DISABLED = 0, |
190 | STATE_EP_READY, | 190 | STATE_EP_READY, |
191 | STATE_EP_DEFER_ENABLE, | ||
192 | STATE_EP_ENABLED, | 191 | STATE_EP_ENABLED, |
193 | STATE_EP_UNBOUND, | 192 | STATE_EP_UNBOUND, |
194 | }; | 193 | }; |
@@ -313,18 +312,10 @@ nonblock: | |||
313 | 312 | ||
314 | if ((val = down_interruptible (&epdata->lock)) < 0) | 313 | if ((val = down_interruptible (&epdata->lock)) < 0) |
315 | return val; | 314 | return val; |
316 | newstate: | 315 | |
317 | switch (epdata->state) { | 316 | switch (epdata->state) { |
318 | case STATE_EP_ENABLED: | 317 | case STATE_EP_ENABLED: |
319 | break; | 318 | break; |
320 | case STATE_EP_DEFER_ENABLE: | ||
321 | DBG (epdata->dev, "%s wait for host\n", epdata->name); | ||
322 | if ((val = wait_event_interruptible (epdata->wait, | ||
323 | epdata->state != STATE_EP_DEFER_ENABLE | ||
324 | || epdata->dev->state == STATE_DEV_UNBOUND | ||
325 | )) < 0) | ||
326 | goto fail; | ||
327 | goto newstate; | ||
328 | // case STATE_EP_DISABLED: /* "can't happen" */ | 319 | // case STATE_EP_DISABLED: /* "can't happen" */ |
329 | // case STATE_EP_READY: /* "can't happen" */ | 320 | // case STATE_EP_READY: /* "can't happen" */ |
330 | default: /* error! */ | 321 | default: /* error! */ |
@@ -333,7 +324,6 @@ newstate: | |||
333 | // FALLTHROUGH | 324 | // FALLTHROUGH |
334 | case STATE_EP_UNBOUND: /* clean disconnect */ | 325 | case STATE_EP_UNBOUND: /* clean disconnect */ |
335 | val = -ENODEV; | 326 | val = -ENODEV; |
336 | fail: | ||
337 | up (&epdata->lock); | 327 | up (&epdata->lock); |
338 | } | 328 | } |
339 | return val; | 329 | return val; |
@@ -565,29 +555,28 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb) | |||
565 | ssize_t len, total; | 555 | ssize_t len, total; |
566 | int i; | 556 | int i; |
567 | 557 | ||
568 | /* we "retry" to get the right mm context for this: */ | 558 | /* we "retry" to get the right mm context for this: */ |
569 | 559 | ||
570 | /* copy stuff into user buffers */ | 560 | /* copy stuff into user buffers */ |
571 | total = priv->actual; | 561 | total = priv->actual; |
572 | len = 0; | 562 | len = 0; |
573 | for (i=0; i < priv->nr_segs; i++) { | 563 | for (i=0; i < priv->nr_segs; i++) { |
574 | ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); | 564 | ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); |
575 | 565 | ||
576 | if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) { | 566 | if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) { |
577 | if (len == 0) | 567 | if (len == 0) |
578 | len = -EFAULT; | 568 | len = -EFAULT; |
579 | break; | 569 | break; |
580 | } | 570 | } |
581 | 571 | ||
582 | total -= this; | 572 | total -= this; |
583 | len += this; | 573 | len += this; |
584 | if (total == 0) | 574 | if (total == 0) |
585 | break; | 575 | break; |
586 | } | 576 | } |
587 | kfree(priv->buf); | 577 | kfree(priv->buf); |
588 | kfree(priv); | 578 | kfree(priv); |
589 | aio_put_req(iocb); | 579 | return len; |
590 | return len; | ||
591 | } | 580 | } |
592 | 581 | ||
593 | static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) | 582 | static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -600,18 +589,17 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) | |||
600 | spin_lock(&epdata->dev->lock); | 589 | spin_lock(&epdata->dev->lock); |
601 | priv->req = NULL; | 590 | priv->req = NULL; |
602 | priv->epdata = NULL; | 591 | priv->epdata = NULL; |
603 | if (priv->iv == NULL | 592 | |
604 | || unlikely(req->actual == 0) | 593 | /* if this was a write or a read returning no data then we |
605 | || unlikely(kiocbIsCancelled(iocb))) { | 594 | * don't need to copy anything to userspace, so we can |
595 | * complete the aio request immediately. | ||
596 | */ | ||
597 | if (priv->iv == NULL || unlikely(req->actual == 0)) { | ||
606 | kfree(req->buf); | 598 | kfree(req->buf); |
607 | kfree(priv); | 599 | kfree(priv); |
608 | iocb->private = NULL; | 600 | iocb->private = NULL; |
609 | /* aio_complete() reports bytes-transferred _and_ faults */ | 601 | /* aio_complete() reports bytes-transferred _and_ faults */ |
610 | if (unlikely(kiocbIsCancelled(iocb))) | 602 | aio_complete(iocb, req->actual ? req->actual : req->status, |
611 | aio_put_req(iocb); | ||
612 | else | ||
613 | aio_complete(iocb, | ||
614 | req->actual ? req->actual : req->status, | ||
615 | req->status); | 603 | req->status); |
616 | } else { | 604 | } else { |
617 | /* retry() won't report both; so we hide some faults */ | 605 | /* retry() won't report both; so we hide some faults */ |
@@ -636,7 +624,7 @@ ep_aio_rwtail( | |||
636 | size_t len, | 624 | size_t len, |
637 | struct ep_data *epdata, | 625 | struct ep_data *epdata, |
638 | const struct iovec *iv, | 626 | const struct iovec *iv, |
639 | unsigned long nr_segs | 627 | unsigned long nr_segs |
640 | ) | 628 | ) |
641 | { | 629 | { |
642 | struct kiocb_priv *priv; | 630 | struct kiocb_priv *priv; |
@@ -852,9 +840,9 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
852 | break; | 840 | break; |
853 | #endif | 841 | #endif |
854 | default: | 842 | default: |
855 | DBG (data->dev, "unconnected, %s init deferred\n", | 843 | DBG(data->dev, "unconnected, %s init abandoned\n", |
856 | data->name); | 844 | data->name); |
857 | data->state = STATE_EP_DEFER_ENABLE; | 845 | value = -EINVAL; |
858 | } | 846 | } |
859 | if (value == 0) { | 847 | if (value == 0) { |
860 | fd->f_op = &ep_io_operations; | 848 | fd->f_op = &ep_io_operations; |
@@ -943,22 +931,24 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req) | |||
943 | static void ep0_complete (struct usb_ep *ep, struct usb_request *req) | 931 | static void ep0_complete (struct usb_ep *ep, struct usb_request *req) |
944 | { | 932 | { |
945 | struct dev_data *dev = ep->driver_data; | 933 | struct dev_data *dev = ep->driver_data; |
934 | unsigned long flags; | ||
946 | int free = 1; | 935 | int free = 1; |
947 | 936 | ||
948 | /* for control OUT, data must still get to userspace */ | 937 | /* for control OUT, data must still get to userspace */ |
938 | spin_lock_irqsave(&dev->lock, flags); | ||
949 | if (!dev->setup_in) { | 939 | if (!dev->setup_in) { |
950 | dev->setup_out_error = (req->status != 0); | 940 | dev->setup_out_error = (req->status != 0); |
951 | if (!dev->setup_out_error) | 941 | if (!dev->setup_out_error) |
952 | free = 0; | 942 | free = 0; |
953 | dev->setup_out_ready = 1; | 943 | dev->setup_out_ready = 1; |
954 | ep0_readable (dev); | 944 | ep0_readable (dev); |
955 | } else if (dev->state == STATE_SETUP) | 945 | } |
956 | dev->state = STATE_CONNECTED; | ||
957 | 946 | ||
958 | /* clean up as appropriate */ | 947 | /* clean up as appropriate */ |
959 | if (free && req->buf != &dev->rbuf) | 948 | if (free && req->buf != &dev->rbuf) |
960 | clean_req (ep, req); | 949 | clean_req (ep, req); |
961 | req->complete = epio_complete; | 950 | req->complete = epio_complete; |
951 | spin_unlock_irqrestore(&dev->lock, flags); | ||
962 | } | 952 | } |
963 | 953 | ||
964 | static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) | 954 | static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) |
@@ -998,13 +988,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
998 | } | 988 | } |
999 | 989 | ||
1000 | /* control DATA stage */ | 990 | /* control DATA stage */ |
1001 | if ((state = dev->state) == STATE_SETUP) { | 991 | if ((state = dev->state) == STATE_DEV_SETUP) { |
1002 | 992 | ||
1003 | if (dev->setup_in) { /* stall IN */ | 993 | if (dev->setup_in) { /* stall IN */ |
1004 | VDEBUG(dev, "ep0in stall\n"); | 994 | VDEBUG(dev, "ep0in stall\n"); |
1005 | (void) usb_ep_set_halt (dev->gadget->ep0); | 995 | (void) usb_ep_set_halt (dev->gadget->ep0); |
1006 | retval = -EL2HLT; | 996 | retval = -EL2HLT; |
1007 | dev->state = STATE_CONNECTED; | 997 | dev->state = STATE_DEV_CONNECTED; |
1008 | 998 | ||
1009 | } else if (len == 0) { /* ack SET_CONFIGURATION etc */ | 999 | } else if (len == 0) { /* ack SET_CONFIGURATION etc */ |
1010 | struct usb_ep *ep = dev->gadget->ep0; | 1000 | struct usb_ep *ep = dev->gadget->ep0; |
@@ -1012,7 +1002,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1012 | 1002 | ||
1013 | if ((retval = setup_req (ep, req, 0)) == 0) | 1003 | if ((retval = setup_req (ep, req, 0)) == 0) |
1014 | retval = usb_ep_queue (ep, req, GFP_ATOMIC); | 1004 | retval = usb_ep_queue (ep, req, GFP_ATOMIC); |
1015 | dev->state = STATE_CONNECTED; | 1005 | dev->state = STATE_DEV_CONNECTED; |
1016 | 1006 | ||
1017 | /* assume that was SET_CONFIGURATION */ | 1007 | /* assume that was SET_CONFIGURATION */ |
1018 | if (dev->current_config) { | 1008 | if (dev->current_config) { |
@@ -1040,6 +1030,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1040 | spin_lock_irq (&dev->lock); | 1030 | spin_lock_irq (&dev->lock); |
1041 | if (retval) | 1031 | if (retval) |
1042 | goto done; | 1032 | goto done; |
1033 | |||
1034 | if (dev->state != STATE_DEV_SETUP) { | ||
1035 | retval = -ECANCELED; | ||
1036 | goto done; | ||
1037 | } | ||
1038 | dev->state = STATE_DEV_CONNECTED; | ||
1039 | |||
1043 | if (dev->setup_out_error) | 1040 | if (dev->setup_out_error) |
1044 | retval = -EIO; | 1041 | retval = -EIO; |
1045 | else { | 1042 | else { |
@@ -1066,39 +1063,36 @@ scan: | |||
1066 | /* return queued events right away */ | 1063 | /* return queued events right away */ |
1067 | if (dev->ev_next != 0) { | 1064 | if (dev->ev_next != 0) { |
1068 | unsigned i, n; | 1065 | unsigned i, n; |
1069 | int tmp = dev->ev_next; | ||
1070 | 1066 | ||
1071 | len = min (len, tmp * sizeof (struct usb_gadgetfs_event)); | ||
1072 | n = len / sizeof (struct usb_gadgetfs_event); | 1067 | n = len / sizeof (struct usb_gadgetfs_event); |
1068 | if (dev->ev_next < n) | ||
1069 | n = dev->ev_next; | ||
1073 | 1070 | ||
1074 | /* ep0 can't deliver events when STATE_SETUP */ | 1071 | /* ep0 i/o has special semantics during STATE_DEV_SETUP */ |
1075 | for (i = 0; i < n; i++) { | 1072 | for (i = 0; i < n; i++) { |
1076 | if (dev->event [i].type == GADGETFS_SETUP) { | 1073 | if (dev->event [i].type == GADGETFS_SETUP) { |
1077 | len = i + 1; | 1074 | dev->state = STATE_DEV_SETUP; |
1078 | len *= sizeof (struct usb_gadgetfs_event); | 1075 | n = i + 1; |
1079 | n = 0; | ||
1080 | break; | 1076 | break; |
1081 | } | 1077 | } |
1082 | } | 1078 | } |
1083 | spin_unlock_irq (&dev->lock); | 1079 | spin_unlock_irq (&dev->lock); |
1080 | len = n * sizeof (struct usb_gadgetfs_event); | ||
1084 | if (copy_to_user (buf, &dev->event, len)) | 1081 | if (copy_to_user (buf, &dev->event, len)) |
1085 | retval = -EFAULT; | 1082 | retval = -EFAULT; |
1086 | else | 1083 | else |
1087 | retval = len; | 1084 | retval = len; |
1088 | if (len > 0) { | 1085 | if (len > 0) { |
1089 | len /= sizeof (struct usb_gadgetfs_event); | ||
1090 | |||
1091 | /* NOTE this doesn't guard against broken drivers; | 1086 | /* NOTE this doesn't guard against broken drivers; |
1092 | * concurrent ep0 readers may lose events. | 1087 | * concurrent ep0 readers may lose events. |
1093 | */ | 1088 | */ |
1094 | spin_lock_irq (&dev->lock); | 1089 | spin_lock_irq (&dev->lock); |
1095 | dev->ev_next -= len; | 1090 | if (dev->ev_next > n) { |
1096 | if (dev->ev_next != 0) | 1091 | memmove(&dev->event[0], &dev->event[n], |
1097 | memmove (&dev->event, &dev->event [len], | ||
1098 | sizeof (struct usb_gadgetfs_event) | 1092 | sizeof (struct usb_gadgetfs_event) |
1099 | * (tmp - len)); | 1093 | * (dev->ev_next - n)); |
1100 | if (n == 0) | 1094 | } |
1101 | dev->state = STATE_SETUP; | 1095 | dev->ev_next -= n; |
1102 | spin_unlock_irq (&dev->lock); | 1096 | spin_unlock_irq (&dev->lock); |
1103 | } | 1097 | } |
1104 | return retval; | 1098 | return retval; |
@@ -1113,8 +1107,8 @@ scan: | |||
1113 | DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); | 1107 | DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); |
1114 | retval = -ESRCH; | 1108 | retval = -ESRCH; |
1115 | break; | 1109 | break; |
1116 | case STATE_UNCONNECTED: | 1110 | case STATE_DEV_UNCONNECTED: |
1117 | case STATE_CONNECTED: | 1111 | case STATE_DEV_CONNECTED: |
1118 | spin_unlock_irq (&dev->lock); | 1112 | spin_unlock_irq (&dev->lock); |
1119 | DBG (dev, "%s wait\n", __FUNCTION__); | 1113 | DBG (dev, "%s wait\n", __FUNCTION__); |
1120 | 1114 | ||
@@ -1141,7 +1135,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1141 | switch (type) { | 1135 | switch (type) { |
1142 | /* these events purge the queue */ | 1136 | /* these events purge the queue */ |
1143 | case GADGETFS_DISCONNECT: | 1137 | case GADGETFS_DISCONNECT: |
1144 | if (dev->state == STATE_SETUP) | 1138 | if (dev->state == STATE_DEV_SETUP) |
1145 | dev->setup_abort = 1; | 1139 | dev->setup_abort = 1; |
1146 | // FALL THROUGH | 1140 | // FALL THROUGH |
1147 | case GADGETFS_CONNECT: | 1141 | case GADGETFS_CONNECT: |
@@ -1153,7 +1147,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1153 | for (i = 0; i != dev->ev_next; i++) { | 1147 | for (i = 0; i != dev->ev_next; i++) { |
1154 | if (dev->event [i].type != type) | 1148 | if (dev->event [i].type != type) |
1155 | continue; | 1149 | continue; |
1156 | DBG (dev, "discard old event %d\n", type); | 1150 | DBG(dev, "discard old event[%d] %d\n", i, type); |
1157 | dev->ev_next--; | 1151 | dev->ev_next--; |
1158 | if (i == dev->ev_next) | 1152 | if (i == dev->ev_next) |
1159 | break; | 1153 | break; |
@@ -1166,9 +1160,9 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1166 | default: | 1160 | default: |
1167 | BUG (); | 1161 | BUG (); |
1168 | } | 1162 | } |
1163 | VDEBUG(dev, "event[%d] = %d\n", dev->ev_next, type); | ||
1169 | event = &dev->event [dev->ev_next++]; | 1164 | event = &dev->event [dev->ev_next++]; |
1170 | BUG_ON (dev->ev_next > N_EVENT); | 1165 | BUG_ON (dev->ev_next > N_EVENT); |
1171 | VDEBUG (dev, "ev %d, next %d\n", type, dev->ev_next); | ||
1172 | memset (event, 0, sizeof *event); | 1166 | memset (event, 0, sizeof *event); |
1173 | event->type = type; | 1167 | event->type = type; |
1174 | return event; | 1168 | return event; |
@@ -1188,12 +1182,13 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1188 | retval = -EIDRM; | 1182 | retval = -EIDRM; |
1189 | 1183 | ||
1190 | /* data and/or status stage for control request */ | 1184 | /* data and/or status stage for control request */ |
1191 | } else if (dev->state == STATE_SETUP) { | 1185 | } else if (dev->state == STATE_DEV_SETUP) { |
1192 | 1186 | ||
1193 | /* IN DATA+STATUS caller makes len <= wLength */ | 1187 | /* IN DATA+STATUS caller makes len <= wLength */ |
1194 | if (dev->setup_in) { | 1188 | if (dev->setup_in) { |
1195 | retval = setup_req (dev->gadget->ep0, dev->req, len); | 1189 | retval = setup_req (dev->gadget->ep0, dev->req, len); |
1196 | if (retval == 0) { | 1190 | if (retval == 0) { |
1191 | dev->state = STATE_DEV_CONNECTED; | ||
1197 | spin_unlock_irq (&dev->lock); | 1192 | spin_unlock_irq (&dev->lock); |
1198 | if (copy_from_user (dev->req->buf, buf, len)) | 1193 | if (copy_from_user (dev->req->buf, buf, len)) |
1199 | retval = -EFAULT; | 1194 | retval = -EFAULT; |
@@ -1219,7 +1214,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1219 | VDEBUG(dev, "ep0out stall\n"); | 1214 | VDEBUG(dev, "ep0out stall\n"); |
1220 | (void) usb_ep_set_halt (dev->gadget->ep0); | 1215 | (void) usb_ep_set_halt (dev->gadget->ep0); |
1221 | retval = -EL2HLT; | 1216 | retval = -EL2HLT; |
1222 | dev->state = STATE_CONNECTED; | 1217 | dev->state = STATE_DEV_CONNECTED; |
1223 | } else { | 1218 | } else { |
1224 | DBG(dev, "bogus ep0out stall!\n"); | 1219 | DBG(dev, "bogus ep0out stall!\n"); |
1225 | } | 1220 | } |
@@ -1261,7 +1256,9 @@ dev_release (struct inode *inode, struct file *fd) | |||
1261 | put_dev (dev); | 1256 | put_dev (dev); |
1262 | 1257 | ||
1263 | /* other endpoints were all decoupled from this device */ | 1258 | /* other endpoints were all decoupled from this device */ |
1259 | spin_lock_irq(&dev->lock); | ||
1264 | dev->state = STATE_DEV_DISABLED; | 1260 | dev->state = STATE_DEV_DISABLED; |
1261 | spin_unlock_irq(&dev->lock); | ||
1265 | return 0; | 1262 | return 0; |
1266 | } | 1263 | } |
1267 | 1264 | ||
@@ -1282,7 +1279,7 @@ ep0_poll (struct file *fd, poll_table *wait) | |||
1282 | goto out; | 1279 | goto out; |
1283 | } | 1280 | } |
1284 | 1281 | ||
1285 | if (dev->state == STATE_SETUP) { | 1282 | if (dev->state == STATE_DEV_SETUP) { |
1286 | if (dev->setup_in || dev->setup_can_stall) | 1283 | if (dev->setup_in || dev->setup_can_stall) |
1287 | mask = POLLOUT; | 1284 | mask = POLLOUT; |
1288 | } else { | 1285 | } else { |
@@ -1392,52 +1389,29 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1392 | 1389 | ||
1393 | spin_lock (&dev->lock); | 1390 | spin_lock (&dev->lock); |
1394 | dev->setup_abort = 0; | 1391 | dev->setup_abort = 0; |
1395 | if (dev->state == STATE_UNCONNECTED) { | 1392 | if (dev->state == STATE_DEV_UNCONNECTED) { |
1396 | struct usb_ep *ep; | ||
1397 | struct ep_data *data; | ||
1398 | |||
1399 | dev->state = STATE_CONNECTED; | ||
1400 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
1401 | |||
1402 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1393 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1403 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { | 1394 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { |
1395 | spin_unlock(&dev->lock); | ||
1404 | ERROR (dev, "no high speed config??\n"); | 1396 | ERROR (dev, "no high speed config??\n"); |
1405 | return -EINVAL; | 1397 | return -EINVAL; |
1406 | } | 1398 | } |
1407 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1399 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
1408 | 1400 | ||
1401 | dev->state = STATE_DEV_CONNECTED; | ||
1402 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
1403 | |||
1409 | INFO (dev, "connected\n"); | 1404 | INFO (dev, "connected\n"); |
1410 | event = next_event (dev, GADGETFS_CONNECT); | 1405 | event = next_event (dev, GADGETFS_CONNECT); |
1411 | event->u.speed = gadget->speed; | 1406 | event->u.speed = gadget->speed; |
1412 | ep0_readable (dev); | 1407 | ep0_readable (dev); |
1413 | 1408 | ||
1414 | list_for_each_entry (ep, &gadget->ep_list, ep_list) { | ||
1415 | data = ep->driver_data; | ||
1416 | /* ... down_trylock (&data->lock) ... */ | ||
1417 | if (data->state != STATE_EP_DEFER_ENABLE) | ||
1418 | continue; | ||
1419 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1420 | if (gadget->speed == USB_SPEED_HIGH) | ||
1421 | value = usb_ep_enable (ep, &data->hs_desc); | ||
1422 | else | ||
1423 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1424 | value = usb_ep_enable (ep, &data->desc); | ||
1425 | if (value) { | ||
1426 | ERROR (dev, "deferred %s enable --> %d\n", | ||
1427 | data->name, value); | ||
1428 | continue; | ||
1429 | } | ||
1430 | data->state = STATE_EP_ENABLED; | ||
1431 | wake_up (&data->wait); | ||
1432 | DBG (dev, "woke up %s waiters\n", data->name); | ||
1433 | } | ||
1434 | |||
1435 | /* host may have given up waiting for response. we can miss control | 1409 | /* host may have given up waiting for response. we can miss control |
1436 | * requests handled lower down (device/endpoint status and features); | 1410 | * requests handled lower down (device/endpoint status and features); |
1437 | * then ep0_{read,write} will report the wrong status. controller | 1411 | * then ep0_{read,write} will report the wrong status. controller |
1438 | * driver will have aborted pending i/o. | 1412 | * driver will have aborted pending i/o. |
1439 | */ | 1413 | */ |
1440 | } else if (dev->state == STATE_SETUP) | 1414 | } else if (dev->state == STATE_DEV_SETUP) |
1441 | dev->setup_abort = 1; | 1415 | dev->setup_abort = 1; |
1442 | 1416 | ||
1443 | req->buf = dev->rbuf; | 1417 | req->buf = dev->rbuf; |
@@ -1583,7 +1557,7 @@ delegate: | |||
1583 | } | 1557 | } |
1584 | 1558 | ||
1585 | /* proceed with data transfer and status phases? */ | 1559 | /* proceed with data transfer and status phases? */ |
1586 | if (value >= 0 && dev->state != STATE_SETUP) { | 1560 | if (value >= 0 && dev->state != STATE_DEV_SETUP) { |
1587 | req->length = value; | 1561 | req->length = value; |
1588 | req->zero = value < w_length; | 1562 | req->zero = value < w_length; |
1589 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); | 1563 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); |
@@ -1747,7 +1721,9 @@ gadgetfs_bind (struct usb_gadget *gadget) | |||
1747 | goto enomem; | 1721 | goto enomem; |
1748 | 1722 | ||
1749 | INFO (dev, "bound to %s driver\n", gadget->name); | 1723 | INFO (dev, "bound to %s driver\n", gadget->name); |
1750 | dev->state = STATE_UNCONNECTED; | 1724 | spin_lock_irq(&dev->lock); |
1725 | dev->state = STATE_DEV_UNCONNECTED; | ||
1726 | spin_unlock_irq(&dev->lock); | ||
1751 | get_dev (dev); | 1727 | get_dev (dev); |
1752 | return 0; | 1728 | return 0; |
1753 | 1729 | ||
@@ -1762,11 +1738,9 @@ gadgetfs_disconnect (struct usb_gadget *gadget) | |||
1762 | struct dev_data *dev = get_gadget_data (gadget); | 1738 | struct dev_data *dev = get_gadget_data (gadget); |
1763 | 1739 | ||
1764 | spin_lock (&dev->lock); | 1740 | spin_lock (&dev->lock); |
1765 | if (dev->state == STATE_UNCONNECTED) { | 1741 | if (dev->state == STATE_DEV_UNCONNECTED) |
1766 | DBG (dev, "already unconnected\n"); | ||
1767 | goto exit; | 1742 | goto exit; |
1768 | } | 1743 | dev->state = STATE_DEV_UNCONNECTED; |
1769 | dev->state = STATE_UNCONNECTED; | ||
1770 | 1744 | ||
1771 | INFO (dev, "disconnected\n"); | 1745 | INFO (dev, "disconnected\n"); |
1772 | next_event (dev, GADGETFS_DISCONNECT); | 1746 | next_event (dev, GADGETFS_DISCONNECT); |
@@ -1783,9 +1757,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) | |||
1783 | INFO (dev, "suspended from state %d\n", dev->state); | 1757 | INFO (dev, "suspended from state %d\n", dev->state); |
1784 | spin_lock (&dev->lock); | 1758 | spin_lock (&dev->lock); |
1785 | switch (dev->state) { | 1759 | switch (dev->state) { |
1786 | case STATE_SETUP: // VERY odd... host died?? | 1760 | case STATE_DEV_SETUP: // VERY odd... host died?? |
1787 | case STATE_CONNECTED: | 1761 | case STATE_DEV_CONNECTED: |
1788 | case STATE_UNCONNECTED: | 1762 | case STATE_DEV_UNCONNECTED: |
1789 | next_event (dev, GADGETFS_SUSPEND); | 1763 | next_event (dev, GADGETFS_SUSPEND); |
1790 | ep0_readable (dev); | 1764 | ep0_readable (dev); |
1791 | /* FALLTHROUGH */ | 1765 | /* FALLTHROUGH */ |
@@ -1808,7 +1782,7 @@ static struct usb_gadget_driver gadgetfs_driver = { | |||
1808 | .disconnect = gadgetfs_disconnect, | 1782 | .disconnect = gadgetfs_disconnect, |
1809 | .suspend = gadgetfs_suspend, | 1783 | .suspend = gadgetfs_suspend, |
1810 | 1784 | ||
1811 | .driver = { | 1785 | .driver = { |
1812 | .name = (char *) shortname, | 1786 | .name = (char *) shortname, |
1813 | }, | 1787 | }, |
1814 | }; | 1788 | }; |
@@ -1829,7 +1803,7 @@ static struct usb_gadget_driver probe_driver = { | |||
1829 | .unbind = gadgetfs_nop, | 1803 | .unbind = gadgetfs_nop, |
1830 | .setup = (void *)gadgetfs_nop, | 1804 | .setup = (void *)gadgetfs_nop, |
1831 | .disconnect = gadgetfs_nop, | 1805 | .disconnect = gadgetfs_nop, |
1832 | .driver = { | 1806 | .driver = { |
1833 | .name = "nop", | 1807 | .name = "nop", |
1834 | }, | 1808 | }, |
1835 | }; | 1809 | }; |
@@ -1849,19 +1823,16 @@ static struct usb_gadget_driver probe_driver = { | |||
1849 | * . full/low speed config ... all wTotalLength bytes (with interface, | 1823 | * . full/low speed config ... all wTotalLength bytes (with interface, |
1850 | * class, altsetting, endpoint, and other descriptors) | 1824 | * class, altsetting, endpoint, and other descriptors) |
1851 | * . high speed config ... all descriptors, for high speed operation; | 1825 | * . high speed config ... all descriptors, for high speed operation; |
1852 | * this one's optional except for high-speed hardware | 1826 | * this one's optional except for high-speed hardware |
1853 | * . device descriptor | 1827 | * . device descriptor |
1854 | * | 1828 | * |
1855 | * Endpoints are not yet enabled. Drivers may want to immediately | 1829 | * Endpoints are not yet enabled. Drivers must wait until device |
1856 | * initialize them, using the /dev/gadget/ep* files that are available | 1830 | * configuration and interface altsetting changes create |
1857 | * as soon as the kernel sees the configuration, or they can wait | ||
1858 | * until device configuration and interface altsetting changes create | ||
1859 | * the need to configure (or unconfigure) them. | 1831 | * the need to configure (or unconfigure) them. |
1860 | * | 1832 | * |
1861 | * After initialization, the device stays active for as long as that | 1833 | * After initialization, the device stays active for as long as that |
1862 | * $CHIP file is open. Events may then be read from that descriptor, | 1834 | * $CHIP file is open. Events must then be read from that descriptor, |
1863 | * such as configuration notifications. More complex drivers will handle | 1835 | * such as configuration notifications. |
1864 | * some control requests in user space. | ||
1865 | */ | 1836 | */ |
1866 | 1837 | ||
1867 | static int is_valid_config (struct usb_config_descriptor *config) | 1838 | static int is_valid_config (struct usb_config_descriptor *config) |
@@ -1884,9 +1855,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1884 | u32 tag; | 1855 | u32 tag; |
1885 | char *kbuf; | 1856 | char *kbuf; |
1886 | 1857 | ||
1887 | if (dev->state != STATE_OPENED) | ||
1888 | return -EEXIST; | ||
1889 | |||
1890 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) | 1858 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) |
1891 | return -EINVAL; | 1859 | return -EINVAL; |
1892 | 1860 | ||
@@ -1978,13 +1946,15 @@ dev_open (struct inode *inode, struct file *fd) | |||
1978 | struct dev_data *dev = inode->i_private; | 1946 | struct dev_data *dev = inode->i_private; |
1979 | int value = -EBUSY; | 1947 | int value = -EBUSY; |
1980 | 1948 | ||
1949 | spin_lock_irq(&dev->lock); | ||
1981 | if (dev->state == STATE_DEV_DISABLED) { | 1950 | if (dev->state == STATE_DEV_DISABLED) { |
1982 | dev->ev_next = 0; | 1951 | dev->ev_next = 0; |
1983 | dev->state = STATE_OPENED; | 1952 | dev->state = STATE_DEV_OPENED; |
1984 | fd->private_data = dev; | 1953 | fd->private_data = dev; |
1985 | get_dev (dev); | 1954 | get_dev (dev); |
1986 | value = 0; | 1955 | value = 0; |
1987 | } | 1956 | } |
1957 | spin_unlock_irq(&dev->lock); | ||
1988 | return value; | 1958 | return value; |
1989 | } | 1959 | } |
1990 | 1960 | ||
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h index e3bb78524c88..b3fe197e1eeb 100644 --- a/drivers/usb/gadget/lh7a40x_udc.h +++ b/drivers/usb/gadget/lh7a40x_udc.h | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <asm/unaligned.h> | 49 | #include <asm/unaligned.h> |
50 | #include <asm/hardware.h> | 50 | #include <asm/hardware.h> |
51 | 51 | ||
52 | #include <linux/usb_ch9.h> | 52 | #include <linux/usb/ch9.h> |
53 | #include <linux/usb_gadget.h> | 53 | #include <linux/usb_gadget.h> |
54 | 54 | ||
55 | /* | 55 | /* |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 569eb8ccf232..7617ff7bd5ac 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #include <linux/interrupt.h> | 63 | #include <linux/interrupt.h> |
64 | #include <linux/moduleparam.h> | 64 | #include <linux/moduleparam.h> |
65 | #include <linux/device.h> | 65 | #include <linux/device.h> |
66 | #include <linux/usb_ch9.h> | 66 | #include <linux/usb/ch9.h> |
67 | #include <linux/usb_gadget.h> | 67 | #include <linux/usb_gadget.h> |
68 | 68 | ||
69 | #include <asm/byteorder.h> | 69 | #include <asm/byteorder.h> |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index cdcfd42843d4..140104341db4 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/mm.h> | 38 | #include <linux/mm.h> |
39 | #include <linux/moduleparam.h> | 39 | #include <linux/moduleparam.h> |
40 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/usb_ch9.h> | 41 | #include <linux/usb/ch9.h> |
42 | #include <linux/usb_gadget.h> | 42 | #include <linux/usb_gadget.h> |
43 | #include <linux/usb/otg.h> | 43 | #include <linux/usb/otg.h> |
44 | #include <linux/dma-mapping.h> | 44 | #include <linux/dma-mapping.h> |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index b78de9694665..0d225369847d 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <asm/arch/pxa-regs.h> | 56 | #include <asm/arch/pxa-regs.h> |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #include <linux/usb_ch9.h> | 59 | #include <linux/usb/ch9.h> |
60 | #include <linux/usb_gadget.h> | 60 | #include <linux/usb_gadget.h> |
61 | 61 | ||
62 | #include <asm/arch/udc.h> | 62 | #include <asm/arch/udc.h> |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index f8a3ec64635d..6c742a909225 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <asm/unaligned.h> | 43 | #include <asm/unaligned.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
45 | 45 | ||
46 | #include <linux/usb_ch9.h> | 46 | #include <linux/usb/ch9.h> |
47 | #include <linux/usb/cdc.h> | 47 | #include <linux/usb/cdc.h> |
48 | #include <linux/usb_gadget.h> | 48 | #include <linux/usb_gadget.h> |
49 | 49 | ||
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index b1735767660b..3459ea6c6c0b 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | 16 | ||
17 | #include <linux/usb_ch9.h> | 17 | #include <linux/usb/ch9.h> |
18 | #include <linux/usb_gadget.h> | 18 | #include <linux/usb_gadget.h> |
19 | 19 | ||
20 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 40710ea1b490..ebe04e0d2879 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -84,7 +84,7 @@ | |||
84 | #include <asm/system.h> | 84 | #include <asm/system.h> |
85 | #include <asm/unaligned.h> | 85 | #include <asm/unaligned.h> |
86 | 86 | ||
87 | #include <linux/usb_ch9.h> | 87 | #include <linux/usb/ch9.h> |
88 | #include <linux/usb_gadget.h> | 88 | #include <linux/usb_gadget.h> |
89 | 89 | ||
90 | #include "gadget_chips.h" | 90 | #include "gadget_chips.h" |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cc60759083bf..62711870f8ee 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -67,6 +67,11 @@ config USB_EHCI_TT_NEWSCHED | |||
67 | 67 | ||
68 | If unsure, say N. | 68 | If unsure, say N. |
69 | 69 | ||
70 | config USB_EHCI_BIG_ENDIAN_MMIO | ||
71 | bool | ||
72 | depends on USB_EHCI_HCD | ||
73 | default n | ||
74 | |||
70 | config USB_ISP116X_HCD | 75 | config USB_ISP116X_HCD |
71 | tristate "ISP116X HCD support" | 76 | tristate "ISP116X HCD support" |
72 | depends on USB | 77 | depends on USB |
@@ -101,21 +106,48 @@ config USB_OHCI_HCD_PPC_SOC | |||
101 | bool "OHCI support for on-chip PPC USB controller" | 106 | bool "OHCI support for on-chip PPC USB controller" |
102 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) | 107 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) |
103 | default y | 108 | default y |
104 | select USB_OHCI_BIG_ENDIAN | 109 | select USB_OHCI_BIG_ENDIAN_DESC |
110 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
105 | ---help--- | 111 | ---help--- |
106 | Enables support for the USB controller on the MPC52xx or | 112 | Enables support for the USB controller on the MPC52xx or |
107 | STB03xxx processor chip. If unsure, say Y. | 113 | STB03xxx processor chip. If unsure, say Y. |
108 | 114 | ||
115 | config USB_OHCI_HCD_PPC_OF | ||
116 | bool "OHCI support for PPC USB controller on OF platform bus" | ||
117 | depends on USB_OHCI_HCD && PPC_OF | ||
118 | default y | ||
119 | ---help--- | ||
120 | Enables support for the USB controller PowerPC present on the | ||
121 | OpenFirmware platform bus. | ||
122 | |||
123 | config USB_OHCI_HCD_PPC_OF_BE | ||
124 | bool "Support big endian HC" | ||
125 | depends on USB_OHCI_HCD_PPC_OF | ||
126 | default y | ||
127 | select USB_OHCI_BIG_ENDIAN_DESC | ||
128 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
129 | |||
130 | config USB_OHCI_HCD_PPC_OF_LE | ||
131 | bool "Support little endian HC" | ||
132 | depends on USB_OHCI_HCD_PPC_OF | ||
133 | default n | ||
134 | select USB_OHCI_LITTLE_ENDIAN | ||
135 | |||
109 | config USB_OHCI_HCD_PCI | 136 | config USB_OHCI_HCD_PCI |
110 | bool "OHCI support for PCI-bus USB controllers" | 137 | bool "OHCI support for PCI-bus USB controllers" |
111 | depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx) | 138 | depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx || USB_OHCI_HCD_PPC_OF) |
112 | default y | 139 | default y |
113 | select USB_OHCI_LITTLE_ENDIAN | 140 | select USB_OHCI_LITTLE_ENDIAN |
114 | ---help--- | 141 | ---help--- |
115 | Enables support for PCI-bus plug-in USB controller cards. | 142 | Enables support for PCI-bus plug-in USB controller cards. |
116 | If unsure, say Y. | 143 | If unsure, say Y. |
117 | 144 | ||
118 | config USB_OHCI_BIG_ENDIAN | 145 | config USB_OHCI_BIG_ENDIAN_DESC |
146 | bool | ||
147 | depends on USB_OHCI_HCD | ||
148 | default n | ||
149 | |||
150 | config USB_OHCI_BIG_ENDIAN_MMIO | ||
119 | bool | 151 | bool |
120 | depends on USB_OHCI_HCD | 152 | depends on USB_OHCI_HCD |
121 | default n | 153 | default n |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 56349d21e6ea..246afea9e83b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -43,7 +43,7 @@ | |||
43 | */ | 43 | */ |
44 | static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) | 44 | static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) |
45 | { | 45 | { |
46 | u32 params = readl (&ehci->caps->hcs_params); | 46 | u32 params = ehci_readl(ehci, &ehci->caps->hcs_params); |
47 | 47 | ||
48 | ehci_dbg (ehci, | 48 | ehci_dbg (ehci, |
49 | "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", | 49 | "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", |
@@ -87,7 +87,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} | |||
87 | * */ | 87 | * */ |
88 | static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) | 88 | static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) |
89 | { | 89 | { |
90 | u32 params = readl (&ehci->caps->hcc_params); | 90 | u32 params = ehci_readl(ehci, &ehci->caps->hcc_params); |
91 | 91 | ||
92 | if (HCC_ISOC_CACHE (params)) { | 92 | if (HCC_ISOC_CACHE (params)) { |
93 | ehci_dbg (ehci, | 93 | ehci_dbg (ehci, |
@@ -653,7 +653,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
653 | } | 653 | } |
654 | 654 | ||
655 | /* Capability Registers */ | 655 | /* Capability Registers */ |
656 | i = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 656 | i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
657 | temp = scnprintf (next, size, | 657 | temp = scnprintf (next, size, |
658 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" | 658 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" |
659 | "%s\n" | 659 | "%s\n" |
@@ -673,7 +673,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
673 | unsigned count = 256/4; | 673 | unsigned count = 256/4; |
674 | 674 | ||
675 | pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | 675 | pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); |
676 | offset = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | 676 | offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params)); |
677 | while (offset && count--) { | 677 | while (offset && count--) { |
678 | pci_read_config_dword (pdev, offset, &cap); | 678 | pci_read_config_dword (pdev, offset, &cap); |
679 | switch (cap & 0xff) { | 679 | switch (cap & 0xff) { |
@@ -704,50 +704,50 @@ show_registers (struct class_device *class_dev, char *buf) | |||
704 | #endif | 704 | #endif |
705 | 705 | ||
706 | // FIXME interpret both types of params | 706 | // FIXME interpret both types of params |
707 | i = readl (&ehci->caps->hcs_params); | 707 | i = ehci_readl(ehci, &ehci->caps->hcs_params); |
708 | temp = scnprintf (next, size, "structural params 0x%08x\n", i); | 708 | temp = scnprintf (next, size, "structural params 0x%08x\n", i); |
709 | size -= temp; | 709 | size -= temp; |
710 | next += temp; | 710 | next += temp; |
711 | 711 | ||
712 | i = readl (&ehci->caps->hcc_params); | 712 | i = ehci_readl(ehci, &ehci->caps->hcc_params); |
713 | temp = scnprintf (next, size, "capability params 0x%08x\n", i); | 713 | temp = scnprintf (next, size, "capability params 0x%08x\n", i); |
714 | size -= temp; | 714 | size -= temp; |
715 | next += temp; | 715 | next += temp; |
716 | 716 | ||
717 | /* Operational Registers */ | 717 | /* Operational Registers */ |
718 | temp = dbg_status_buf (scratch, sizeof scratch, label, | 718 | temp = dbg_status_buf (scratch, sizeof scratch, label, |
719 | readl (&ehci->regs->status)); | 719 | ehci_readl(ehci, &ehci->regs->status)); |
720 | temp = scnprintf (next, size, fmt, temp, scratch); | 720 | temp = scnprintf (next, size, fmt, temp, scratch); |
721 | size -= temp; | 721 | size -= temp; |
722 | next += temp; | 722 | next += temp; |
723 | 723 | ||
724 | temp = dbg_command_buf (scratch, sizeof scratch, label, | 724 | temp = dbg_command_buf (scratch, sizeof scratch, label, |
725 | readl (&ehci->regs->command)); | 725 | ehci_readl(ehci, &ehci->regs->command)); |
726 | temp = scnprintf (next, size, fmt, temp, scratch); | 726 | temp = scnprintf (next, size, fmt, temp, scratch); |
727 | size -= temp; | 727 | size -= temp; |
728 | next += temp; | 728 | next += temp; |
729 | 729 | ||
730 | temp = dbg_intr_buf (scratch, sizeof scratch, label, | 730 | temp = dbg_intr_buf (scratch, sizeof scratch, label, |
731 | readl (&ehci->regs->intr_enable)); | 731 | ehci_readl(ehci, &ehci->regs->intr_enable)); |
732 | temp = scnprintf (next, size, fmt, temp, scratch); | 732 | temp = scnprintf (next, size, fmt, temp, scratch); |
733 | size -= temp; | 733 | size -= temp; |
734 | next += temp; | 734 | next += temp; |
735 | 735 | ||
736 | temp = scnprintf (next, size, "uframe %04x\n", | 736 | temp = scnprintf (next, size, "uframe %04x\n", |
737 | readl (&ehci->regs->frame_index)); | 737 | ehci_readl(ehci, &ehci->regs->frame_index)); |
738 | size -= temp; | 738 | size -= temp; |
739 | next += temp; | 739 | next += temp; |
740 | 740 | ||
741 | for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { | 741 | for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { |
742 | temp = dbg_port_buf (scratch, sizeof scratch, label, i, | 742 | temp = dbg_port_buf (scratch, sizeof scratch, label, i, |
743 | readl (&ehci->regs->port_status [i - 1])); | 743 | ehci_readl(ehci, &ehci->regs->port_status [i - 1])); |
744 | temp = scnprintf (next, size, fmt, temp, scratch); | 744 | temp = scnprintf (next, size, fmt, temp, scratch); |
745 | size -= temp; | 745 | size -= temp; |
746 | next += temp; | 746 | next += temp; |
747 | if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { | 747 | if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { |
748 | temp = scnprintf (next, size, | 748 | temp = scnprintf (next, size, |
749 | " debug control %08x\n", | 749 | " debug control %08x\n", |
750 | readl (&ehci->debug->control)); | 750 | ehci_readl(ehci, &ehci->debug->control)); |
751 | size -= temp; | 751 | size -= temp; |
752 | next += temp; | 752 | next += temp; |
753 | } | 753 | } |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 1a915e982c1c..a52480505f78 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -177,7 +177,7 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci, | |||
177 | case FSL_USB2_PHY_NONE: | 177 | case FSL_USB2_PHY_NONE: |
178 | break; | 178 | break; |
179 | } | 179 | } |
180 | writel(portsc, &ehci->regs->port_status[port_offset]); | 180 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); |
181 | } | 181 | } |
182 | 182 | ||
183 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) | 183 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) |
@@ -214,7 +214,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | /* put controller in host mode. */ | 216 | /* put controller in host mode. */ |
217 | writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE); | 217 | ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE); |
218 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); | 218 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); |
219 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); | 219 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); |
220 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); | 220 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); |
@@ -238,12 +238,12 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
238 | /* EHCI registers start at offset 0x100 */ | 238 | /* EHCI registers start at offset 0x100 */ |
239 | ehci->caps = hcd->regs + 0x100; | 239 | ehci->caps = hcd->regs + 0x100; |
240 | ehci->regs = hcd->regs + 0x100 + | 240 | ehci->regs = hcd->regs + 0x100 + |
241 | HC_LENGTH(readl(&ehci->caps->hc_capbase)); | 241 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
242 | dbg_hcs_params(ehci, "reset"); | 242 | dbg_hcs_params(ehci, "reset"); |
243 | dbg_hcc_params(ehci, "reset"); | 243 | dbg_hcc_params(ehci, "reset"); |
244 | 244 | ||
245 | /* cache this readonly data; minimize chip reads */ | 245 | /* cache this readonly data; minimize chip reads */ |
246 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 246 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
247 | 247 | ||
248 | retval = ehci_halt(ehci); | 248 | retval = ehci_halt(ehci); |
249 | if (retval) | 249 | if (retval) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 025d33313681..185721dba42b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -157,12 +157,13 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); | |||
157 | * before driver shutdown. But it also seems to be caused by bugs in cardbus | 157 | * before driver shutdown. But it also seems to be caused by bugs in cardbus |
158 | * bridge shutdown: shutting down the bridge before the devices using it. | 158 | * bridge shutdown: shutting down the bridge before the devices using it. |
159 | */ | 159 | */ |
160 | static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) | 160 | static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, |
161 | u32 mask, u32 done, int usec) | ||
161 | { | 162 | { |
162 | u32 result; | 163 | u32 result; |
163 | 164 | ||
164 | do { | 165 | do { |
165 | result = readl (ptr); | 166 | result = ehci_readl(ehci, ptr); |
166 | if (result == ~(u32)0) /* card removed */ | 167 | if (result == ~(u32)0) /* card removed */ |
167 | return -ENODEV; | 168 | return -ENODEV; |
168 | result &= mask; | 169 | result &= mask; |
@@ -177,18 +178,19 @@ static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) | |||
177 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ | 178 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ |
178 | static int ehci_halt (struct ehci_hcd *ehci) | 179 | static int ehci_halt (struct ehci_hcd *ehci) |
179 | { | 180 | { |
180 | u32 temp = readl (&ehci->regs->status); | 181 | u32 temp = ehci_readl(ehci, &ehci->regs->status); |
181 | 182 | ||
182 | /* disable any irqs left enabled by previous code */ | 183 | /* disable any irqs left enabled by previous code */ |
183 | writel (0, &ehci->regs->intr_enable); | 184 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
184 | 185 | ||
185 | if ((temp & STS_HALT) != 0) | 186 | if ((temp & STS_HALT) != 0) |
186 | return 0; | 187 | return 0; |
187 | 188 | ||
188 | temp = readl (&ehci->regs->command); | 189 | temp = ehci_readl(ehci, &ehci->regs->command); |
189 | temp &= ~CMD_RUN; | 190 | temp &= ~CMD_RUN; |
190 | writel (temp, &ehci->regs->command); | 191 | ehci_writel(ehci, temp, &ehci->regs->command); |
191 | return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); | 192 | return handshake (ehci, &ehci->regs->status, |
193 | STS_HALT, STS_HALT, 16 * 125); | ||
192 | } | 194 | } |
193 | 195 | ||
194 | /* put TDI/ARC silicon into EHCI mode */ | 196 | /* put TDI/ARC silicon into EHCI mode */ |
@@ -198,23 +200,24 @@ static void tdi_reset (struct ehci_hcd *ehci) | |||
198 | u32 tmp; | 200 | u32 tmp; |
199 | 201 | ||
200 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); | 202 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); |
201 | tmp = readl (reg_ptr); | 203 | tmp = ehci_readl(ehci, reg_ptr); |
202 | tmp |= 0x3; | 204 | tmp |= 0x3; |
203 | writel (tmp, reg_ptr); | 205 | ehci_writel(ehci, tmp, reg_ptr); |
204 | } | 206 | } |
205 | 207 | ||
206 | /* reset a non-running (STS_HALT == 1) controller */ | 208 | /* reset a non-running (STS_HALT == 1) controller */ |
207 | static int ehci_reset (struct ehci_hcd *ehci) | 209 | static int ehci_reset (struct ehci_hcd *ehci) |
208 | { | 210 | { |
209 | int retval; | 211 | int retval; |
210 | u32 command = readl (&ehci->regs->command); | 212 | u32 command = ehci_readl(ehci, &ehci->regs->command); |
211 | 213 | ||
212 | command |= CMD_RESET; | 214 | command |= CMD_RESET; |
213 | dbg_cmd (ehci, "reset", command); | 215 | dbg_cmd (ehci, "reset", command); |
214 | writel (command, &ehci->regs->command); | 216 | ehci_writel(ehci, command, &ehci->regs->command); |
215 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 217 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
216 | ehci->next_statechange = jiffies; | 218 | ehci->next_statechange = jiffies; |
217 | retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); | 219 | retval = handshake (ehci, &ehci->regs->command, |
220 | CMD_RESET, 0, 250 * 1000); | ||
218 | 221 | ||
219 | if (retval) | 222 | if (retval) |
220 | return retval; | 223 | return retval; |
@@ -236,21 +239,21 @@ static void ehci_quiesce (struct ehci_hcd *ehci) | |||
236 | #endif | 239 | #endif |
237 | 240 | ||
238 | /* wait for any schedule enables/disables to take effect */ | 241 | /* wait for any schedule enables/disables to take effect */ |
239 | temp = readl (&ehci->regs->command) << 10; | 242 | temp = ehci_readl(ehci, &ehci->regs->command) << 10; |
240 | temp &= STS_ASS | STS_PSS; | 243 | temp &= STS_ASS | STS_PSS; |
241 | if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, | 244 | if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, |
242 | temp, 16 * 125) != 0) { | 245 | temp, 16 * 125) != 0) { |
243 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 246 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
244 | return; | 247 | return; |
245 | } | 248 | } |
246 | 249 | ||
247 | /* then disable anything that's still active */ | 250 | /* then disable anything that's still active */ |
248 | temp = readl (&ehci->regs->command); | 251 | temp = ehci_readl(ehci, &ehci->regs->command); |
249 | temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); | 252 | temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); |
250 | writel (temp, &ehci->regs->command); | 253 | ehci_writel(ehci, temp, &ehci->regs->command); |
251 | 254 | ||
252 | /* hardware can take 16 microframes to turn off ... */ | 255 | /* hardware can take 16 microframes to turn off ... */ |
253 | if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, | 256 | if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, |
254 | 0, 16 * 125) != 0) { | 257 | 0, 16 * 125) != 0) { |
255 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 258 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
256 | return; | 259 | return; |
@@ -277,11 +280,11 @@ static void ehci_watchdog (unsigned long param) | |||
277 | 280 | ||
278 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ | 281 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ |
279 | if (ehci->reclaim) { | 282 | if (ehci->reclaim) { |
280 | u32 status = readl (&ehci->regs->status); | 283 | u32 status = ehci_readl(ehci, &ehci->regs->status); |
281 | if (status & STS_IAA) { | 284 | if (status & STS_IAA) { |
282 | ehci_vdbg (ehci, "lost IAA\n"); | 285 | ehci_vdbg (ehci, "lost IAA\n"); |
283 | COUNT (ehci->stats.lost_iaa); | 286 | COUNT (ehci->stats.lost_iaa); |
284 | writel (STS_IAA, &ehci->regs->status); | 287 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); |
285 | ehci->reclaim_ready = 1; | 288 | ehci->reclaim_ready = 1; |
286 | } | 289 | } |
287 | } | 290 | } |
@@ -309,7 +312,7 @@ ehci_shutdown (struct usb_hcd *hcd) | |||
309 | (void) ehci_halt (ehci); | 312 | (void) ehci_halt (ehci); |
310 | 313 | ||
311 | /* make BIOS/etc use companion controller during reboot */ | 314 | /* make BIOS/etc use companion controller during reboot */ |
312 | writel (0, &ehci->regs->configured_flag); | 315 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
313 | } | 316 | } |
314 | 317 | ||
315 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | 318 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) |
@@ -379,12 +382,13 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
379 | ehci_quiesce (ehci); | 382 | ehci_quiesce (ehci); |
380 | 383 | ||
381 | ehci_reset (ehci); | 384 | ehci_reset (ehci); |
382 | writel (0, &ehci->regs->intr_enable); | 385 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
383 | spin_unlock_irq(&ehci->lock); | 386 | spin_unlock_irq(&ehci->lock); |
384 | 387 | ||
385 | /* let companion controllers work when we aren't */ | 388 | /* let companion controllers work when we aren't */ |
386 | writel (0, &ehci->regs->configured_flag); | 389 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
387 | 390 | ||
391 | remove_companion_file(ehci); | ||
388 | remove_debug_files (ehci); | 392 | remove_debug_files (ehci); |
389 | 393 | ||
390 | /* root hub is shut down separately (first, when possible) */ | 394 | /* root hub is shut down separately (first, when possible) */ |
@@ -402,7 +406,8 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
402 | ehci->stats.complete, ehci->stats.unlink); | 406 | ehci->stats.complete, ehci->stats.unlink); |
403 | #endif | 407 | #endif |
404 | 408 | ||
405 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); | 409 | dbg_status (ehci, "ehci_stop completed", |
410 | ehci_readl(ehci, &ehci->regs->status)); | ||
406 | } | 411 | } |
407 | 412 | ||
408 | /* one-time init, only for memory state */ | 413 | /* one-time init, only for memory state */ |
@@ -428,7 +433,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
428 | return retval; | 433 | return retval; |
429 | 434 | ||
430 | /* controllers may cache some of the periodic schedule ... */ | 435 | /* controllers may cache some of the periodic schedule ... */ |
431 | hcc_params = readl(&ehci->caps->hcc_params); | 436 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); |
432 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache | 437 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache |
433 | ehci->i_thresh = 8; | 438 | ehci->i_thresh = 8; |
434 | else // N microframes cached | 439 | else // N microframes cached |
@@ -496,13 +501,16 @@ static int ehci_run (struct usb_hcd *hcd) | |||
496 | u32 temp; | 501 | u32 temp; |
497 | u32 hcc_params; | 502 | u32 hcc_params; |
498 | 503 | ||
504 | hcd->uses_new_polling = 1; | ||
505 | hcd->poll_rh = 0; | ||
506 | |||
499 | /* EHCI spec section 4.1 */ | 507 | /* EHCI spec section 4.1 */ |
500 | if ((retval = ehci_reset(ehci)) != 0) { | 508 | if ((retval = ehci_reset(ehci)) != 0) { |
501 | ehci_mem_cleanup(ehci); | 509 | ehci_mem_cleanup(ehci); |
502 | return retval; | 510 | return retval; |
503 | } | 511 | } |
504 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | 512 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
505 | writel((u32)ehci->async->qh_dma, &ehci->regs->async_next); | 513 | ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); |
506 | 514 | ||
507 | /* | 515 | /* |
508 | * hcc_params controls whether ehci->regs->segment must (!!!) | 516 | * hcc_params controls whether ehci->regs->segment must (!!!) |
@@ -516,9 +524,9 @@ static int ehci_run (struct usb_hcd *hcd) | |||
516 | * Scsi_Host.highmem_io, and so forth. It's readonly to all | 524 | * Scsi_Host.highmem_io, and so forth. It's readonly to all |
517 | * host side drivers though. | 525 | * host side drivers though. |
518 | */ | 526 | */ |
519 | hcc_params = readl(&ehci->caps->hcc_params); | 527 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); |
520 | if (HCC_64BIT_ADDR(hcc_params)) { | 528 | if (HCC_64BIT_ADDR(hcc_params)) { |
521 | writel(0, &ehci->regs->segment); | 529 | ehci_writel(ehci, 0, &ehci->regs->segment); |
522 | #if 0 | 530 | #if 0 |
523 | // this is deeply broken on almost all architectures | 531 | // this is deeply broken on almost all architectures |
524 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) | 532 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) |
@@ -531,7 +539,7 @@ static int ehci_run (struct usb_hcd *hcd) | |||
531 | // root hub will detect new devices (why?); NEC doesn't | 539 | // root hub will detect new devices (why?); NEC doesn't |
532 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); | 540 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); |
533 | ehci->command |= CMD_RUN; | 541 | ehci->command |= CMD_RUN; |
534 | writel (ehci->command, &ehci->regs->command); | 542 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
535 | dbg_cmd (ehci, "init", ehci->command); | 543 | dbg_cmd (ehci, "init", ehci->command); |
536 | 544 | ||
537 | /* | 545 | /* |
@@ -541,23 +549,25 @@ static int ehci_run (struct usb_hcd *hcd) | |||
541 | * and there's no companion controller unless maybe for USB OTG.) | 549 | * and there's no companion controller unless maybe for USB OTG.) |
542 | */ | 550 | */ |
543 | hcd->state = HC_STATE_RUNNING; | 551 | hcd->state = HC_STATE_RUNNING; |
544 | writel (FLAG_CF, &ehci->regs->configured_flag); | 552 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
545 | readl (&ehci->regs->command); /* unblock posted writes */ | 553 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
546 | 554 | ||
547 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 555 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
548 | ehci_info (ehci, | 556 | ehci_info (ehci, |
549 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", | 557 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", |
550 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), | 558 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
551 | temp >> 8, temp & 0xff, DRIVER_VERSION, | 559 | temp >> 8, temp & 0xff, DRIVER_VERSION, |
552 | ignore_oc ? ", overcurrent ignored" : ""); | 560 | ignore_oc ? ", overcurrent ignored" : ""); |
553 | 561 | ||
554 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ | 562 | ehci_writel(ehci, INTR_MASK, |
563 | &ehci->regs->intr_enable); /* Turn On Interrupts */ | ||
555 | 564 | ||
556 | /* GRR this is run-once init(), being done every time the HC starts. | 565 | /* GRR this is run-once init(), being done every time the HC starts. |
557 | * So long as they're part of class devices, we can't do it init() | 566 | * So long as they're part of class devices, we can't do it init() |
558 | * since the class device isn't created that early. | 567 | * since the class device isn't created that early. |
559 | */ | 568 | */ |
560 | create_debug_files(ehci); | 569 | create_debug_files(ehci); |
570 | create_companion_file(ehci); | ||
561 | 571 | ||
562 | return 0; | 572 | return 0; |
563 | } | 573 | } |
@@ -567,12 +577,12 @@ static int ehci_run (struct usb_hcd *hcd) | |||
567 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 577 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
568 | { | 578 | { |
569 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 579 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
570 | u32 status; | 580 | u32 status, pcd_status = 0; |
571 | int bh; | 581 | int bh; |
572 | 582 | ||
573 | spin_lock (&ehci->lock); | 583 | spin_lock (&ehci->lock); |
574 | 584 | ||
575 | status = readl (&ehci->regs->status); | 585 | status = ehci_readl(ehci, &ehci->regs->status); |
576 | 586 | ||
577 | /* e.g. cardbus physical eject */ | 587 | /* e.g. cardbus physical eject */ |
578 | if (status == ~(u32) 0) { | 588 | if (status == ~(u32) 0) { |
@@ -587,8 +597,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
587 | } | 597 | } |
588 | 598 | ||
589 | /* clear (just) interrupts */ | 599 | /* clear (just) interrupts */ |
590 | writel (status, &ehci->regs->status); | 600 | ehci_writel(ehci, status, &ehci->regs->status); |
591 | readl (&ehci->regs->command); /* unblock posted write */ | 601 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ |
592 | bh = 0; | 602 | bh = 0; |
593 | 603 | ||
594 | #ifdef EHCI_VERBOSE_DEBUG | 604 | #ifdef EHCI_VERBOSE_DEBUG |
@@ -617,13 +627,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
617 | /* remote wakeup [4.3.1] */ | 627 | /* remote wakeup [4.3.1] */ |
618 | if (status & STS_PCD) { | 628 | if (status & STS_PCD) { |
619 | unsigned i = HCS_N_PORTS (ehci->hcs_params); | 629 | unsigned i = HCS_N_PORTS (ehci->hcs_params); |
630 | pcd_status = status; | ||
620 | 631 | ||
621 | /* resume root hub? */ | 632 | /* resume root hub? */ |
622 | if (!(readl(&ehci->regs->command) & CMD_RUN)) | 633 | if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN)) |
623 | usb_hcd_resume_root_hub(hcd); | 634 | usb_hcd_resume_root_hub(hcd); |
624 | 635 | ||
625 | while (i--) { | 636 | while (i--) { |
626 | int pstatus = readl (&ehci->regs->port_status [i]); | 637 | int pstatus = ehci_readl(ehci, |
638 | &ehci->regs->port_status [i]); | ||
627 | 639 | ||
628 | if (pstatus & PORT_OWNER) | 640 | if (pstatus & PORT_OWNER) |
629 | continue; | 641 | continue; |
@@ -643,14 +655,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
643 | /* PCI errors [4.15.2.4] */ | 655 | /* PCI errors [4.15.2.4] */ |
644 | if (unlikely ((status & STS_FATAL) != 0)) { | 656 | if (unlikely ((status & STS_FATAL) != 0)) { |
645 | /* bogus "fatal" IRQs appear on some chips... why? */ | 657 | /* bogus "fatal" IRQs appear on some chips... why? */ |
646 | status = readl (&ehci->regs->status); | 658 | status = ehci_readl(ehci, &ehci->regs->status); |
647 | dbg_cmd (ehci, "fatal", readl (&ehci->regs->command)); | 659 | dbg_cmd (ehci, "fatal", ehci_readl(ehci, |
660 | &ehci->regs->command)); | ||
648 | dbg_status (ehci, "fatal", status); | 661 | dbg_status (ehci, "fatal", status); |
649 | if (status & STS_HALT) { | 662 | if (status & STS_HALT) { |
650 | ehci_err (ehci, "fatal error\n"); | 663 | ehci_err (ehci, "fatal error\n"); |
651 | dead: | 664 | dead: |
652 | ehci_reset (ehci); | 665 | ehci_reset (ehci); |
653 | writel (0, &ehci->regs->configured_flag); | 666 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
654 | /* generic layer kills/unlinks all urbs, then | 667 | /* generic layer kills/unlinks all urbs, then |
655 | * uses ehci_stop to clean up the rest | 668 | * uses ehci_stop to clean up the rest |
656 | */ | 669 | */ |
@@ -661,6 +674,8 @@ dead: | |||
661 | if (bh) | 674 | if (bh) |
662 | ehci_work (ehci); | 675 | ehci_work (ehci); |
663 | spin_unlock (&ehci->lock); | 676 | spin_unlock (&ehci->lock); |
677 | if (pcd_status & STS_PCD) | ||
678 | usb_hcd_poll_rh_status(hcd); | ||
664 | return IRQ_HANDLED; | 679 | return IRQ_HANDLED; |
665 | } | 680 | } |
666 | 681 | ||
@@ -873,7 +888,8 @@ done: | |||
873 | static int ehci_get_frame (struct usb_hcd *hcd) | 888 | static int ehci_get_frame (struct usb_hcd *hcd) |
874 | { | 889 | { |
875 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 890 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
876 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; | 891 | return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % |
892 | ehci->periodic_size; | ||
877 | } | 893 | } |
878 | 894 | ||
879 | /*-------------------------------------------------------------------------*/ | 895 | /*-------------------------------------------------------------------------*/ |
@@ -899,7 +915,13 @@ MODULE_LICENSE ("GPL"); | |||
899 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver | 915 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver |
900 | #endif | 916 | #endif |
901 | 917 | ||
902 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) | 918 | #ifdef CONFIG_PPC_PS3 |
919 | #include "ehci-ps3.c" | ||
920 | #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_sb_driver | ||
921 | #endif | ||
922 | |||
923 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | ||
924 | !defined(PS3_SYSTEM_BUS_DRIVER) | ||
903 | #error "missing bus glue for ehci-hcd" | 925 | #error "missing bus glue for ehci-hcd" |
904 | #endif | 926 | #endif |
905 | 927 | ||
@@ -924,6 +946,20 @@ static int __init ehci_hcd_init(void) | |||
924 | #ifdef PLATFORM_DRIVER | 946 | #ifdef PLATFORM_DRIVER |
925 | platform_driver_unregister(&PLATFORM_DRIVER); | 947 | platform_driver_unregister(&PLATFORM_DRIVER); |
926 | #endif | 948 | #endif |
949 | return retval; | ||
950 | } | ||
951 | #endif | ||
952 | |||
953 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
954 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | ||
955 | if (retval < 0) { | ||
956 | #ifdef PLATFORM_DRIVER | ||
957 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
958 | #endif | ||
959 | #ifdef PCI_DRIVER | ||
960 | pci_unregister_driver(&PCI_DRIVER); | ||
961 | #endif | ||
962 | return retval; | ||
927 | } | 963 | } |
928 | #endif | 964 | #endif |
929 | 965 | ||
@@ -939,6 +975,9 @@ static void __exit ehci_hcd_cleanup(void) | |||
939 | #ifdef PCI_DRIVER | 975 | #ifdef PCI_DRIVER |
940 | pci_unregister_driver(&PCI_DRIVER); | 976 | pci_unregister_driver(&PCI_DRIVER); |
941 | #endif | 977 | #endif |
978 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
979 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
980 | #endif | ||
942 | } | 981 | } |
943 | module_exit(ehci_hcd_cleanup); | 982 | module_exit(ehci_hcd_cleanup); |
944 | 983 | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index bfe5f307cba6..0d83c6df1a3b 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -47,7 +47,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
47 | ehci_quiesce (ehci); | 47 | ehci_quiesce (ehci); |
48 | hcd->state = HC_STATE_QUIESCING; | 48 | hcd->state = HC_STATE_QUIESCING; |
49 | } | 49 | } |
50 | ehci->command = readl (&ehci->regs->command); | 50 | ehci->command = ehci_readl(ehci, &ehci->regs->command); |
51 | if (ehci->reclaim) | 51 | if (ehci->reclaim) |
52 | ehci->reclaim_ready = 1; | 52 | ehci->reclaim_ready = 1; |
53 | ehci_work(ehci); | 53 | ehci_work(ehci); |
@@ -60,7 +60,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
60 | ehci->bus_suspended = 0; | 60 | ehci->bus_suspended = 0; |
61 | while (port--) { | 61 | while (port--) { |
62 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 62 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
63 | u32 t1 = readl (reg) & ~PORT_RWC_BITS; | 63 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |
64 | u32 t2 = t1; | 64 | u32 t2 = t1; |
65 | 65 | ||
66 | /* keep track of which ports we suspend */ | 66 | /* keep track of which ports we suspend */ |
@@ -79,7 +79,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
79 | if (t1 != t2) { | 79 | if (t1 != t2) { |
80 | ehci_vdbg (ehci, "port %d, %08x -> %08x\n", | 80 | ehci_vdbg (ehci, "port %d, %08x -> %08x\n", |
81 | port + 1, t1, t2); | 81 | port + 1, t1, t2); |
82 | writel (t2, reg); | 82 | ehci_writel(ehci, t2, reg); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
@@ -92,8 +92,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
92 | mask = INTR_MASK; | 92 | mask = INTR_MASK; |
93 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) | 93 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) |
94 | mask &= ~STS_PCD; | 94 | mask &= ~STS_PCD; |
95 | writel(mask, &ehci->regs->intr_enable); | 95 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); |
96 | readl(&ehci->regs->intr_enable); | 96 | ehci_readl(ehci, &ehci->regs->intr_enable); |
97 | 97 | ||
98 | ehci->next_statechange = jiffies + msecs_to_jiffies(10); | 98 | ehci->next_statechange = jiffies + msecs_to_jiffies(10); |
99 | spin_unlock_irq (&ehci->lock); | 99 | spin_unlock_irq (&ehci->lock); |
@@ -118,26 +118,26 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
118 | * the last user of the controller, not reset/pm hardware keeping | 118 | * the last user of the controller, not reset/pm hardware keeping |
119 | * state we gave to it. | 119 | * state we gave to it. |
120 | */ | 120 | */ |
121 | temp = readl(&ehci->regs->intr_enable); | 121 | temp = ehci_readl(ehci, &ehci->regs->intr_enable); |
122 | ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); | 122 | ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); |
123 | 123 | ||
124 | /* at least some APM implementations will try to deliver | 124 | /* at least some APM implementations will try to deliver |
125 | * IRQs right away, so delay them until we're ready. | 125 | * IRQs right away, so delay them until we're ready. |
126 | */ | 126 | */ |
127 | writel(0, &ehci->regs->intr_enable); | 127 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
128 | 128 | ||
129 | /* re-init operational registers */ | 129 | /* re-init operational registers */ |
130 | writel(0, &ehci->regs->segment); | 130 | ehci_writel(ehci, 0, &ehci->regs->segment); |
131 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | 131 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
132 | writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); | 132 | ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next); |
133 | 133 | ||
134 | /* restore CMD_RUN, framelist size, and irq threshold */ | 134 | /* restore CMD_RUN, framelist size, and irq threshold */ |
135 | writel (ehci->command, &ehci->regs->command); | 135 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
136 | 136 | ||
137 | /* manually resume the ports we suspended during bus_suspend() */ | 137 | /* manually resume the ports we suspended during bus_suspend() */ |
138 | i = HCS_N_PORTS (ehci->hcs_params); | 138 | i = HCS_N_PORTS (ehci->hcs_params); |
139 | while (i--) { | 139 | while (i--) { |
140 | temp = readl (&ehci->regs->port_status [i]); | 140 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
141 | temp &= ~(PORT_RWC_BITS | 141 | temp &= ~(PORT_RWC_BITS |
142 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); | 142 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); |
143 | if (test_bit(i, &ehci->bus_suspended) && | 143 | if (test_bit(i, &ehci->bus_suspended) && |
@@ -145,20 +145,20 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
145 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | 145 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); |
146 | temp |= PORT_RESUME; | 146 | temp |= PORT_RESUME; |
147 | } | 147 | } |
148 | writel (temp, &ehci->regs->port_status [i]); | 148 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
149 | } | 149 | } |
150 | i = HCS_N_PORTS (ehci->hcs_params); | 150 | i = HCS_N_PORTS (ehci->hcs_params); |
151 | mdelay (20); | 151 | mdelay (20); |
152 | while (i--) { | 152 | while (i--) { |
153 | temp = readl (&ehci->regs->port_status [i]); | 153 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
154 | if (test_bit(i, &ehci->bus_suspended) && | 154 | if (test_bit(i, &ehci->bus_suspended) && |
155 | (temp & PORT_SUSPEND)) { | 155 | (temp & PORT_SUSPEND)) { |
156 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); | 156 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); |
157 | writel (temp, &ehci->regs->port_status [i]); | 157 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
158 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); | 158 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); |
159 | } | 159 | } |
160 | } | 160 | } |
161 | (void) readl (&ehci->regs->command); | 161 | (void) ehci_readl(ehci, &ehci->regs->command); |
162 | 162 | ||
163 | /* maybe re-activate the schedule(s) */ | 163 | /* maybe re-activate the schedule(s) */ |
164 | temp = 0; | 164 | temp = 0; |
@@ -168,14 +168,14 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
168 | temp |= CMD_PSE; | 168 | temp |= CMD_PSE; |
169 | if (temp) { | 169 | if (temp) { |
170 | ehci->command |= temp; | 170 | ehci->command |= temp; |
171 | writel (ehci->command, &ehci->regs->command); | 171 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
172 | } | 172 | } |
173 | 173 | ||
174 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); | 174 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); |
175 | hcd->state = HC_STATE_RUNNING; | 175 | hcd->state = HC_STATE_RUNNING; |
176 | 176 | ||
177 | /* Now we can safely re-enable irqs */ | 177 | /* Now we can safely re-enable irqs */ |
178 | writel(INTR_MASK, &ehci->regs->intr_enable); | 178 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); |
179 | 179 | ||
180 | spin_unlock_irq (&ehci->lock); | 180 | spin_unlock_irq (&ehci->lock); |
181 | return 0; | 181 | return 0; |
@@ -190,9 +190,107 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
190 | 190 | ||
191 | /*-------------------------------------------------------------------------*/ | 191 | /*-------------------------------------------------------------------------*/ |
192 | 192 | ||
193 | /* Display the ports dedicated to the companion controller */ | ||
194 | static ssize_t show_companion(struct class_device *class_dev, char *buf) | ||
195 | { | ||
196 | struct ehci_hcd *ehci; | ||
197 | int nports, index, n; | ||
198 | int count = PAGE_SIZE; | ||
199 | char *ptr = buf; | ||
200 | |||
201 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | ||
202 | nports = HCS_N_PORTS(ehci->hcs_params); | ||
203 | |||
204 | for (index = 0; index < nports; ++index) { | ||
205 | if (test_bit(index, &ehci->companion_ports)) { | ||
206 | n = scnprintf(ptr, count, "%d\n", index + 1); | ||
207 | ptr += n; | ||
208 | count -= n; | ||
209 | } | ||
210 | } | ||
211 | return ptr - buf; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Dedicate or undedicate a port to the companion controller. | ||
216 | * Syntax is "[-]portnum", where a leading '-' sign means | ||
217 | * return control of the port to the EHCI controller. | ||
218 | */ | ||
219 | static ssize_t store_companion(struct class_device *class_dev, | ||
220 | const char *buf, size_t count) | ||
221 | { | ||
222 | struct ehci_hcd *ehci; | ||
223 | int portnum, new_owner, try; | ||
224 | u32 __iomem *status_reg; | ||
225 | u32 port_status; | ||
226 | |||
227 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | ||
228 | new_owner = PORT_OWNER; /* Owned by companion */ | ||
229 | if (sscanf(buf, "%d", &portnum) != 1) | ||
230 | return -EINVAL; | ||
231 | if (portnum < 0) { | ||
232 | portnum = - portnum; | ||
233 | new_owner = 0; /* Owned by EHCI */ | ||
234 | } | ||
235 | if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params)) | ||
236 | return -ENOENT; | ||
237 | status_reg = &ehci->regs->port_status[--portnum]; | ||
238 | if (new_owner) | ||
239 | set_bit(portnum, &ehci->companion_ports); | ||
240 | else | ||
241 | clear_bit(portnum, &ehci->companion_ports); | ||
242 | |||
243 | /* | ||
244 | * The controller won't set the OWNER bit if the port is | ||
245 | * enabled, so this loop will sometimes require at least two | ||
246 | * iterations: one to disable the port and one to set OWNER. | ||
247 | */ | ||
248 | |||
249 | for (try = 4; try > 0; --try) { | ||
250 | spin_lock_irq(&ehci->lock); | ||
251 | port_status = ehci_readl(ehci, status_reg); | ||
252 | if ((port_status & PORT_OWNER) == new_owner | ||
253 | || (port_status & (PORT_OWNER | PORT_CONNECT)) | ||
254 | == 0) | ||
255 | try = 0; | ||
256 | else { | ||
257 | port_status ^= PORT_OWNER; | ||
258 | port_status &= ~(PORT_PE | PORT_RWC_BITS); | ||
259 | ehci_writel(ehci, port_status, status_reg); | ||
260 | } | ||
261 | spin_unlock_irq(&ehci->lock); | ||
262 | if (try > 1) | ||
263 | msleep(5); | ||
264 | } | ||
265 | return count; | ||
266 | } | ||
267 | static CLASS_DEVICE_ATTR(companion, 0644, show_companion, store_companion); | ||
268 | |||
269 | static inline void create_companion_file(struct ehci_hcd *ehci) | ||
270 | { | ||
271 | int i; | ||
272 | |||
273 | /* with integrated TT there is no companion! */ | ||
274 | if (!ehci_is_TDI(ehci)) | ||
275 | i = class_device_create_file(ehci_to_hcd(ehci)->self.class_dev, | ||
276 | &class_device_attr_companion); | ||
277 | } | ||
278 | |||
279 | static inline void remove_companion_file(struct ehci_hcd *ehci) | ||
280 | { | ||
281 | /* with integrated TT there is no companion! */ | ||
282 | if (!ehci_is_TDI(ehci)) | ||
283 | class_device_remove_file(ehci_to_hcd(ehci)->self.class_dev, | ||
284 | &class_device_attr_companion); | ||
285 | } | ||
286 | |||
287 | |||
288 | /*-------------------------------------------------------------------------*/ | ||
289 | |||
193 | static int check_reset_complete ( | 290 | static int check_reset_complete ( |
194 | struct ehci_hcd *ehci, | 291 | struct ehci_hcd *ehci, |
195 | int index, | 292 | int index, |
293 | u32 __iomem *status_reg, | ||
196 | int port_status | 294 | int port_status |
197 | ) { | 295 | ) { |
198 | if (!(port_status & PORT_CONNECT)) { | 296 | if (!(port_status & PORT_CONNECT)) { |
@@ -217,7 +315,7 @@ static int check_reset_complete ( | |||
217 | // what happens if HCS_N_CC(params) == 0 ? | 315 | // what happens if HCS_N_CC(params) == 0 ? |
218 | port_status |= PORT_OWNER; | 316 | port_status |= PORT_OWNER; |
219 | port_status &= ~PORT_RWC_BITS; | 317 | port_status &= ~PORT_RWC_BITS; |
220 | writel (port_status, &ehci->regs->port_status [index]); | 318 | ehci_writel(ehci, port_status, status_reg); |
221 | 319 | ||
222 | } else | 320 | } else |
223 | ehci_dbg (ehci, "port %d high speed\n", index + 1); | 321 | ehci_dbg (ehci, "port %d high speed\n", index + 1); |
@@ -268,22 +366,21 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
268 | /* port N changes (bit N)? */ | 366 | /* port N changes (bit N)? */ |
269 | spin_lock_irqsave (&ehci->lock, flags); | 367 | spin_lock_irqsave (&ehci->lock, flags); |
270 | for (i = 0; i < ports; i++) { | 368 | for (i = 0; i < ports; i++) { |
271 | temp = readl (&ehci->regs->port_status [i]); | 369 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
272 | if (temp & PORT_OWNER) { | 370 | |
273 | /* don't report this in GetPortStatus */ | 371 | /* |
274 | if (temp & PORT_CSC) { | 372 | * Return status information even for ports with OWNER set. |
275 | temp &= ~PORT_RWC_BITS; | 373 | * Otherwise khubd wouldn't see the disconnect event when a |
276 | temp |= PORT_CSC; | 374 | * high-speed device is switched over to the companion |
277 | writel (temp, &ehci->regs->port_status [i]); | 375 | * controller by the user. |
278 | } | 376 | */ |
279 | continue; | 377 | |
280 | } | ||
281 | if (!(temp & PORT_CONNECT)) | 378 | if (!(temp & PORT_CONNECT)) |
282 | ehci->reset_done [i] = 0; | 379 | ehci->reset_done [i] = 0; |
283 | if ((temp & mask) != 0 | 380 | if ((temp & mask) != 0 |
284 | || ((temp & PORT_RESUME) != 0 | 381 | || ((temp & PORT_RESUME) != 0 |
285 | && time_after (jiffies, | 382 | && time_after_eq(jiffies, |
286 | ehci->reset_done [i]))) { | 383 | ehci->reset_done[i]))) { |
287 | if (i < 7) | 384 | if (i < 7) |
288 | buf [0] |= 1 << (i + 1); | 385 | buf [0] |= 1 << (i + 1); |
289 | else | 386 | else |
@@ -345,6 +442,7 @@ static int ehci_hub_control ( | |||
345 | ) { | 442 | ) { |
346 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 443 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
347 | int ports = HCS_N_PORTS (ehci->hcs_params); | 444 | int ports = HCS_N_PORTS (ehci->hcs_params); |
445 | u32 __iomem *status_reg = &ehci->regs->port_status[wIndex - 1]; | ||
348 | u32 temp, status; | 446 | u32 temp, status; |
349 | unsigned long flags; | 447 | unsigned long flags; |
350 | int retval = 0; | 448 | int retval = 0; |
@@ -373,18 +471,22 @@ static int ehci_hub_control ( | |||
373 | if (!wIndex || wIndex > ports) | 471 | if (!wIndex || wIndex > ports) |
374 | goto error; | 472 | goto error; |
375 | wIndex--; | 473 | wIndex--; |
376 | temp = readl (&ehci->regs->port_status [wIndex]); | 474 | temp = ehci_readl(ehci, status_reg); |
377 | if (temp & PORT_OWNER) | 475 | |
378 | break; | 476 | /* |
477 | * Even if OWNER is set, so the port is owned by the | ||
478 | * companion controller, khubd needs to be able to clear | ||
479 | * the port-change status bits (especially | ||
480 | * USB_PORT_FEAT_C_CONNECTION). | ||
481 | */ | ||
379 | 482 | ||
380 | switch (wValue) { | 483 | switch (wValue) { |
381 | case USB_PORT_FEAT_ENABLE: | 484 | case USB_PORT_FEAT_ENABLE: |
382 | writel (temp & ~PORT_PE, | 485 | ehci_writel(ehci, temp & ~PORT_PE, status_reg); |
383 | &ehci->regs->port_status [wIndex]); | ||
384 | break; | 486 | break; |
385 | case USB_PORT_FEAT_C_ENABLE: | 487 | case USB_PORT_FEAT_C_ENABLE: |
386 | writel((temp & ~PORT_RWC_BITS) | PORT_PEC, | 488 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC, |
387 | &ehci->regs->port_status [wIndex]); | 489 | status_reg); |
388 | break; | 490 | break; |
389 | case USB_PORT_FEAT_SUSPEND: | 491 | case USB_PORT_FEAT_SUSPEND: |
390 | if (temp & PORT_RESET) | 492 | if (temp & PORT_RESET) |
@@ -396,8 +498,8 @@ static int ehci_hub_control ( | |||
396 | goto error; | 498 | goto error; |
397 | /* resume signaling for 20 msec */ | 499 | /* resume signaling for 20 msec */ |
398 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | 500 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); |
399 | writel (temp | PORT_RESUME, | 501 | ehci_writel(ehci, temp | PORT_RESUME, |
400 | &ehci->regs->port_status [wIndex]); | 502 | status_reg); |
401 | ehci->reset_done [wIndex] = jiffies | 503 | ehci->reset_done [wIndex] = jiffies |
402 | + msecs_to_jiffies (20); | 504 | + msecs_to_jiffies (20); |
403 | } | 505 | } |
@@ -407,16 +509,17 @@ static int ehci_hub_control ( | |||
407 | break; | 509 | break; |
408 | case USB_PORT_FEAT_POWER: | 510 | case USB_PORT_FEAT_POWER: |
409 | if (HCS_PPC (ehci->hcs_params)) | 511 | if (HCS_PPC (ehci->hcs_params)) |
410 | writel (temp & ~(PORT_RWC_BITS | PORT_POWER), | 512 | ehci_writel(ehci, |
411 | &ehci->regs->port_status [wIndex]); | 513 | temp & ~(PORT_RWC_BITS | PORT_POWER), |
514 | status_reg); | ||
412 | break; | 515 | break; |
413 | case USB_PORT_FEAT_C_CONNECTION: | 516 | case USB_PORT_FEAT_C_CONNECTION: |
414 | writel((temp & ~PORT_RWC_BITS) | PORT_CSC, | 517 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC, |
415 | &ehci->regs->port_status [wIndex]); | 518 | status_reg); |
416 | break; | 519 | break; |
417 | case USB_PORT_FEAT_C_OVER_CURRENT: | 520 | case USB_PORT_FEAT_C_OVER_CURRENT: |
418 | writel((temp & ~PORT_RWC_BITS) | PORT_OCC, | 521 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC, |
419 | &ehci->regs->port_status [wIndex]); | 522 | status_reg); |
420 | break; | 523 | break; |
421 | case USB_PORT_FEAT_C_RESET: | 524 | case USB_PORT_FEAT_C_RESET: |
422 | /* GetPortStatus clears reset */ | 525 | /* GetPortStatus clears reset */ |
@@ -424,7 +527,7 @@ static int ehci_hub_control ( | |||
424 | default: | 527 | default: |
425 | goto error; | 528 | goto error; |
426 | } | 529 | } |
427 | readl (&ehci->regs->command); /* unblock posted write */ | 530 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ |
428 | break; | 531 | break; |
429 | case GetHubDescriptor: | 532 | case GetHubDescriptor: |
430 | ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) | 533 | ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) |
@@ -440,7 +543,7 @@ static int ehci_hub_control ( | |||
440 | goto error; | 543 | goto error; |
441 | wIndex--; | 544 | wIndex--; |
442 | status = 0; | 545 | status = 0; |
443 | temp = readl (&ehci->regs->port_status [wIndex]); | 546 | temp = ehci_readl(ehci, status_reg); |
444 | 547 | ||
445 | // wPortChange bits | 548 | // wPortChange bits |
446 | if (temp & PORT_CSC) | 549 | if (temp & PORT_CSC) |
@@ -451,42 +554,55 @@ static int ehci_hub_control ( | |||
451 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; | 554 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; |
452 | 555 | ||
453 | /* whoever resumes must GetPortStatus to complete it!! */ | 556 | /* whoever resumes must GetPortStatus to complete it!! */ |
454 | if ((temp & PORT_RESUME) | 557 | if (temp & PORT_RESUME) { |
455 | && time_after (jiffies, | ||
456 | ehci->reset_done [wIndex])) { | ||
457 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
458 | ehci->reset_done [wIndex] = 0; | ||
459 | 558 | ||
460 | /* stop resume signaling */ | 559 | /* Remote Wakeup received? */ |
461 | temp = readl (&ehci->regs->port_status [wIndex]); | 560 | if (!ehci->reset_done[wIndex]) { |
462 | writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), | 561 | /* resume signaling for 20 msec */ |
463 | &ehci->regs->port_status [wIndex]); | 562 | ehci->reset_done[wIndex] = jiffies |
464 | retval = handshake ( | 563 | + msecs_to_jiffies(20); |
465 | &ehci->regs->port_status [wIndex], | 564 | /* check the port again */ |
466 | PORT_RESUME, 0, 2000 /* 2msec */); | 565 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, |
467 | if (retval != 0) { | 566 | ehci->reset_done[wIndex]); |
468 | ehci_err (ehci, "port %d resume error %d\n", | 567 | } |
469 | wIndex + 1, retval); | 568 | |
470 | goto error; | 569 | /* resume completed? */ |
570 | else if (time_after_eq(jiffies, | ||
571 | ehci->reset_done[wIndex])) { | ||
572 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
573 | ehci->reset_done[wIndex] = 0; | ||
574 | |||
575 | /* stop resume signaling */ | ||
576 | temp = ehci_readl(ehci, status_reg); | ||
577 | ehci_writel(ehci, | ||
578 | temp & ~(PORT_RWC_BITS | PORT_RESUME), | ||
579 | status_reg); | ||
580 | retval = handshake(ehci, status_reg, | ||
581 | PORT_RESUME, 0, 2000 /* 2msec */); | ||
582 | if (retval != 0) { | ||
583 | ehci_err(ehci, | ||
584 | "port %d resume error %d\n", | ||
585 | wIndex + 1, retval); | ||
586 | goto error; | ||
587 | } | ||
588 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
471 | } | 589 | } |
472 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
473 | } | 590 | } |
474 | 591 | ||
475 | /* whoever resets must GetPortStatus to complete it!! */ | 592 | /* whoever resets must GetPortStatus to complete it!! */ |
476 | if ((temp & PORT_RESET) | 593 | if ((temp & PORT_RESET) |
477 | && time_after (jiffies, | 594 | && time_after_eq(jiffies, |
478 | ehci->reset_done [wIndex])) { | 595 | ehci->reset_done[wIndex])) { |
479 | status |= 1 << USB_PORT_FEAT_C_RESET; | 596 | status |= 1 << USB_PORT_FEAT_C_RESET; |
480 | ehci->reset_done [wIndex] = 0; | 597 | ehci->reset_done [wIndex] = 0; |
481 | 598 | ||
482 | /* force reset to complete */ | 599 | /* force reset to complete */ |
483 | writel (temp & ~(PORT_RWC_BITS | PORT_RESET), | 600 | ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), |
484 | &ehci->regs->port_status [wIndex]); | 601 | status_reg); |
485 | /* REVISIT: some hardware needs 550+ usec to clear | 602 | /* REVISIT: some hardware needs 550+ usec to clear |
486 | * this bit; seems too long to spin routinely... | 603 | * this bit; seems too long to spin routinely... |
487 | */ | 604 | */ |
488 | retval = handshake ( | 605 | retval = handshake(ehci, status_reg, |
489 | &ehci->regs->port_status [wIndex], | ||
490 | PORT_RESET, 0, 750); | 606 | PORT_RESET, 0, 750); |
491 | if (retval != 0) { | 607 | if (retval != 0) { |
492 | ehci_err (ehci, "port %d reset error %d\n", | 608 | ehci_err (ehci, "port %d reset error %d\n", |
@@ -495,28 +611,41 @@ static int ehci_hub_control ( | |||
495 | } | 611 | } |
496 | 612 | ||
497 | /* see what we found out */ | 613 | /* see what we found out */ |
498 | temp = check_reset_complete (ehci, wIndex, | 614 | temp = check_reset_complete (ehci, wIndex, status_reg, |
499 | readl (&ehci->regs->port_status [wIndex])); | 615 | ehci_readl(ehci, status_reg)); |
500 | } | 616 | } |
501 | 617 | ||
502 | // don't show wPortStatus if it's owned by a companion hc | 618 | /* transfer dedicated ports to the companion hc */ |
503 | if (!(temp & PORT_OWNER)) { | 619 | if ((temp & PORT_CONNECT) && |
504 | if (temp & PORT_CONNECT) { | 620 | test_bit(wIndex, &ehci->companion_ports)) { |
505 | status |= 1 << USB_PORT_FEAT_CONNECTION; | 621 | temp &= ~PORT_RWC_BITS; |
506 | // status may be from integrated TT | 622 | temp |= PORT_OWNER; |
507 | status |= ehci_port_speed(ehci, temp); | 623 | ehci_writel(ehci, temp, status_reg); |
508 | } | 624 | ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1); |
509 | if (temp & PORT_PE) | 625 | temp = ehci_readl(ehci, status_reg); |
510 | status |= 1 << USB_PORT_FEAT_ENABLE; | 626 | } |
511 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | 627 | |
512 | status |= 1 << USB_PORT_FEAT_SUSPEND; | 628 | /* |
513 | if (temp & PORT_OC) | 629 | * Even if OWNER is set, there's no harm letting khubd |
514 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | 630 | * see the wPortStatus values (they should all be 0 except |
515 | if (temp & PORT_RESET) | 631 | * for PORT_POWER anyway). |
516 | status |= 1 << USB_PORT_FEAT_RESET; | 632 | */ |
517 | if (temp & PORT_POWER) | 633 | |
518 | status |= 1 << USB_PORT_FEAT_POWER; | 634 | if (temp & PORT_CONNECT) { |
635 | status |= 1 << USB_PORT_FEAT_CONNECTION; | ||
636 | // status may be from integrated TT | ||
637 | status |= ehci_port_speed(ehci, temp); | ||
519 | } | 638 | } |
639 | if (temp & PORT_PE) | ||
640 | status |= 1 << USB_PORT_FEAT_ENABLE; | ||
641 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | ||
642 | status |= 1 << USB_PORT_FEAT_SUSPEND; | ||
643 | if (temp & PORT_OC) | ||
644 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | ||
645 | if (temp & PORT_RESET) | ||
646 | status |= 1 << USB_PORT_FEAT_RESET; | ||
647 | if (temp & PORT_POWER) | ||
648 | status |= 1 << USB_PORT_FEAT_POWER; | ||
520 | 649 | ||
521 | #ifndef EHCI_VERBOSE_DEBUG | 650 | #ifndef EHCI_VERBOSE_DEBUG |
522 | if (status & ~0xffff) /* only if wPortChange is interesting */ | 651 | if (status & ~0xffff) /* only if wPortChange is interesting */ |
@@ -541,7 +670,7 @@ static int ehci_hub_control ( | |||
541 | if (!wIndex || wIndex > ports) | 670 | if (!wIndex || wIndex > ports) |
542 | goto error; | 671 | goto error; |
543 | wIndex--; | 672 | wIndex--; |
544 | temp = readl (&ehci->regs->port_status [wIndex]); | 673 | temp = ehci_readl(ehci, status_reg); |
545 | if (temp & PORT_OWNER) | 674 | if (temp & PORT_OWNER) |
546 | break; | 675 | break; |
547 | 676 | ||
@@ -555,13 +684,12 @@ static int ehci_hub_control ( | |||
555 | goto error; | 684 | goto error; |
556 | if (device_may_wakeup(&hcd->self.root_hub->dev)) | 685 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
557 | temp |= PORT_WAKE_BITS; | 686 | temp |= PORT_WAKE_BITS; |
558 | writel (temp | PORT_SUSPEND, | 687 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); |
559 | &ehci->regs->port_status [wIndex]); | ||
560 | break; | 688 | break; |
561 | case USB_PORT_FEAT_POWER: | 689 | case USB_PORT_FEAT_POWER: |
562 | if (HCS_PPC (ehci->hcs_params)) | 690 | if (HCS_PPC (ehci->hcs_params)) |
563 | writel (temp | PORT_POWER, | 691 | ehci_writel(ehci, temp | PORT_POWER, |
564 | &ehci->regs->port_status [wIndex]); | 692 | status_reg); |
565 | break; | 693 | break; |
566 | case USB_PORT_FEAT_RESET: | 694 | case USB_PORT_FEAT_RESET: |
567 | if (temp & PORT_RESUME) | 695 | if (temp & PORT_RESUME) |
@@ -589,7 +717,7 @@ static int ehci_hub_control ( | |||
589 | ehci->reset_done [wIndex] = jiffies | 717 | ehci->reset_done [wIndex] = jiffies |
590 | + msecs_to_jiffies (50); | 718 | + msecs_to_jiffies (50); |
591 | } | 719 | } |
592 | writel (temp, &ehci->regs->port_status [wIndex]); | 720 | ehci_writel(ehci, temp, status_reg); |
593 | break; | 721 | break; |
594 | 722 | ||
595 | /* For downstream facing ports (these): one hub port is put | 723 | /* For downstream facing ports (these): one hub port is put |
@@ -604,13 +732,13 @@ static int ehci_hub_control ( | |||
604 | ehci_quiesce(ehci); | 732 | ehci_quiesce(ehci); |
605 | ehci_halt(ehci); | 733 | ehci_halt(ehci); |
606 | temp |= selector << 16; | 734 | temp |= selector << 16; |
607 | writel (temp, &ehci->regs->port_status [wIndex]); | 735 | ehci_writel(ehci, temp, status_reg); |
608 | break; | 736 | break; |
609 | 737 | ||
610 | default: | 738 | default: |
611 | goto error; | 739 | goto error; |
612 | } | 740 | } |
613 | readl (&ehci->regs->command); /* unblock posted writes */ | 741 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
614 | break; | 742 | break; |
615 | 743 | ||
616 | default: | 744 | default: |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 4bc7970ba3ef..12edc723ec73 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -38,7 +38,7 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
38 | if ((temp & (3 << 13)) == (1 << 13)) { | 38 | if ((temp & (3 << 13)) == (1 << 13)) { |
39 | temp &= 0x1fff; | 39 | temp &= 0x1fff; |
40 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; | 40 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; |
41 | temp = readl(&ehci->debug->control); | 41 | temp = ehci_readl(ehci, &ehci->debug->control); |
42 | ehci_info(ehci, "debug port %d%s\n", | 42 | ehci_info(ehci, "debug port %d%s\n", |
43 | HCS_DEBUG_PORT(ehci->hcs_params), | 43 | HCS_DEBUG_PORT(ehci->hcs_params), |
44 | (temp & DBGP_ENABLED) | 44 | (temp & DBGP_ENABLED) |
@@ -71,8 +71,24 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
71 | u32 temp; | 71 | u32 temp; |
72 | int retval; | 72 | int retval; |
73 | 73 | ||
74 | switch (pdev->vendor) { | ||
75 | case PCI_VENDOR_ID_TOSHIBA_2: | ||
76 | /* celleb's companion chip */ | ||
77 | if (pdev->device == 0x01b5) { | ||
78 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
79 | ehci->big_endian_mmio = 1; | ||
80 | #else | ||
81 | ehci_warn(ehci, | ||
82 | "unsupported big endian Toshiba quirk\n"); | ||
83 | #endif | ||
84 | } | ||
85 | break; | ||
86 | } | ||
87 | |||
74 | ehci->caps = hcd->regs; | 88 | ehci->caps = hcd->regs; |
75 | ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); | 89 | ehci->regs = hcd->regs + |
90 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
91 | |||
76 | dbg_hcs_params(ehci, "reset"); | 92 | dbg_hcs_params(ehci, "reset"); |
77 | dbg_hcc_params(ehci, "reset"); | 93 | dbg_hcc_params(ehci, "reset"); |
78 | 94 | ||
@@ -101,7 +117,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
101 | } | 117 | } |
102 | 118 | ||
103 | /* cache this readonly data; minimize chip reads */ | 119 | /* cache this readonly data; minimize chip reads */ |
104 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 120 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
105 | 121 | ||
106 | retval = ehci_halt(ehci); | 122 | retval = ehci_halt(ehci); |
107 | if (retval) | 123 | if (retval) |
@@ -235,8 +251,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
235 | rc = -EINVAL; | 251 | rc = -EINVAL; |
236 | goto bail; | 252 | goto bail; |
237 | } | 253 | } |
238 | writel (0, &ehci->regs->intr_enable); | 254 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
239 | (void)readl(&ehci->regs->intr_enable); | 255 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); |
240 | 256 | ||
241 | /* make sure snapshot being resumed re-enumerates everything */ | 257 | /* make sure snapshot being resumed re-enumerates everything */ |
242 | if (message.event == PM_EVENT_PRETHAW) { | 258 | if (message.event == PM_EVENT_PRETHAW) { |
@@ -270,13 +286,13 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
270 | /* If CF is still set, we maintained PCI Vaux power. | 286 | /* If CF is still set, we maintained PCI Vaux power. |
271 | * Just undo the effect of ehci_pci_suspend(). | 287 | * Just undo the effect of ehci_pci_suspend(). |
272 | */ | 288 | */ |
273 | if (readl(&ehci->regs->configured_flag) == FLAG_CF) { | 289 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { |
274 | int mask = INTR_MASK; | 290 | int mask = INTR_MASK; |
275 | 291 | ||
276 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) | 292 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) |
277 | mask &= ~STS_PCD; | 293 | mask &= ~STS_PCD; |
278 | writel(mask, &ehci->regs->intr_enable); | 294 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); |
279 | readl(&ehci->regs->intr_enable); | 295 | ehci_readl(ehci, &ehci->regs->intr_enable); |
280 | return 0; | 296 | return 0; |
281 | } | 297 | } |
282 | 298 | ||
@@ -300,9 +316,9 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
300 | /* here we "know" root ports should always stay powered */ | 316 | /* here we "know" root ports should always stay powered */ |
301 | ehci_port_power(ehci, 1); | 317 | ehci_port_power(ehci, 1); |
302 | 318 | ||
303 | writel(ehci->command, &ehci->regs->command); | 319 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
304 | writel(FLAG_CF, &ehci->regs->configured_flag); | 320 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
305 | readl(&ehci->regs->command); /* unblock posted writes */ | 321 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
306 | 322 | ||
307 | hcd->state = HC_STATE_SUSPENDED; | 323 | hcd->state = HC_STATE_SUSPENDED; |
308 | return 0; | 324 | return 0; |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c new file mode 100644 index 000000000000..371f194a9d39 --- /dev/null +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * PS3 EHCI Host Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
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; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/ps3.h> | ||
22 | |||
23 | static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | ||
24 | { | ||
25 | int result; | ||
26 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
27 | |||
28 | ehci->big_endian_mmio = 1; | ||
29 | |||
30 | ehci->caps = hcd->regs; | ||
31 | ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, | ||
32 | &ehci->caps->hc_capbase)); | ||
33 | |||
34 | dbg_hcs_params(ehci, "reset"); | ||
35 | dbg_hcc_params(ehci, "reset"); | ||
36 | |||
37 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
38 | |||
39 | result = ehci_halt(ehci); | ||
40 | |||
41 | if (result) | ||
42 | return result; | ||
43 | |||
44 | result = ehci_init(hcd); | ||
45 | |||
46 | if (result) | ||
47 | return result; | ||
48 | |||
49 | ehci_port_power(ehci, 0); | ||
50 | |||
51 | return result; | ||
52 | } | ||
53 | |||
54 | static const struct hc_driver ps3_ehci_hc_driver = { | ||
55 | .description = hcd_name, | ||
56 | .product_desc = "PS3 EHCI Host Controller", | ||
57 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
58 | .irq = ehci_irq, | ||
59 | .flags = HCD_MEMORY | HCD_USB2, | ||
60 | .reset = ps3_ehci_hc_reset, | ||
61 | .start = ehci_run, | ||
62 | .stop = ehci_stop, | ||
63 | .shutdown = ehci_shutdown, | ||
64 | .urb_enqueue = ehci_urb_enqueue, | ||
65 | .urb_dequeue = ehci_urb_dequeue, | ||
66 | .endpoint_disable = ehci_endpoint_disable, | ||
67 | .get_frame_number = ehci_get_frame, | ||
68 | .hub_status_data = ehci_hub_status_data, | ||
69 | .hub_control = ehci_hub_control, | ||
70 | #if defined(CONFIG_PM) | ||
71 | .bus_suspend = ehci_bus_suspend, | ||
72 | .bus_resume = ehci_bus_resume, | ||
73 | #endif | ||
74 | }; | ||
75 | |||
76 | #if !defined(DEBUG) | ||
77 | #undef dev_dbg | ||
78 | static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( | ||
79 | const struct device *_dev, const char *fmt, ...) {return 0;} | ||
80 | #endif | ||
81 | |||
82 | |||
83 | static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) | ||
84 | { | ||
85 | int result; | ||
86 | struct usb_hcd *hcd; | ||
87 | unsigned int virq; | ||
88 | static u64 dummy_mask = DMA_32BIT_MASK; | ||
89 | |||
90 | if (usb_disabled()) { | ||
91 | result = -ENODEV; | ||
92 | goto fail_start; | ||
93 | } | ||
94 | |||
95 | result = ps3_mmio_region_create(dev->m_region); | ||
96 | |||
97 | if (result) { | ||
98 | dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", | ||
99 | __func__, __LINE__); | ||
100 | result = -EPERM; | ||
101 | goto fail_mmio; | ||
102 | } | ||
103 | |||
104 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | ||
105 | __LINE__, dev->m_region->lpar_addr); | ||
106 | |||
107 | result = ps3_alloc_io_irq(dev->interrupt_id, &virq); | ||
108 | |||
109 | if (result) { | ||
110 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | ||
111 | __func__, __LINE__, virq); | ||
112 | result = -EPERM; | ||
113 | goto fail_irq; | ||
114 | } | ||
115 | |||
116 | dev->core.power.power_state = PMSG_ON; | ||
117 | dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ | ||
118 | |||
119 | hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id); | ||
120 | |||
121 | if (!hcd) { | ||
122 | dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, | ||
123 | __LINE__); | ||
124 | result = -ENOMEM; | ||
125 | goto fail_create_hcd; | ||
126 | } | ||
127 | |||
128 | hcd->rsrc_start = dev->m_region->lpar_addr; | ||
129 | hcd->rsrc_len = dev->m_region->len; | ||
130 | hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); | ||
131 | |||
132 | if (!hcd->regs) { | ||
133 | dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, | ||
134 | __LINE__); | ||
135 | result = -EPERM; | ||
136 | goto fail_ioremap; | ||
137 | } | ||
138 | |||
139 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, | ||
140 | (unsigned long)hcd->rsrc_start); | ||
141 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, | ||
142 | (unsigned long)hcd->rsrc_len); | ||
143 | dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, | ||
144 | (unsigned long)hcd->regs); | ||
145 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | ||
146 | (unsigned long)virq); | ||
147 | |||
148 | ps3_system_bus_set_driver_data(dev, hcd); | ||
149 | |||
150 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | ||
151 | |||
152 | if (result) { | ||
153 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | ||
154 | __func__, __LINE__, result); | ||
155 | goto fail_add_hcd; | ||
156 | } | ||
157 | |||
158 | return result; | ||
159 | |||
160 | fail_add_hcd: | ||
161 | iounmap(hcd->regs); | ||
162 | fail_ioremap: | ||
163 | usb_put_hcd(hcd); | ||
164 | fail_create_hcd: | ||
165 | ps3_free_io_irq(virq); | ||
166 | fail_irq: | ||
167 | ps3_free_mmio_region(dev->m_region); | ||
168 | fail_mmio: | ||
169 | fail_start: | ||
170 | return result; | ||
171 | } | ||
172 | |||
173 | static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev) | ||
174 | { | ||
175 | struct usb_hcd *hcd = | ||
176 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
177 | |||
178 | usb_put_hcd(hcd); | ||
179 | ps3_system_bus_set_driver_data(dev, NULL); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | MODULE_ALIAS("ps3-ehci"); | ||
185 | |||
186 | static struct ps3_system_bus_driver ps3_ehci_sb_driver = { | ||
187 | .match_id = PS3_MATCH_ID_EHCI, | ||
188 | .core = { | ||
189 | .name = "ps3-ehci-driver", | ||
190 | }, | ||
191 | .probe = ps3_ehci_sb_probe, | ||
192 | .remove = ps3_ehci_sb_remove, | ||
193 | }; | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 62e46dc60e86..e7fbbd00e7cd 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -789,13 +789,14 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
789 | head = ehci->async; | 789 | head = ehci->async; |
790 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 790 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
791 | if (!head->qh_next.qh) { | 791 | if (!head->qh_next.qh) { |
792 | u32 cmd = readl (&ehci->regs->command); | 792 | u32 cmd = ehci_readl(ehci, &ehci->regs->command); |
793 | 793 | ||
794 | if (!(cmd & CMD_ASE)) { | 794 | if (!(cmd & CMD_ASE)) { |
795 | /* in case a clear of CMD_ASE didn't take yet */ | 795 | /* in case a clear of CMD_ASE didn't take yet */ |
796 | (void) handshake (&ehci->regs->status, STS_ASS, 0, 150); | 796 | (void)handshake(ehci, &ehci->regs->status, |
797 | STS_ASS, 0, 150); | ||
797 | cmd |= CMD_ASE | CMD_RUN; | 798 | cmd |= CMD_ASE | CMD_RUN; |
798 | writel (cmd, &ehci->regs->command); | 799 | ehci_writel(ehci, cmd, &ehci->regs->command); |
799 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 800 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
800 | /* posted write need not be known to HC yet ... */ | 801 | /* posted write need not be known to HC yet ... */ |
801 | } | 802 | } |
@@ -1007,7 +1008,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
1007 | 1008 | ||
1008 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 1009 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
1009 | { | 1010 | { |
1010 | int cmd = readl (&ehci->regs->command); | 1011 | int cmd = ehci_readl(ehci, &ehci->regs->command); |
1011 | struct ehci_qh *prev; | 1012 | struct ehci_qh *prev; |
1012 | 1013 | ||
1013 | #ifdef DEBUG | 1014 | #ifdef DEBUG |
@@ -1025,7 +1026,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1025 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT | 1026 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT |
1026 | && !ehci->reclaim) { | 1027 | && !ehci->reclaim) { |
1027 | /* ... and CMD_IAAD clear */ | 1028 | /* ... and CMD_IAAD clear */ |
1028 | writel (cmd & ~CMD_ASE, &ehci->regs->command); | 1029 | ehci_writel(ehci, cmd & ~CMD_ASE, |
1030 | &ehci->regs->command); | ||
1029 | wmb (); | 1031 | wmb (); |
1030 | // handshake later, if we need to | 1032 | // handshake later, if we need to |
1031 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 1033 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
@@ -1054,8 +1056,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1054 | 1056 | ||
1055 | ehci->reclaim_ready = 0; | 1057 | ehci->reclaim_ready = 0; |
1056 | cmd |= CMD_IAAD; | 1058 | cmd |= CMD_IAAD; |
1057 | writel (cmd, &ehci->regs->command); | 1059 | ehci_writel(ehci, cmd, &ehci->regs->command); |
1058 | (void) readl (&ehci->regs->command); | 1060 | (void)ehci_readl(ehci, &ehci->regs->command); |
1059 | timer_action (ehci, TIMER_IAA_WATCHDOG); | 1061 | timer_action (ehci, TIMER_IAA_WATCHDOG); |
1060 | } | 1062 | } |
1061 | 1063 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 65c402a0fa7a..7b5ae7111f23 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -433,20 +433,20 @@ static int enable_periodic (struct ehci_hcd *ehci) | |||
433 | /* did clearing PSE did take effect yet? | 433 | /* did clearing PSE did take effect yet? |
434 | * takes effect only at frame boundaries... | 434 | * takes effect only at frame boundaries... |
435 | */ | 435 | */ |
436 | status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125); | 436 | status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125); |
437 | if (status != 0) { | 437 | if (status != 0) { |
438 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 438 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
439 | return status; | 439 | return status; |
440 | } | 440 | } |
441 | 441 | ||
442 | cmd = readl (&ehci->regs->command) | CMD_PSE; | 442 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; |
443 | writel (cmd, &ehci->regs->command); | 443 | ehci_writel(ehci, cmd, &ehci->regs->command); |
444 | /* posted write ... PSS happens later */ | 444 | /* posted write ... PSS happens later */ |
445 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 445 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
446 | 446 | ||
447 | /* make sure ehci_work scans these */ | 447 | /* make sure ehci_work scans these */ |
448 | ehci->next_uframe = readl (&ehci->regs->frame_index) | 448 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) |
449 | % (ehci->periodic_size << 3); | 449 | % (ehci->periodic_size << 3); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
@@ -458,14 +458,14 @@ static int disable_periodic (struct ehci_hcd *ehci) | |||
458 | /* did setting PSE not take effect yet? | 458 | /* did setting PSE not take effect yet? |
459 | * takes effect only at frame boundaries... | 459 | * takes effect only at frame boundaries... |
460 | */ | 460 | */ |
461 | status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); | 461 | status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); |
462 | if (status != 0) { | 462 | if (status != 0) { |
463 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 463 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
464 | return status; | 464 | return status; |
465 | } | 465 | } |
466 | 466 | ||
467 | cmd = readl (&ehci->regs->command) & ~CMD_PSE; | 467 | cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; |
468 | writel (cmd, &ehci->regs->command); | 468 | ehci_writel(ehci, cmd, &ehci->regs->command); |
469 | /* posted write ... */ | 469 | /* posted write ... */ |
470 | 470 | ||
471 | ehci->next_uframe = -1; | 471 | ehci->next_uframe = -1; |
@@ -1336,7 +1336,7 @@ iso_stream_schedule ( | |||
1336 | goto fail; | 1336 | goto fail; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | now = readl (&ehci->regs->frame_index) % mod; | 1339 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
1340 | 1340 | ||
1341 | /* when's the last uframe this urb could start? */ | 1341 | /* when's the last uframe this urb could start? */ |
1342 | max = now + mod; | 1342 | max = now + mod; |
@@ -2088,7 +2088,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2088 | */ | 2088 | */ |
2089 | now_uframe = ehci->next_uframe; | 2089 | now_uframe = ehci->next_uframe; |
2090 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2090 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) |
2091 | clock = readl (&ehci->regs->frame_index); | 2091 | clock = ehci_readl(ehci, &ehci->regs->frame_index); |
2092 | else | 2092 | else |
2093 | clock = now_uframe + mod - 1; | 2093 | clock = now_uframe + mod - 1; |
2094 | clock %= mod; | 2094 | clock %= mod; |
@@ -2213,7 +2213,7 @@ restart: | |||
2213 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2213 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) |
2214 | break; | 2214 | break; |
2215 | ehci->next_uframe = now_uframe; | 2215 | ehci->next_uframe = now_uframe; |
2216 | now = readl (&ehci->regs->frame_index) % mod; | 2216 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
2217 | if (now_uframe == now) | 2217 | if (now_uframe == now) |
2218 | break; | 2218 | break; |
2219 | 2219 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 74dbc6c8228f..ec0da0343be4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -74,7 +74,11 @@ struct ehci_hcd { /* one per controller */ | |||
74 | 74 | ||
75 | /* per root hub port */ | 75 | /* per root hub port */ |
76 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; | 76 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; |
77 | unsigned long bus_suspended; | 77 | /* bit vectors (one bit per port) */ |
78 | unsigned long bus_suspended; /* which ports were | ||
79 | already suspended at the start of a bus suspend */ | ||
80 | unsigned long companion_ports; /* which ports are | ||
81 | dedicated to the companion controller */ | ||
78 | 82 | ||
79 | /* per-HC memory pools (could be per-bus, but ...) */ | 83 | /* per-HC memory pools (could be per-bus, but ...) */ |
80 | struct dma_pool *qh_pool; /* qh per active urb */ | 84 | struct dma_pool *qh_pool; /* qh per active urb */ |
@@ -92,6 +96,7 @@ struct ehci_hcd { /* one per controller */ | |||
92 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ | 96 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ |
93 | unsigned no_selective_suspend:1; | 97 | unsigned no_selective_suspend:1; |
94 | unsigned has_fsl_port_bug:1; /* FreeScale */ | 98 | unsigned has_fsl_port_bug:1; /* FreeScale */ |
99 | unsigned big_endian_mmio:1; | ||
95 | 100 | ||
96 | u8 sbrn; /* packed release number */ | 101 | u8 sbrn; /* packed release number */ |
97 | 102 | ||
@@ -651,6 +656,45 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) | |||
651 | #define ehci_has_fsl_portno_bug(e) (0) | 656 | #define ehci_has_fsl_portno_bug(e) (0) |
652 | #endif | 657 | #endif |
653 | 658 | ||
659 | /* | ||
660 | * While most USB host controllers implement their registers in | ||
661 | * little-endian format, a minority (celleb companion chip) implement | ||
662 | * them in big endian format. | ||
663 | * | ||
664 | * This attempts to support either format at compile time without a | ||
665 | * runtime penalty, or both formats with the additional overhead | ||
666 | * of checking a flag bit. | ||
667 | */ | ||
668 | |||
669 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
670 | #define ehci_big_endian_mmio(e) ((e)->big_endian_mmio) | ||
671 | #else | ||
672 | #define ehci_big_endian_mmio(e) 0 | ||
673 | #endif | ||
674 | |||
675 | static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, | ||
676 | __u32 __iomem * regs) | ||
677 | { | ||
678 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
679 | return ehci_big_endian_mmio(ehci) ? | ||
680 | readl_be((__force u32 *)regs) : | ||
681 | readl((__force u32 *)regs); | ||
682 | #else | ||
683 | return readl((__force u32 *)regs); | ||
684 | #endif | ||
685 | } | ||
686 | |||
687 | static inline void ehci_writel (const struct ehci_hcd *ehci, | ||
688 | const unsigned int val, __u32 __iomem *regs) | ||
689 | { | ||
690 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
691 | ehci_big_endian_mmio(ehci) ? | ||
692 | writel_be(val, (__force u32 *)regs) : | ||
693 | writel(val, (__force u32 *)regs); | ||
694 | #else | ||
695 | writel(val, (__force u32 *)regs); | ||
696 | #endif | ||
697 | } | ||
654 | 698 | ||
655 | /*-------------------------------------------------------------------------*/ | 699 | /*-------------------------------------------------------------------------*/ |
656 | 700 | ||
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index cc405512fa1c..930346487278 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -170,7 +170,6 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, | |||
170 | at91_stop_hc(pdev); | 170 | at91_stop_hc(pdev); |
171 | iounmap(hcd->regs); | 171 | iounmap(hcd->regs); |
172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
173 | disable_irq_wake(hcd->irq); | ||
174 | 173 | ||
175 | clk_put(fclk); | 174 | clk_put(fclk); |
176 | clk_put(iclk); | 175 | clk_put(iclk); |
@@ -271,8 +270,6 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
271 | 270 | ||
272 | if (device_may_wakeup(&pdev->dev)) | 271 | if (device_may_wakeup(&pdev->dev)) |
273 | enable_irq_wake(hcd->irq); | 272 | enable_irq_wake(hcd->irq); |
274 | else | ||
275 | disable_irq_wake(hcd->irq); | ||
276 | 273 | ||
277 | /* | 274 | /* |
278 | * The integrated transceivers seem unable to notice disconnect, | 275 | * The integrated transceivers seem unable to notice disconnect, |
@@ -293,6 +290,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
293 | 290 | ||
294 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) | 291 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) |
295 | { | 292 | { |
293 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
294 | |||
295 | if (device_may_wakeup(&pdev->dev)) | ||
296 | disable_irq_wake(hcd->irq); | ||
297 | |||
296 | if (!clocked) { | 298 | if (!clocked) { |
297 | clk_enable(iclk); | 299 | clk_enable(iclk); |
298 | clk_enable(fclk); | 300 | clk_enable(fclk); |
@@ -320,18 +322,3 @@ static struct platform_driver ohci_hcd_at91_driver = { | |||
320 | }, | 322 | }, |
321 | }; | 323 | }; |
322 | 324 | ||
323 | static int __init ohci_hcd_at91_init (void) | ||
324 | { | ||
325 | if (usb_disabled()) | ||
326 | return -ENODEV; | ||
327 | |||
328 | return platform_driver_register(&ohci_hcd_at91_driver); | ||
329 | } | ||
330 | |||
331 | static void __exit ohci_hcd_at91_cleanup (void) | ||
332 | { | ||
333 | platform_driver_unregister(&ohci_hcd_at91_driver); | ||
334 | } | ||
335 | |||
336 | module_init (ohci_hcd_at91_init); | ||
337 | module_exit (ohci_hcd_at91_cleanup); | ||
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index e70b2430e2a9..663a0600b6e7 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -345,19 +345,3 @@ static struct platform_driver ohci_hcd_au1xxx_driver = { | |||
345 | }, | 345 | }, |
346 | }; | 346 | }; |
347 | 347 | ||
348 | static int __init ohci_hcd_au1xxx_init (void) | ||
349 | { | ||
350 | pr_debug (DRIVER_INFO " (Au1xxx)"); | ||
351 | pr_debug ("block sizes: ed %d td %d\n", | ||
352 | sizeof (struct ed), sizeof (struct td)); | ||
353 | |||
354 | return platform_driver_register(&ohci_hcd_au1xxx_driver); | ||
355 | } | ||
356 | |||
357 | static void __exit ohci_hcd_au1xxx_cleanup (void) | ||
358 | { | ||
359 | platform_driver_unregister(&ohci_hcd_au1xxx_driver); | ||
360 | } | ||
361 | |||
362 | module_init (ohci_hcd_au1xxx_init); | ||
363 | module_exit (ohci_hcd_au1xxx_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 3348b07f0fe5..44c60fba76e1 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -214,15 +214,3 @@ static struct platform_driver ohci_hcd_ep93xx_driver = { | |||
214 | }, | 214 | }, |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static int __init ohci_hcd_ep93xx_init(void) | ||
218 | { | ||
219 | return platform_driver_register(&ohci_hcd_ep93xx_driver); | ||
220 | } | ||
221 | |||
222 | static void __exit ohci_hcd_ep93xx_cleanup(void) | ||
223 | { | ||
224 | platform_driver_unregister(&ohci_hcd_ep93xx_driver); | ||
225 | } | ||
226 | |||
227 | module_init(ohci_hcd_ep93xx_init); | ||
228 | module_exit(ohci_hcd_ep93xx_cleanup); | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index c1c1d871aba4..fa6a7ceaa0db 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -855,63 +855,167 @@ MODULE_LICENSE ("GPL"); | |||
855 | 855 | ||
856 | #ifdef CONFIG_PCI | 856 | #ifdef CONFIG_PCI |
857 | #include "ohci-pci.c" | 857 | #include "ohci-pci.c" |
858 | #define PCI_DRIVER ohci_pci_driver | ||
858 | #endif | 859 | #endif |
859 | 860 | ||
860 | #ifdef CONFIG_SA1111 | 861 | #ifdef CONFIG_SA1111 |
861 | #include "ohci-sa1111.c" | 862 | #include "ohci-sa1111.c" |
863 | #define SA1111_DRIVER ohci_hcd_sa1111_driver | ||
862 | #endif | 864 | #endif |
863 | 865 | ||
864 | #ifdef CONFIG_ARCH_S3C2410 | 866 | #ifdef CONFIG_ARCH_S3C2410 |
865 | #include "ohci-s3c2410.c" | 867 | #include "ohci-s3c2410.c" |
868 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | ||
866 | #endif | 869 | #endif |
867 | 870 | ||
868 | #ifdef CONFIG_ARCH_OMAP | 871 | #ifdef CONFIG_ARCH_OMAP |
869 | #include "ohci-omap.c" | 872 | #include "ohci-omap.c" |
873 | #define PLATFORM_DRIVER ohci_hcd_omap_driver | ||
870 | #endif | 874 | #endif |
871 | 875 | ||
872 | #ifdef CONFIG_ARCH_LH7A404 | 876 | #ifdef CONFIG_ARCH_LH7A404 |
873 | #include "ohci-lh7a404.c" | 877 | #include "ohci-lh7a404.c" |
878 | #define PLATFORM_DRIVER ohci_hcd_lh7a404_driver | ||
874 | #endif | 879 | #endif |
875 | 880 | ||
876 | #ifdef CONFIG_PXA27x | 881 | #ifdef CONFIG_PXA27x |
877 | #include "ohci-pxa27x.c" | 882 | #include "ohci-pxa27x.c" |
883 | #define PLATFORM_DRIVER ohci_hcd_pxa27x_driver | ||
878 | #endif | 884 | #endif |
879 | 885 | ||
880 | #ifdef CONFIG_ARCH_EP93XX | 886 | #ifdef CONFIG_ARCH_EP93XX |
881 | #include "ohci-ep93xx.c" | 887 | #include "ohci-ep93xx.c" |
888 | #define PLATFORM_DRIVER ohci_hcd_ep93xx_driver | ||
882 | #endif | 889 | #endif |
883 | 890 | ||
884 | #ifdef CONFIG_SOC_AU1X00 | 891 | #ifdef CONFIG_SOC_AU1X00 |
885 | #include "ohci-au1xxx.c" | 892 | #include "ohci-au1xxx.c" |
893 | #define PLATFORM_DRIVER ohci_hcd_au1xxx_driver | ||
886 | #endif | 894 | #endif |
887 | 895 | ||
888 | #ifdef CONFIG_PNX8550 | 896 | #ifdef CONFIG_PNX8550 |
889 | #include "ohci-pnx8550.c" | 897 | #include "ohci-pnx8550.c" |
898 | #define PLATFORM_DRIVER ohci_hcd_pnx8550_driver | ||
890 | #endif | 899 | #endif |
891 | 900 | ||
892 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC | 901 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC |
893 | #include "ohci-ppc-soc.c" | 902 | #include "ohci-ppc-soc.c" |
903 | #define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver | ||
894 | #endif | 904 | #endif |
895 | 905 | ||
896 | #ifdef CONFIG_ARCH_AT91 | 906 | #ifdef CONFIG_ARCH_AT91 |
897 | #include "ohci-at91.c" | 907 | #include "ohci-at91.c" |
908 | #define PLATFORM_DRIVER ohci_hcd_at91_driver | ||
898 | #endif | 909 | #endif |
899 | 910 | ||
900 | #ifdef CONFIG_ARCH_PNX4008 | 911 | #ifdef CONFIG_ARCH_PNX4008 |
901 | #include "ohci-pnx4008.c" | 912 | #include "ohci-pnx4008.c" |
913 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver | ||
902 | #endif | 914 | #endif |
903 | 915 | ||
904 | #if !(defined(CONFIG_PCI) \ | 916 | |
905 | || defined(CONFIG_SA1111) \ | 917 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF |
906 | || defined(CONFIG_ARCH_S3C2410) \ | 918 | #include "ohci-ppc-of.c" |
907 | || defined(CONFIG_ARCH_OMAP) \ | 919 | #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver |
908 | || defined (CONFIG_ARCH_LH7A404) \ | 920 | #endif |
909 | || defined (CONFIG_PXA27x) \ | 921 | |
910 | || defined (CONFIG_ARCH_EP93XX) \ | 922 | #ifdef CONFIG_PPC_PS3 |
911 | || defined (CONFIG_SOC_AU1X00) \ | 923 | #include "ohci-ps3.c" |
912 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ | 924 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_sb_driver |
913 | || defined (CONFIG_ARCH_AT91) \ | 925 | #endif |
914 | || defined (CONFIG_ARCH_PNX4008) \ | 926 | |
915 | ) | 927 | #if !defined(PCI_DRIVER) && \ |
928 | !defined(PLATFORM_DRIVER) && \ | ||
929 | !defined(OF_PLATFORM_DRIVER) && \ | ||
930 | !defined(SA1111_DRIVER) && \ | ||
931 | !defined(PS3_SYSTEM_BUS_DRIVER) | ||
916 | #error "missing bus glue for ohci-hcd" | 932 | #error "missing bus glue for ohci-hcd" |
917 | #endif | 933 | #endif |
934 | |||
935 | static int __init ohci_hcd_mod_init(void) | ||
936 | { | ||
937 | int retval = 0; | ||
938 | |||
939 | if (usb_disabled()) | ||
940 | return -ENODEV; | ||
941 | |||
942 | printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name); | ||
943 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
944 | sizeof (struct ed), sizeof (struct td)); | ||
945 | |||
946 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
947 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | ||
948 | if (retval < 0) | ||
949 | goto error_ps3; | ||
950 | #endif | ||
951 | |||
952 | #ifdef PLATFORM_DRIVER | ||
953 | retval = platform_driver_register(&PLATFORM_DRIVER); | ||
954 | if (retval < 0) | ||
955 | goto error_platform; | ||
956 | #endif | ||
957 | |||
958 | #ifdef OF_PLATFORM_DRIVER | ||
959 | retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); | ||
960 | if (retval < 0) | ||
961 | goto error_of_platform; | ||
962 | #endif | ||
963 | |||
964 | #ifdef SA1111_DRIVER | ||
965 | retval = sa1111_driver_register(&SA1111_DRIVER); | ||
966 | if (retval < 0) | ||
967 | goto error_sa1111; | ||
968 | #endif | ||
969 | |||
970 | #ifdef PCI_DRIVER | ||
971 | retval = pci_register_driver(&PCI_DRIVER); | ||
972 | if (retval < 0) | ||
973 | goto error_pci; | ||
974 | #endif | ||
975 | |||
976 | return retval; | ||
977 | |||
978 | /* Error path */ | ||
979 | #ifdef PCI_DRIVER | ||
980 | error_pci: | ||
981 | #endif | ||
982 | #ifdef SA1111_DRIVER | ||
983 | sa1111_driver_unregister(&SA1111_DRIVER); | ||
984 | error_sa1111: | ||
985 | #endif | ||
986 | #ifdef OF_PLATFORM_DRIVER | ||
987 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
988 | error_of_platform: | ||
989 | #endif | ||
990 | #ifdef PLATFORM_DRIVER | ||
991 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
992 | error_platform: | ||
993 | #endif | ||
994 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
995 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
996 | error_ps3: | ||
997 | #endif | ||
998 | return retval; | ||
999 | } | ||
1000 | module_init(ohci_hcd_mod_init); | ||
1001 | |||
1002 | static void __exit ohci_hcd_mod_exit(void) | ||
1003 | { | ||
1004 | #ifdef PCI_DRIVER | ||
1005 | pci_unregister_driver(&PCI_DRIVER); | ||
1006 | #endif | ||
1007 | #ifdef SA1111_DRIVER | ||
1008 | sa1111_driver_unregister(&SA1111_DRIVER); | ||
1009 | #endif | ||
1010 | #ifdef OF_PLATFORM_DRIVER | ||
1011 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
1012 | #endif | ||
1013 | #ifdef PLATFORM_DRIVER | ||
1014 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
1015 | #endif | ||
1016 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
1017 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
1018 | #endif | ||
1019 | } | ||
1020 | module_exit(ohci_hcd_mod_exit); | ||
1021 | |||
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index e9807cf73a2f..4a043abd85ea 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -251,19 +251,3 @@ static struct platform_driver ohci_hcd_lh7a404_driver = { | |||
251 | }, | 251 | }, |
252 | }; | 252 | }; |
253 | 253 | ||
254 | static int __init ohci_hcd_lh7a404_init (void) | ||
255 | { | ||
256 | pr_debug (DRIVER_INFO " (LH7A404)"); | ||
257 | pr_debug ("block sizes: ed %d td %d\n", | ||
258 | sizeof (struct ed), sizeof (struct td)); | ||
259 | |||
260 | return platform_driver_register(&ohci_hcd_lh7a404_driver); | ||
261 | } | ||
262 | |||
263 | static void __exit ohci_hcd_lh7a404_cleanup (void) | ||
264 | { | ||
265 | platform_driver_unregister(&ohci_hcd_lh7a404_driver); | ||
266 | } | ||
267 | |||
268 | module_init (ohci_hcd_lh7a404_init); | ||
269 | module_exit (ohci_hcd_lh7a404_cleanup); | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 27be1f936885..5cfa3d1c4413 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -544,22 +544,3 @@ static struct platform_driver ohci_hcd_omap_driver = { | |||
544 | }, | 544 | }, |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static int __init ohci_hcd_omap_init (void) | ||
548 | { | ||
549 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (OMAP)\n", hcd_name); | ||
550 | if (usb_disabled()) | ||
551 | return -ENODEV; | ||
552 | |||
553 | pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
554 | sizeof (struct ed), sizeof (struct td)); | ||
555 | |||
556 | return platform_driver_register(&ohci_hcd_omap_driver); | ||
557 | } | ||
558 | |||
559 | static void __exit ohci_hcd_omap_cleanup (void) | ||
560 | { | ||
561 | platform_driver_unregister(&ohci_hcd_omap_driver); | ||
562 | } | ||
563 | |||
564 | module_init (ohci_hcd_omap_init); | ||
565 | module_exit (ohci_hcd_omap_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 596e0b41e606..b331ac4d0d62 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -20,79 +20,154 @@ | |||
20 | 20 | ||
21 | /*-------------------------------------------------------------------------*/ | 21 | /*-------------------------------------------------------------------------*/ |
22 | 22 | ||
23 | static int | 23 | /* AMD 756, for most chips (early revs), corrupts register |
24 | ohci_pci_reset (struct usb_hcd *hcd) | 24 | * values on read ... so enable the vendor workaround. |
25 | */ | ||
26 | static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd) | ||
25 | { | 27 | { |
26 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 28 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
27 | 29 | ||
28 | ohci_hcd_init (ohci); | 30 | ohci->flags = OHCI_QUIRK_AMD756; |
29 | return ohci_init (ohci); | 31 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); |
32 | |||
33 | /* also erratum 10 (suspend/resume issues) */ | ||
34 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
35 | |||
36 | return 0; | ||
30 | } | 37 | } |
31 | 38 | ||
32 | static int __devinit | 39 | /* Apple's OHCI driver has a lot of bizarre workarounds |
33 | ohci_pci_start (struct usb_hcd *hcd) | 40 | * for this chip. Evidently control and bulk lists |
41 | * can get confused. (B&W G3 models, and ...) | ||
42 | */ | ||
43 | static int __devinit ohci_quirk_opti(struct usb_hcd *hcd) | ||
34 | { | 44 | { |
35 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 45 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
36 | int ret; | ||
37 | 46 | ||
38 | /* REVISIT this whole block should move to reset(), which handles | 47 | ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n"); |
39 | * all the other one-time init. | 48 | |
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* Check for NSC87560. We have to look at the bridge (fn1) to | ||
53 | * identify the USB (fn2). This quirk might apply to more or | ||
54 | * even all NSC stuff. | ||
55 | */ | ||
56 | static int __devinit ohci_quirk_ns(struct usb_hcd *hcd) | ||
57 | { | ||
58 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
59 | struct pci_dev *b; | ||
60 | |||
61 | b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
62 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
63 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
64 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
65 | |||
66 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
67 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
68 | } | ||
69 | pci_dev_put(b); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | /* Check for Compaq's ZFMicro chipset, which needs short | ||
75 | * delays before control or bulk queues get re-activated | ||
76 | * in finish_unlinks() | ||
77 | */ | ||
78 | static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) | ||
79 | { | ||
80 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
81 | |||
82 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
83 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* Check for Toshiba SCC OHCI which has big endian registers | ||
89 | * and little endian in memory data structures | ||
90 | */ | ||
91 | static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | ||
92 | { | ||
93 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
94 | |||
95 | /* That chip is only present in the southbridge of some | ||
96 | * cell based platforms which are supposed to select | ||
97 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if | ||
98 | * that was the case though. | ||
99 | */ | ||
100 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
101 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
102 | ohci_dbg (ohci, "enabled big endian Toshiba quirk\n"); | ||
103 | return 0; | ||
104 | #else | ||
105 | ohci_err (ohci, "unsupported big endian Toshiba quirk\n"); | ||
106 | return -ENXIO; | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | /* List of quirks for OHCI */ | ||
111 | static const struct pci_device_id ohci_pci_quirks[] = { | ||
112 | { | ||
113 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c), | ||
114 | .driver_data = (unsigned long)ohci_quirk_amd756, | ||
115 | }, | ||
116 | { | ||
117 | PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861), | ||
118 | .driver_data = (unsigned long)ohci_quirk_opti, | ||
119 | }, | ||
120 | { | ||
121 | PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID), | ||
122 | .driver_data = (unsigned long)ohci_quirk_ns, | ||
123 | }, | ||
124 | { | ||
125 | PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), | ||
126 | .driver_data = (unsigned long)ohci_quirk_zfmicro, | ||
127 | }, | ||
128 | { | ||
129 | PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), | ||
130 | .driver_data = (unsigned long)ohci_quirk_toshiba_scc, | ||
131 | }, | ||
132 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
133 | * won't work at all. blacklist them. | ||
40 | */ | 134 | */ |
135 | |||
136 | {}, | ||
137 | }; | ||
138 | |||
139 | static int ohci_pci_reset (struct usb_hcd *hcd) | ||
140 | { | ||
141 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
142 | int ret = 0; | ||
143 | |||
41 | if (hcd->self.controller) { | 144 | if (hcd->self.controller) { |
42 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 145 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
146 | const struct pci_device_id *quirk_id; | ||
43 | 147 | ||
44 | /* AMD 756, for most chips (early revs), corrupts register | 148 | quirk_id = pci_match_id(ohci_pci_quirks, pdev); |
45 | * values on read ... so enable the vendor workaround. | 149 | if (quirk_id != NULL) { |
46 | */ | 150 | int (*quirk)(struct usb_hcd *ohci); |
47 | if (pdev->vendor == PCI_VENDOR_ID_AMD | 151 | quirk = (void *)quirk_id->driver_data; |
48 | && pdev->device == 0x740c) { | 152 | ret = quirk(hcd); |
49 | ohci->flags = OHCI_QUIRK_AMD756; | ||
50 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); | ||
51 | /* also erratum 10 (suspend/resume issues) */ | ||
52 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
53 | } | 153 | } |
154 | } | ||
155 | if (ret == 0) { | ||
156 | ohci_hcd_init (ohci); | ||
157 | return ohci_init (ohci); | ||
158 | } | ||
159 | return ret; | ||
160 | } | ||
54 | 161 | ||
55 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
56 | * won't work at all. blacklist them. | ||
57 | */ | ||
58 | |||
59 | /* Apple's OHCI driver has a lot of bizarre workarounds | ||
60 | * for this chip. Evidently control and bulk lists | ||
61 | * can get confused. (B&W G3 models, and ...) | ||
62 | */ | ||
63 | else if (pdev->vendor == PCI_VENDOR_ID_OPTI | ||
64 | && pdev->device == 0xc861) { | ||
65 | ohci_dbg (ohci, | ||
66 | "WARNING: OPTi workarounds unavailable\n"); | ||
67 | } | ||
68 | 162 | ||
69 | /* Check for NSC87560. We have to look at the bridge (fn1) to | 163 | static int __devinit ohci_pci_start (struct usb_hcd *hcd) |
70 | * identify the USB (fn2). This quirk might apply to more or | 164 | { |
71 | * even all NSC stuff. | 165 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
72 | */ | 166 | int ret; |
73 | else if (pdev->vendor == PCI_VENDOR_ID_NS) { | ||
74 | struct pci_dev *b; | ||
75 | |||
76 | b = pci_get_slot (pdev->bus, | ||
77 | PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
78 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
79 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
80 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
81 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
82 | } | ||
83 | pci_dev_put(b); | ||
84 | } | ||
85 | 167 | ||
86 | /* Check for Compaq's ZFMicro chipset, which needs short | 168 | #ifdef CONFIG_PM /* avoid warnings about unused pdev */ |
87 | * delays before control or bulk queues get re-activated | 169 | if (hcd->self.controller) { |
88 | * in finish_unlinks() | 170 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
89 | */ | ||
90 | else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ | ||
91 | && pdev->device == 0xa0f8) { | ||
92 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
93 | ohci_dbg (ohci, | ||
94 | "enabled Compaq ZFMicro chipset quirk\n"); | ||
95 | } | ||
96 | 171 | ||
97 | /* RWC may not be set for add-in PCI cards, since boot | 172 | /* RWC may not be set for add-in PCI cards, since boot |
98 | * firmware probably ignored them. This transfers PCI | 173 | * firmware probably ignored them. This transfers PCI |
@@ -101,16 +176,14 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
101 | if (device_may_wakeup(&pdev->dev)) | 176 | if (device_may_wakeup(&pdev->dev)) |
102 | ohci->hc_control |= OHCI_CTRL_RWC; | 177 | ohci->hc_control |= OHCI_CTRL_RWC; |
103 | } | 178 | } |
179 | #endif /* CONFIG_PM */ | ||
104 | 180 | ||
105 | /* NOTE: there may have already been a first reset, to | 181 | ret = ohci_run (ohci); |
106 | * keep bios/smm irqs from making trouble | 182 | if (ret < 0) { |
107 | */ | ||
108 | if ((ret = ohci_run (ohci)) < 0) { | ||
109 | ohci_err (ohci, "can't start\n"); | 183 | ohci_err (ohci, "can't start\n"); |
110 | ohci_stop (hcd); | 184 | ohci_stop (hcd); |
111 | return ret; | ||
112 | } | 185 | } |
113 | return 0; | 186 | return ret; |
114 | } | 187 | } |
115 | 188 | ||
116 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM |
@@ -238,23 +311,3 @@ static struct pci_driver ohci_pci_driver = { | |||
238 | .shutdown = usb_hcd_pci_shutdown, | 311 | .shutdown = usb_hcd_pci_shutdown, |
239 | }; | 312 | }; |
240 | 313 | ||
241 | |||
242 | static int __init ohci_hcd_pci_init (void) | ||
243 | { | ||
244 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); | ||
245 | if (usb_disabled()) | ||
246 | return -ENODEV; | ||
247 | |||
248 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
249 | sizeof (struct ed), sizeof (struct td)); | ||
250 | return pci_register_driver (&ohci_pci_driver); | ||
251 | } | ||
252 | module_init (ohci_hcd_pci_init); | ||
253 | |||
254 | /*-------------------------------------------------------------------------*/ | ||
255 | |||
256 | static void __exit ohci_hcd_pci_cleanup (void) | ||
257 | { | ||
258 | pci_unregister_driver (&ohci_pci_driver); | ||
259 | } | ||
260 | module_exit (ohci_hcd_pci_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 3a8cbfb69054..893b172384da 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -465,15 +465,3 @@ static struct platform_driver usb_hcd_pnx4008_driver = { | |||
465 | .remove = usb_hcd_pnx4008_remove, | 465 | .remove = usb_hcd_pnx4008_remove, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | static int __init usb_hcd_pnx4008_init(void) | ||
469 | { | ||
470 | return platform_driver_register(&usb_hcd_pnx4008_driver); | ||
471 | } | ||
472 | |||
473 | static void __exit usb_hcd_pnx4008_cleanup(void) | ||
474 | { | ||
475 | return platform_driver_unregister(&usb_hcd_pnx4008_driver); | ||
476 | } | ||
477 | |||
478 | module_init(usb_hcd_pnx4008_init); | ||
479 | module_exit(usb_hcd_pnx4008_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c index 6922b91b1704..de45eb0051a7 100644 --- a/drivers/usb/host/ohci-pnx8550.c +++ b/drivers/usb/host/ohci-pnx8550.c | |||
@@ -240,19 +240,3 @@ static struct platform_driver ohci_hcd_pnx8550_driver = { | |||
240 | .remove = ohci_hcd_pnx8550_drv_remove, | 240 | .remove = ohci_hcd_pnx8550_drv_remove, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static int __init ohci_hcd_pnx8550_init (void) | ||
244 | { | ||
245 | pr_debug (DRIVER_INFO " (pnx8550)"); | ||
246 | pr_debug ("block sizes: ed %d td %d\n", | ||
247 | sizeof (struct ed), sizeof (struct td)); | ||
248 | |||
249 | return platform_driver_register(&ohci_hcd_pnx8550_driver); | ||
250 | } | ||
251 | |||
252 | static void __exit ohci_hcd_pnx8550_cleanup (void) | ||
253 | { | ||
254 | platform_driver_unregister(&ohci_hcd_pnx8550_driver); | ||
255 | } | ||
256 | |||
257 | module_init (ohci_hcd_pnx8550_init); | ||
258 | module_exit (ohci_hcd_pnx8550_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c new file mode 100644 index 000000000000..08e237c7bc43 --- /dev/null +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2006 Sylvain Munaut <tnt@246tNt.com> | ||
8 | * | ||
9 | * Bus glue for OHCI HC on the of_platform bus | ||
10 | * | ||
11 | * Modified for of_platform bus from ohci-sa1111.c | ||
12 | * | ||
13 | * This file is licenced under the GPL. | ||
14 | */ | ||
15 | |||
16 | #include <linux/signal.h> | ||
17 | |||
18 | #include <asm/of_platform.h> | ||
19 | #include <asm/prom.h> | ||
20 | |||
21 | |||
22 | static int __devinit | ||
23 | ohci_ppc_of_start(struct usb_hcd *hcd) | ||
24 | { | ||
25 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
26 | int ret; | ||
27 | |||
28 | if ((ret = ohci_init(ohci)) < 0) | ||
29 | return ret; | ||
30 | |||
31 | if ((ret = ohci_run(ohci)) < 0) { | ||
32 | err("can't start %s", ohci_to_hcd(ohci)->self.bus_name); | ||
33 | ohci_stop(hcd); | ||
34 | return ret; | ||
35 | } | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static const struct hc_driver ohci_ppc_of_hc_driver = { | ||
41 | .description = hcd_name, | ||
42 | .product_desc = "OF OHCI", | ||
43 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
44 | |||
45 | /* | ||
46 | * generic hardware linkage | ||
47 | */ | ||
48 | .irq = ohci_irq, | ||
49 | .flags = HCD_USB11 | HCD_MEMORY, | ||
50 | |||
51 | /* | ||
52 | * basic lifecycle operations | ||
53 | */ | ||
54 | .start = ohci_ppc_of_start, | ||
55 | .stop = ohci_stop, | ||
56 | .shutdown = ohci_shutdown, | ||
57 | |||
58 | /* | ||
59 | * managing i/o requests and associated device resources | ||
60 | */ | ||
61 | .urb_enqueue = ohci_urb_enqueue, | ||
62 | .urb_dequeue = ohci_urb_dequeue, | ||
63 | .endpoint_disable = ohci_endpoint_disable, | ||
64 | |||
65 | /* | ||
66 | * scheduling support | ||
67 | */ | ||
68 | .get_frame_number = ohci_get_frame, | ||
69 | |||
70 | /* | ||
71 | * root hub support | ||
72 | */ | ||
73 | .hub_status_data = ohci_hub_status_data, | ||
74 | .hub_control = ohci_hub_control, | ||
75 | .hub_irq_enable = ohci_rhsc_enable, | ||
76 | #ifdef CONFIG_PM | ||
77 | .bus_suspend = ohci_bus_suspend, | ||
78 | .bus_resume = ohci_bus_resume, | ||
79 | #endif | ||
80 | .start_port_reset = ohci_start_port_reset, | ||
81 | }; | ||
82 | |||
83 | |||
84 | static int __devinit | ||
85 | ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | ||
86 | { | ||
87 | struct device_node *dn = op->node; | ||
88 | struct usb_hcd *hcd; | ||
89 | struct ohci_hcd *ohci; | ||
90 | struct resource res; | ||
91 | int irq; | ||
92 | |||
93 | int rv; | ||
94 | int is_bigendian; | ||
95 | |||
96 | if (usb_disabled()) | ||
97 | return -ENODEV; | ||
98 | |||
99 | is_bigendian = | ||
100 | device_is_compatible(dn, "ohci-bigendian") || | ||
101 | device_is_compatible(dn, "ohci-be"); | ||
102 | |||
103 | dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); | ||
104 | |||
105 | rv = of_address_to_resource(dn, 0, &res); | ||
106 | if (rv) | ||
107 | return rv; | ||
108 | |||
109 | hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); | ||
110 | if (!hcd) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | hcd->rsrc_start = res.start; | ||
114 | hcd->rsrc_len = res.end - res.start + 1; | ||
115 | |||
116 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
117 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | ||
118 | rv = -EBUSY; | ||
119 | goto err_rmr; | ||
120 | } | ||
121 | |||
122 | irq = irq_of_parse_and_map(dn, 0); | ||
123 | if (irq == NO_IRQ) { | ||
124 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | ||
125 | rv = -EBUSY; | ||
126 | goto err_irq; | ||
127 | } | ||
128 | |||
129 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
130 | if (!hcd->regs) { | ||
131 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | ||
132 | rv = -ENOMEM; | ||
133 | goto err_ioremap; | ||
134 | } | ||
135 | |||
136 | ohci = hcd_to_ohci(hcd); | ||
137 | if (is_bigendian) | ||
138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | ||
139 | |||
140 | ohci_hcd_init(ohci); | ||
141 | |||
142 | rv = usb_add_hcd(hcd, irq, 0); | ||
143 | if (rv == 0) | ||
144 | return 0; | ||
145 | |||
146 | iounmap(hcd->regs); | ||
147 | err_ioremap: | ||
148 | irq_dispose_mapping(irq); | ||
149 | err_irq: | ||
150 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
151 | err_rmr: | ||
152 | usb_put_hcd(hcd); | ||
153 | |||
154 | return rv; | ||
155 | } | ||
156 | |||
157 | static int ohci_hcd_ppc_of_remove(struct of_device *op) | ||
158 | { | ||
159 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
160 | dev_set_drvdata(&op->dev, NULL); | ||
161 | |||
162 | dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); | ||
163 | |||
164 | usb_remove_hcd(hcd); | ||
165 | |||
166 | iounmap(hcd->regs); | ||
167 | irq_dispose_mapping(hcd->irq); | ||
168 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
169 | |||
170 | usb_put_hcd(hcd); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int ohci_hcd_ppc_of_shutdown(struct of_device *op) | ||
176 | { | ||
177 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
178 | |||
179 | if (hcd->driver->shutdown) | ||
180 | hcd->driver->shutdown(hcd); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | |||
186 | static struct of_device_id ohci_hcd_ppc_of_match[] = { | ||
187 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE | ||
188 | { | ||
189 | .name = "usb", | ||
190 | .compatible = "ohci-bigendian", | ||
191 | }, | ||
192 | { | ||
193 | .name = "usb", | ||
194 | .compatible = "ohci-be", | ||
195 | }, | ||
196 | #endif | ||
197 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_LE | ||
198 | { | ||
199 | .name = "usb", | ||
200 | .compatible = "ohci-littledian", | ||
201 | }, | ||
202 | { | ||
203 | .name = "usb", | ||
204 | .compatible = "ohci-le", | ||
205 | }, | ||
206 | #endif | ||
207 | {}, | ||
208 | }; | ||
209 | MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); | ||
210 | |||
211 | #if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \ | ||
212 | !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE) | ||
213 | #error "No endianess selected for ppc-of-ohci" | ||
214 | #endif | ||
215 | |||
216 | |||
217 | static struct of_platform_driver ohci_hcd_ppc_of_driver = { | ||
218 | .name = "ppc-of-ohci", | ||
219 | .match_table = ohci_hcd_ppc_of_match, | ||
220 | .probe = ohci_hcd_ppc_of_probe, | ||
221 | .remove = ohci_hcd_ppc_of_remove, | ||
222 | .shutdown = ohci_hcd_ppc_of_shutdown, | ||
223 | #ifdef CONFIG_PM | ||
224 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | ||
225 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | ||
226 | #endif | ||
227 | .driver = { | ||
228 | .name = "ppc-of-ohci", | ||
229 | .owner = THIS_MODULE, | ||
230 | }, | ||
231 | }; | ||
232 | |||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index e1a7eb817313..1a2e1777ca61 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -72,7 +72,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | ohci = hcd_to_ohci(hcd); | 74 | ohci = hcd_to_ohci(hcd); |
75 | ohci->flags |= OHCI_BIG_ENDIAN; | 75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
76 | ohci_hcd_init(ohci); | 76 | ohci_hcd_init(ohci); |
77 | 77 | ||
78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
@@ -208,19 +208,3 @@ static struct platform_driver ohci_hcd_ppc_soc_driver = { | |||
208 | }, | 208 | }, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | static int __init ohci_hcd_ppc_soc_init(void) | ||
212 | { | ||
213 | pr_debug(DRIVER_INFO " (PPC SOC)\n"); | ||
214 | pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed), | ||
215 | sizeof(struct td)); | ||
216 | |||
217 | return platform_driver_register(&ohci_hcd_ppc_soc_driver); | ||
218 | } | ||
219 | |||
220 | static void __exit ohci_hcd_ppc_soc_cleanup(void) | ||
221 | { | ||
222 | platform_driver_unregister(&ohci_hcd_ppc_soc_driver); | ||
223 | } | ||
224 | |||
225 | module_init(ohci_hcd_ppc_soc_init); | ||
226 | module_exit(ohci_hcd_ppc_soc_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c new file mode 100644 index 000000000000..69d948b4a701 --- /dev/null +++ b/drivers/usb/host/ohci-ps3.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * PS3 OHCI Host Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
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; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/ps3.h> | ||
22 | |||
23 | static int ps3_ohci_hc_reset(struct usb_hcd *hcd) | ||
24 | { | ||
25 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
26 | |||
27 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
28 | ohci_hcd_init(ohci); | ||
29 | return ohci_init(ohci); | ||
30 | } | ||
31 | |||
32 | static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd) | ||
33 | { | ||
34 | int result; | ||
35 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
36 | |||
37 | /* Handle root hub init quirk in spider south bridge. */ | ||
38 | /* Also set PwrOn2PwrGood to 0x7f (254ms). */ | ||
39 | |||
40 | ohci_writel(ohci, 0x7f000000 | RH_A_PSM | RH_A_OCPM, | ||
41 | &ohci->regs->roothub.a); | ||
42 | ohci_writel(ohci, 0x00060000, &ohci->regs->roothub.b); | ||
43 | |||
44 | result = ohci_run(ohci); | ||
45 | |||
46 | if (result < 0) { | ||
47 | err("can't start %s", hcd->self.bus_name); | ||
48 | ohci_stop(hcd); | ||
49 | } | ||
50 | |||
51 | return result; | ||
52 | } | ||
53 | |||
54 | static const struct hc_driver ps3_ohci_hc_driver = { | ||
55 | .description = hcd_name, | ||
56 | .product_desc = "PS3 OHCI Host Controller", | ||
57 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
58 | .irq = ohci_irq, | ||
59 | .flags = HCD_MEMORY | HCD_USB11, | ||
60 | .reset = ps3_ohci_hc_reset, | ||
61 | .start = ps3_ohci_hc_start, | ||
62 | .stop = ohci_stop, | ||
63 | .shutdown = ohci_shutdown, | ||
64 | .urb_enqueue = ohci_urb_enqueue, | ||
65 | .urb_dequeue = ohci_urb_dequeue, | ||
66 | .endpoint_disable = ohci_endpoint_disable, | ||
67 | .get_frame_number = ohci_get_frame, | ||
68 | .hub_status_data = ohci_hub_status_data, | ||
69 | .hub_control = ohci_hub_control, | ||
70 | .hub_irq_enable = ohci_rhsc_enable, | ||
71 | .start_port_reset = ohci_start_port_reset, | ||
72 | #if defined(CONFIG_PM) | ||
73 | .bus_suspend = ohci_bus_suspend, | ||
74 | .bus_resume = ohci_bus_resume, | ||
75 | #endif | ||
76 | }; | ||
77 | |||
78 | /* redefine dev_dbg to do a syntax check */ | ||
79 | |||
80 | #if !defined(DEBUG) | ||
81 | #undef dev_dbg | ||
82 | static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( | ||
83 | const struct device *_dev, const char *fmt, ...) {return 0;} | ||
84 | #endif | ||
85 | |||
86 | static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) | ||
87 | { | ||
88 | int result; | ||
89 | struct usb_hcd *hcd; | ||
90 | unsigned int virq; | ||
91 | static u64 dummy_mask = DMA_32BIT_MASK; | ||
92 | |||
93 | if (usb_disabled()) { | ||
94 | result = -ENODEV; | ||
95 | goto fail_start; | ||
96 | } | ||
97 | |||
98 | result = ps3_mmio_region_create(dev->m_region); | ||
99 | |||
100 | if (result) { | ||
101 | dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", | ||
102 | __func__, __LINE__); | ||
103 | result = -EPERM; | ||
104 | goto fail_mmio; | ||
105 | } | ||
106 | |||
107 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | ||
108 | __LINE__, dev->m_region->lpar_addr); | ||
109 | |||
110 | result = ps3_alloc_io_irq(dev->interrupt_id, &virq); | ||
111 | |||
112 | if (result) { | ||
113 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | ||
114 | __func__, __LINE__, virq); | ||
115 | result = -EPERM; | ||
116 | goto fail_irq; | ||
117 | } | ||
118 | |||
119 | dev->core.power.power_state = PMSG_ON; | ||
120 | dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ | ||
121 | |||
122 | hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id); | ||
123 | |||
124 | if (!hcd) { | ||
125 | dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, | ||
126 | __LINE__); | ||
127 | result = -ENOMEM; | ||
128 | goto fail_create_hcd; | ||
129 | } | ||
130 | |||
131 | hcd->rsrc_start = dev->m_region->lpar_addr; | ||
132 | hcd->rsrc_len = dev->m_region->len; | ||
133 | hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); | ||
134 | |||
135 | if (!hcd->regs) { | ||
136 | dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, | ||
137 | __LINE__); | ||
138 | result = -EPERM; | ||
139 | goto fail_ioremap; | ||
140 | } | ||
141 | |||
142 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, | ||
143 | (unsigned long)hcd->rsrc_start); | ||
144 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, | ||
145 | (unsigned long)hcd->rsrc_len); | ||
146 | dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, | ||
147 | (unsigned long)hcd->regs); | ||
148 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | ||
149 | (unsigned long)virq); | ||
150 | |||
151 | ps3_system_bus_set_driver_data(dev, hcd); | ||
152 | |||
153 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | ||
154 | |||
155 | if (result) { | ||
156 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | ||
157 | __func__, __LINE__, result); | ||
158 | goto fail_add_hcd; | ||
159 | } | ||
160 | |||
161 | return result; | ||
162 | |||
163 | fail_add_hcd: | ||
164 | iounmap(hcd->regs); | ||
165 | fail_ioremap: | ||
166 | usb_put_hcd(hcd); | ||
167 | fail_create_hcd: | ||
168 | ps3_free_io_irq(virq); | ||
169 | fail_irq: | ||
170 | ps3_free_mmio_region(dev->m_region); | ||
171 | fail_mmio: | ||
172 | fail_start: | ||
173 | return result; | ||
174 | } | ||
175 | |||
176 | static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev) | ||
177 | { | ||
178 | struct usb_hcd *hcd = | ||
179 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
180 | |||
181 | usb_put_hcd(hcd); | ||
182 | ps3_system_bus_set_driver_data(dev, NULL); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | MODULE_ALIAS("ps3-ohci"); | ||
188 | |||
189 | static struct ps3_system_bus_driver ps3_ohci_sb_driver = { | ||
190 | .match_id = PS3_MATCH_ID_OHCI, | ||
191 | .core = { | ||
192 | .name = "ps3-ohci-driver", | ||
193 | }, | ||
194 | .probe = ps3_ohci_sb_probe, | ||
195 | .remove = ps3_ohci_sb_remove, | ||
196 | }; | ||
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 3bbea844a9e3..f1563dc319d3 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -369,19 +369,3 @@ static struct platform_driver ohci_hcd_pxa27x_driver = { | |||
369 | }, | 369 | }, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int __init ohci_hcd_pxa27x_init (void) | ||
373 | { | ||
374 | pr_debug (DRIVER_INFO " (pxa27x)"); | ||
375 | pr_debug ("block sizes: ed %d td %d\n", | ||
376 | sizeof (struct ed), sizeof (struct td)); | ||
377 | |||
378 | return platform_driver_register(&ohci_hcd_pxa27x_driver); | ||
379 | } | ||
380 | |||
381 | static void __exit ohci_hcd_pxa27x_cleanup (void) | ||
382 | { | ||
383 | platform_driver_unregister(&ohci_hcd_pxa27x_driver); | ||
384 | } | ||
385 | |||
386 | module_init (ohci_hcd_pxa27x_init); | ||
387 | module_exit (ohci_hcd_pxa27x_cleanup); | ||
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index b350d45033e7..6829814b7aaf 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -501,15 +501,3 @@ static struct platform_driver ohci_hcd_s3c2410_driver = { | |||
501 | }, | 501 | }, |
502 | }; | 502 | }; |
503 | 503 | ||
504 | static int __init ohci_hcd_s3c2410_init (void) | ||
505 | { | ||
506 | return platform_driver_register(&ohci_hcd_s3c2410_driver); | ||
507 | } | ||
508 | |||
509 | static void __exit ohci_hcd_s3c2410_cleanup (void) | ||
510 | { | ||
511 | platform_driver_unregister(&ohci_hcd_s3c2410_driver); | ||
512 | } | ||
513 | |||
514 | module_init (ohci_hcd_s3c2410_init); | ||
515 | module_exit (ohci_hcd_s3c2410_cleanup); | ||
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index fe0090e33675..0f48f2d99226 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -269,19 +269,3 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { | |||
269 | .remove = ohci_hcd_sa1111_drv_remove, | 269 | .remove = ohci_hcd_sa1111_drv_remove, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static int __init ohci_hcd_sa1111_init (void) | ||
273 | { | ||
274 | dbg (DRIVER_INFO " (SA-1111)"); | ||
275 | dbg ("block sizes: ed %d td %d", | ||
276 | sizeof (struct ed), sizeof (struct td)); | ||
277 | |||
278 | return sa1111_driver_register(&ohci_hcd_sa1111_driver); | ||
279 | } | ||
280 | |||
281 | static void __exit ohci_hcd_sa1111_cleanup (void) | ||
282 | { | ||
283 | sa1111_driver_unregister(&ohci_hcd_sa1111_driver); | ||
284 | } | ||
285 | |||
286 | module_init (ohci_hcd_sa1111_init); | ||
287 | module_exit (ohci_hcd_sa1111_cleanup); | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 405257f3e853..0dafcda37291 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -394,8 +394,9 @@ struct ohci_hcd { | |||
394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ | 394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ |
395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ | 395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ |
396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ | 396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ |
397 | #define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ | 397 | #define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ |
398 | #define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ | 398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ |
399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ | ||
399 | // there are also chip quirks/bugs in init logic | 400 | // there are also chip quirks/bugs in init logic |
400 | 401 | ||
401 | }; | 402 | }; |
@@ -439,117 +440,164 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) | |||
439 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 | 440 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 |
440 | * processors) implement them in big endian format. | 441 | * processors) implement them in big endian format. |
441 | * | 442 | * |
443 | * In addition some more exotic implementations like the Toshiba | ||
444 | * Spider (aka SCC) cell southbridge are "mixed" endian, that is, | ||
445 | * they have a different endianness for registers vs. in-memory | ||
446 | * descriptors. | ||
447 | * | ||
442 | * This attempts to support either format at compile time without a | 448 | * This attempts to support either format at compile time without a |
443 | * runtime penalty, or both formats with the additional overhead | 449 | * runtime penalty, or both formats with the additional overhead |
444 | * of checking a flag bit. | 450 | * of checking a flag bit. |
451 | * | ||
452 | * That leads to some tricky Kconfig rules howevber. There are | ||
453 | * different defaults based on some arch/ppc platforms, though | ||
454 | * the basic rules are: | ||
455 | * | ||
456 | * Controller type Kconfig options needed | ||
457 | * --------------- ---------------------- | ||
458 | * little endian CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
459 | * | ||
460 | * fully big endian CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_ | ||
461 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
462 | * | ||
463 | * mixed endian CONFIG_USB_OHCI_LITTLE_ENDIAN _and_ | ||
464 | * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} | ||
465 | * | ||
466 | * (If you have a mixed endian controller, you -must- also define | ||
467 | * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building | ||
468 | * both your mixed endian and a fully big endian controller support in | ||
469 | * the same kernel image). | ||
445 | */ | 470 | */ |
446 | 471 | ||
447 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN | 472 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC |
473 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
474 | #define big_endian_desc(ohci) (ohci->flags & OHCI_QUIRK_BE_DESC) | ||
475 | #else | ||
476 | #define big_endian_desc(ohci) 1 /* only big endian */ | ||
477 | #endif | ||
478 | #else | ||
479 | #define big_endian_desc(ohci) 0 /* only little endian */ | ||
480 | #endif | ||
448 | 481 | ||
482 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
449 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | 483 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN |
450 | #define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */ | 484 | #define big_endian_mmio(ohci) (ohci->flags & OHCI_QUIRK_BE_MMIO) |
451 | #else | 485 | #else |
452 | #define big_endian(ohci) 1 /* only big endian */ | 486 | #define big_endian_mmio(ohci) 1 /* only big endian */ |
487 | #endif | ||
488 | #else | ||
489 | #define big_endian_mmio(ohci) 0 /* only little endian */ | ||
453 | #endif | 490 | #endif |
454 | 491 | ||
455 | /* | 492 | /* |
456 | * Big-endian read/write functions are arch-specific. | 493 | * Big-endian read/write functions are arch-specific. |
457 | * Other arches can be added if/when they're needed. | 494 | * Other arches can be added if/when they're needed. |
495 | * | ||
496 | * REVISIT: arch/powerpc now has readl/writel_be, so the | ||
497 | * definition below can die once the STB04xxx support is | ||
498 | * finally ported over. | ||
458 | */ | 499 | */ |
459 | #if defined(CONFIG_PPC) | 500 | #if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) |
460 | #define readl_be(addr) in_be32((__force unsigned *)addr) | 501 | #define readl_be(addr) in_be32((__force unsigned *)addr) |
461 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) | 502 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) |
462 | #endif | 503 | #endif |
463 | 504 | ||
464 | static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, | 505 | static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, |
465 | __hc32 __iomem * regs) | 506 | __hc32 __iomem * regs) |
466 | { | 507 | { |
467 | return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs); | 508 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO |
509 | return big_endian_mmio(ohci) ? | ||
510 | readl_be ((__force u32 *)regs) : | ||
511 | readl ((__force u32 *)regs); | ||
512 | #else | ||
513 | return readl ((__force u32 *)regs); | ||
514 | #endif | ||
468 | } | 515 | } |
469 | 516 | ||
470 | static inline void ohci_writel (const struct ohci_hcd *ohci, | 517 | static inline void _ohci_writel (const struct ohci_hcd *ohci, |
471 | const unsigned int val, __hc32 __iomem *regs) | 518 | const unsigned int val, __hc32 __iomem *regs) |
472 | { | 519 | { |
473 | big_endian(ohci) ? writel_be (val, regs) : | 520 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO |
474 | writel (val, (__force u32 *)regs); | 521 | big_endian_mmio(ohci) ? |
522 | writel_be (val, (__force u32 *)regs) : | ||
523 | writel (val, (__force u32 *)regs); | ||
524 | #else | ||
525 | writel (val, (__force u32 *)regs); | ||
526 | #endif | ||
475 | } | 527 | } |
476 | 528 | ||
477 | #else /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
478 | |||
479 | #define big_endian(ohci) 0 /* only little endian */ | ||
480 | |||
481 | #ifdef CONFIG_ARCH_LH7A404 | 529 | #ifdef CONFIG_ARCH_LH7A404 |
482 | /* Marc Singer: at the time this code was written, the LH7A404 | 530 | /* Marc Singer: at the time this code was written, the LH7A404 |
483 | * had a problem reading the USB host registers. This | 531 | * had a problem reading the USB host registers. This |
484 | * implementation of the ohci_readl function performs the read | 532 | * implementation of the ohci_readl function performs the read |
485 | * twice as a work-around. | 533 | * twice as a work-around. |
486 | */ | 534 | */ |
487 | static inline unsigned int | 535 | #define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) |
488 | ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs) | 536 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
489 | { | ||
490 | *(volatile __force unsigned int*) regs; | ||
491 | return *(volatile __force unsigned int*) regs; | ||
492 | } | ||
493 | #else | 537 | #else |
494 | /* Standard version of ohci_readl uses standard, platform | 538 | #define ohci_readl(o,r) _ohci_readl(o,r) |
495 | * specific implementation. */ | 539 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
496 | static inline unsigned int | ||
497 | ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) | ||
498 | { | ||
499 | return readl(regs); | ||
500 | } | ||
501 | #endif | 540 | #endif |
502 | 541 | ||
503 | static inline void ohci_writel (const struct ohci_hcd *ohci, | ||
504 | const unsigned int val, __hc32 __iomem *regs) | ||
505 | { | ||
506 | writel (val, regs); | ||
507 | } | ||
508 | |||
509 | #endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
510 | 542 | ||
511 | /*-------------------------------------------------------------------------*/ | 543 | /*-------------------------------------------------------------------------*/ |
512 | 544 | ||
513 | /* cpu to ohci */ | 545 | /* cpu to ohci */ |
514 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) | 546 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) |
515 | { | 547 | { |
516 | return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x); | 548 | return big_endian_desc(ohci) ? |
549 | (__force __hc16)cpu_to_be16(x) : | ||
550 | (__force __hc16)cpu_to_le16(x); | ||
517 | } | 551 | } |
518 | 552 | ||
519 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) | 553 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) |
520 | { | 554 | { |
521 | return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x); | 555 | return big_endian_desc(ohci) ? |
556 | cpu_to_be16p(x) : | ||
557 | cpu_to_le16p(x); | ||
522 | } | 558 | } |
523 | 559 | ||
524 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) | 560 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) |
525 | { | 561 | { |
526 | return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); | 562 | return big_endian_desc(ohci) ? |
563 | (__force __hc32)cpu_to_be32(x) : | ||
564 | (__force __hc32)cpu_to_le32(x); | ||
527 | } | 565 | } |
528 | 566 | ||
529 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) | 567 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) |
530 | { | 568 | { |
531 | return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x); | 569 | return big_endian_desc(ohci) ? |
570 | cpu_to_be32p(x) : | ||
571 | cpu_to_le32p(x); | ||
532 | } | 572 | } |
533 | 573 | ||
534 | /* ohci to cpu */ | 574 | /* ohci to cpu */ |
535 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) | 575 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) |
536 | { | 576 | { |
537 | return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x); | 577 | return big_endian_desc(ohci) ? |
578 | be16_to_cpu((__force __be16)x) : | ||
579 | le16_to_cpu((__force __le16)x); | ||
538 | } | 580 | } |
539 | 581 | ||
540 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) | 582 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) |
541 | { | 583 | { |
542 | return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x); | 584 | return big_endian_desc(ohci) ? |
585 | be16_to_cpup((__force __be16 *)x) : | ||
586 | le16_to_cpup((__force __le16 *)x); | ||
543 | } | 587 | } |
544 | 588 | ||
545 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) | 589 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) |
546 | { | 590 | { |
547 | return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); | 591 | return big_endian_desc(ohci) ? |
592 | be32_to_cpu((__force __be32)x) : | ||
593 | le32_to_cpu((__force __le32)x); | ||
548 | } | 594 | } |
549 | 595 | ||
550 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | 596 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) |
551 | { | 597 | { |
552 | return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); | 598 | return big_endian_desc(ohci) ? |
599 | be32_to_cpup((__force __be32 *)x) : | ||
600 | le32_to_cpup((__force __le32 *)x); | ||
553 | } | 601 | } |
554 | 602 | ||
555 | /*-------------------------------------------------------------------------*/ | 603 | /*-------------------------------------------------------------------------*/ |
@@ -557,6 +605,9 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
557 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all | 605 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all |
558 | * hardware handles 16 bit reads. That creates a different confusion on | 606 | * hardware handles 16 bit reads. That creates a different confusion on |
559 | * some big-endian SOC implementations. Same thing happens with PSW access. | 607 | * some big-endian SOC implementations. Same thing happens with PSW access. |
608 | * | ||
609 | * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over | ||
610 | * to arch/powerpc | ||
560 | */ | 611 | */ |
561 | 612 | ||
562 | #ifdef CONFIG_STB03xxx | 613 | #ifdef CONFIG_STB03xxx |
@@ -568,7 +619,7 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
568 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | 619 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) |
569 | { | 620 | { |
570 | u32 tmp; | 621 | u32 tmp; |
571 | if (big_endian(ohci)) { | 622 | if (big_endian_desc(ohci)) { |
572 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); | 623 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); |
573 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; | 624 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; |
574 | } else | 625 | } else |
@@ -580,7 +631,7 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | |||
580 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, | 631 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, |
581 | const struct td *td, int index) | 632 | const struct td *td, int index) |
582 | { | 633 | { |
583 | return (__hc16 *)(big_endian(ohci) ? | 634 | return (__hc16 *)(big_endian_desc(ohci) ? |
584 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); | 635 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); |
585 | } | 636 | } |
586 | 637 | ||
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index e345f15b7d87..5d6c06bc4524 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -168,9 +168,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
168 | space, "", qh, qtype, | 168 | space, "", qh, qtype, |
169 | le32_to_cpu(qh->link), le32_to_cpu(element)); | 169 | le32_to_cpu(qh->link), le32_to_cpu(element)); |
170 | if (qh->type == USB_ENDPOINT_XFER_ISOC) | 170 | if (qh->type == USB_ENDPOINT_XFER_ISOC) |
171 | out += sprintf(out, "%*s period %d frame %x desc [%p]\n", | 171 | out += sprintf(out, "%*s period %d phase %d load %d us, " |
172 | space, "", qh->period, qh->iso_frame, | 172 | "frame %x desc [%p]\n", |
173 | qh->iso_packet_desc); | 173 | space, "", qh->period, qh->phase, qh->load, |
174 | qh->iso_frame, qh->iso_packet_desc); | ||
175 | else if (qh->type == USB_ENDPOINT_XFER_INT) | ||
176 | out += sprintf(out, "%*s period %d phase %d load %d us\n", | ||
177 | space, "", qh->period, qh->phase, qh->load); | ||
174 | 178 | ||
175 | if (element & UHCI_PTR_QH) | 179 | if (element & UHCI_PTR_QH) |
176 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); | 180 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); |
@@ -208,7 +212,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
208 | space, "", nurbs); | 212 | space, "", nurbs); |
209 | } | 213 | } |
210 | 214 | ||
211 | if (qh->udev) { | 215 | if (qh->dummy_td) { |
212 | out += sprintf(out, "%*s Dummy TD\n", space, ""); | 216 | out += sprintf(out, "%*s Dummy TD\n", space, ""); |
213 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); | 217 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); |
214 | } | 218 | } |
@@ -347,31 +351,80 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
347 | struct uhci_qh *qh; | 351 | struct uhci_qh *qh; |
348 | struct uhci_td *td; | 352 | struct uhci_td *td; |
349 | struct list_head *tmp, *head; | 353 | struct list_head *tmp, *head; |
354 | int nframes, nerrs; | ||
350 | 355 | ||
351 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); | 356 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); |
352 | out += sprintf(out, "HC status\n"); | 357 | out += sprintf(out, "HC status\n"); |
353 | out += uhci_show_status(uhci, out, len - (out - buf)); | 358 | out += uhci_show_status(uhci, out, len - (out - buf)); |
359 | |||
360 | out += sprintf(out, "Periodic load table\n"); | ||
361 | for (i = 0; i < MAX_PHASE; ++i) { | ||
362 | out += sprintf(out, "\t%d", uhci->load[i]); | ||
363 | if (i % 8 == 7) | ||
364 | *out++ = '\n'; | ||
365 | } | ||
366 | out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n", | ||
367 | uhci->total_load, | ||
368 | uhci_to_hcd(uhci)->self.bandwidth_int_reqs, | ||
369 | uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); | ||
354 | if (debug <= 1) | 370 | if (debug <= 1) |
355 | return out - buf; | 371 | return out - buf; |
356 | 372 | ||
357 | out += sprintf(out, "Frame List\n"); | 373 | out += sprintf(out, "Frame List\n"); |
374 | nframes = 10; | ||
375 | nerrs = 0; | ||
358 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 376 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
377 | __le32 link, qh_dma; | ||
378 | |||
379 | j = 0; | ||
359 | td = uhci->frame_cpu[i]; | 380 | td = uhci->frame_cpu[i]; |
381 | link = uhci->frame[i]; | ||
360 | if (!td) | 382 | if (!td) |
361 | continue; | 383 | goto check_link; |
362 | 384 | ||
363 | out += sprintf(out, "- Frame %d\n", i); \ | 385 | if (nframes > 0) { |
364 | if (td->dma_handle != (dma_addr_t)uhci->frame[i]) | 386 | out += sprintf(out, "- Frame %d -> (%08x)\n", |
365 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); | 387 | i, le32_to_cpu(link)); |
388 | j = 1; | ||
389 | } | ||
366 | 390 | ||
367 | head = &td->fl_list; | 391 | head = &td->fl_list; |
368 | tmp = head; | 392 | tmp = head; |
369 | do { | 393 | do { |
370 | td = list_entry(tmp, struct uhci_td, fl_list); | 394 | td = list_entry(tmp, struct uhci_td, fl_list); |
371 | tmp = tmp->next; | 395 | tmp = tmp->next; |
372 | out += uhci_show_td(td, out, len - (out - buf), 4); | 396 | if (cpu_to_le32(td->dma_handle) != link) { |
397 | if (nframes > 0) | ||
398 | out += sprintf(out, " link does " | ||
399 | "not match list entry!\n"); | ||
400 | else | ||
401 | ++nerrs; | ||
402 | } | ||
403 | if (nframes > 0) | ||
404 | out += uhci_show_td(td, out, | ||
405 | len - (out - buf), 4); | ||
406 | link = td->link; | ||
373 | } while (tmp != head); | 407 | } while (tmp != head); |
408 | |||
409 | check_link: | ||
410 | qh_dma = uhci_frame_skel_link(uhci, i); | ||
411 | if (link != qh_dma) { | ||
412 | if (nframes > 0) { | ||
413 | if (!j) { | ||
414 | out += sprintf(out, | ||
415 | "- Frame %d -> (%08x)\n", | ||
416 | i, le32_to_cpu(link)); | ||
417 | j = 1; | ||
418 | } | ||
419 | out += sprintf(out, " link does not match " | ||
420 | "QH (%08x)!\n", le32_to_cpu(qh_dma)); | ||
421 | } else | ||
422 | ++nerrs; | ||
423 | } | ||
424 | nframes -= j; | ||
374 | } | 425 | } |
426 | if (nerrs > 0) | ||
427 | out += sprintf(out, "Skipped %d bad links\n", nerrs); | ||
375 | 428 | ||
376 | out += sprintf(out, "Skeleton QHs\n"); | 429 | out += sprintf(out, "Skeleton QHs\n"); |
377 | 430 | ||
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index e0d4c2358b39..49b9d390b95f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -92,6 +92,34 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); | |||
92 | static void wakeup_rh(struct uhci_hcd *uhci); | 92 | static void wakeup_rh(struct uhci_hcd *uhci); |
93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | 93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); |
94 | 94 | ||
95 | /* | ||
96 | * Calculate the link pointer DMA value for the first Skeleton QH in a frame. | ||
97 | */ | ||
98 | static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | ||
99 | { | ||
100 | int skelnum; | ||
101 | |||
102 | /* | ||
103 | * The interrupt queues will be interleaved as evenly as possible. | ||
104 | * There's not much to be done about period-1 interrupts; they have | ||
105 | * to occur in every frame. But we can schedule period-2 interrupts | ||
106 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
107 | * to 2 (mod 4), and so on. This way each frame only has two | ||
108 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
109 | * | ||
110 | * ffs (Find First bit Set) does exactly what we need: | ||
111 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
112 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
113 | * ffs >= 7 => not on any high-period queue, so use | ||
114 | * skel_int1_qh = skelqh[9]. | ||
115 | * Add in UHCI_NUMFRAMES to insure at least one bit is set. | ||
116 | */ | ||
117 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); | ||
118 | if (skelnum <= 1) | ||
119 | skelnum = 9; | ||
120 | return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); | ||
121 | } | ||
122 | |||
95 | #include "uhci-debug.c" | 123 | #include "uhci-debug.c" |
96 | #include "uhci-q.c" | 124 | #include "uhci-q.c" |
97 | #include "uhci-hub.c" | 125 | #include "uhci-hub.c" |
@@ -631,32 +659,11 @@ static int uhci_start(struct usb_hcd *hcd) | |||
631 | /* | 659 | /* |
632 | * Fill the frame list: make all entries point to the proper | 660 | * Fill the frame list: make all entries point to the proper |
633 | * interrupt queue. | 661 | * interrupt queue. |
634 | * | ||
635 | * The interrupt queues will be interleaved as evenly as possible. | ||
636 | * There's not much to be done about period-1 interrupts; they have | ||
637 | * to occur in every frame. But we can schedule period-2 interrupts | ||
638 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
639 | * to 2 (mod 4), and so on. This way each frame only has two | ||
640 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
641 | */ | 662 | */ |
642 | for (i = 0; i < UHCI_NUMFRAMES; i++) { | 663 | for (i = 0; i < UHCI_NUMFRAMES; i++) { |
643 | int irq; | ||
644 | |||
645 | /* | ||
646 | * ffs (Find First bit Set) does exactly what we need: | ||
647 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
648 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
649 | * ffs >= 7 => not on any high-period queue, so use | ||
650 | * skel_int1_qh = skelqh[9]. | ||
651 | * Add UHCI_NUMFRAMES to insure at least one bit is set. | ||
652 | */ | ||
653 | irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); | ||
654 | if (irq <= 1) | ||
655 | irq = 9; | ||
656 | 664 | ||
657 | /* Only place we don't use the frame list routines */ | 665 | /* Only place we don't use the frame list routines */ |
658 | uhci->frame[i] = UHCI_PTR_QH | | 666 | uhci->frame[i] = uhci_frame_skel_link(uhci, i); |
659 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | ||
660 | } | 667 | } |
661 | 668 | ||
662 | /* | 669 | /* |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 108e3de2dc26..74469b5bcb61 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -83,6 +83,7 @@ | |||
83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames |
85 | * can be scheduled */ | 85 | * can be scheduled */ |
86 | #define MAX_PHASE 32 /* Periodic scheduling length */ | ||
86 | 87 | ||
87 | /* When no queues need Full-Speed Bandwidth Reclamation, | 88 | /* When no queues need Full-Speed Bandwidth Reclamation, |
88 | * delay this long before turning FSBR off */ | 89 | * delay this long before turning FSBR off */ |
@@ -141,6 +142,8 @@ struct uhci_qh { | |||
141 | unsigned long advance_jiffies; /* Time of last queue advance */ | 142 | unsigned long advance_jiffies; /* Time of last queue advance */ |
142 | unsigned int unlink_frame; /* When the QH was unlinked */ | 143 | unsigned int unlink_frame; /* When the QH was unlinked */ |
143 | unsigned int period; /* For Interrupt and Isochronous QHs */ | 144 | unsigned int period; /* For Interrupt and Isochronous QHs */ |
145 | short phase; /* Between 0 and period-1 */ | ||
146 | short load; /* Periodic time requirement, in us */ | ||
144 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ | 147 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ |
145 | int iso_status; /* Status for Isochronous URBs */ | 148 | int iso_status; /* Status for Isochronous URBs */ |
146 | 149 | ||
@@ -153,6 +156,8 @@ struct uhci_qh { | |||
153 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ | 156 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ |
154 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ | 157 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ |
155 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ | 158 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ |
159 | unsigned int bandwidth_reserved:1; /* Periodic bandwidth has | ||
160 | * been allocated */ | ||
156 | } __attribute__((aligned(16))); | 161 | } __attribute__((aligned(16))); |
157 | 162 | ||
158 | /* | 163 | /* |
@@ -414,6 +419,9 @@ struct uhci_hcd { | |||
414 | 419 | ||
415 | wait_queue_head_t waitqh; /* endpoint_disable waiters */ | 420 | wait_queue_head_t waitqh; /* endpoint_disable waiters */ |
416 | int num_waiting; /* Number of waiters */ | 421 | int num_waiting; /* Number of waiters */ |
422 | |||
423 | int total_load; /* Sum of array values */ | ||
424 | short load[MAX_PHASE]; /* Periodic allocations */ | ||
417 | }; | 425 | }; |
418 | 426 | ||
419 | /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ | 427 | /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 30b88459ac7d..2cbb239e63f8 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -248,16 +248,26 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, | |||
248 | INIT_LIST_HEAD(&qh->node); | 248 | INIT_LIST_HEAD(&qh->node); |
249 | 249 | ||
250 | if (udev) { /* Normal QH */ | 250 | if (udev) { /* Normal QH */ |
251 | qh->dummy_td = uhci_alloc_td(uhci); | 251 | qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
252 | if (!qh->dummy_td) { | 252 | if (qh->type != USB_ENDPOINT_XFER_ISOC) { |
253 | dma_pool_free(uhci->qh_pool, qh, dma_handle); | 253 | qh->dummy_td = uhci_alloc_td(uhci); |
254 | return NULL; | 254 | if (!qh->dummy_td) { |
255 | dma_pool_free(uhci->qh_pool, qh, dma_handle); | ||
256 | return NULL; | ||
257 | } | ||
255 | } | 258 | } |
256 | qh->state = QH_STATE_IDLE; | 259 | qh->state = QH_STATE_IDLE; |
257 | qh->hep = hep; | 260 | qh->hep = hep; |
258 | qh->udev = udev; | 261 | qh->udev = udev; |
259 | hep->hcpriv = qh; | 262 | hep->hcpriv = qh; |
260 | qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 263 | |
264 | if (qh->type == USB_ENDPOINT_XFER_INT || | ||
265 | qh->type == USB_ENDPOINT_XFER_ISOC) | ||
266 | qh->load = usb_calc_bus_time(udev->speed, | ||
267 | usb_endpoint_dir_in(&hep->desc), | ||
268 | qh->type == USB_ENDPOINT_XFER_ISOC, | ||
269 | le16_to_cpu(hep->desc.wMaxPacketSize)) | ||
270 | / 1000 + 1; | ||
261 | 271 | ||
262 | } else { /* Skeleton QH */ | 272 | } else { /* Skeleton QH */ |
263 | qh->state = QH_STATE_ACTIVE; | 273 | qh->state = QH_STATE_ACTIVE; |
@@ -275,7 +285,8 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
275 | list_del(&qh->node); | 285 | list_del(&qh->node); |
276 | if (qh->udev) { | 286 | if (qh->udev) { |
277 | qh->hep->hcpriv = NULL; | 287 | qh->hep->hcpriv = NULL; |
278 | uhci_free_td(uhci, qh->dummy_td); | 288 | if (qh->dummy_td) |
289 | uhci_free_td(uhci, qh->dummy_td); | ||
279 | } | 290 | } |
280 | dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); | 291 | dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); |
281 | } | 292 | } |
@@ -327,7 +338,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
327 | goto done; | 338 | goto done; |
328 | qh->element = UHCI_PTR_TERM; | 339 | qh->element = UHCI_PTR_TERM; |
329 | 340 | ||
330 | /* Control pipes have to worry about toggles */ | 341 | /* Control pipes don't have to worry about toggles */ |
331 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) | 342 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) |
332 | goto done; | 343 | goto done; |
333 | 344 | ||
@@ -493,6 +504,121 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
493 | wake_up_all(&uhci->waitqh); | 504 | wake_up_all(&uhci->waitqh); |
494 | } | 505 | } |
495 | 506 | ||
507 | /* | ||
508 | * Find the highest existing bandwidth load for a given phase and period. | ||
509 | */ | ||
510 | static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period) | ||
511 | { | ||
512 | int highest_load = uhci->load[phase]; | ||
513 | |||
514 | for (phase += period; phase < MAX_PHASE; phase += period) | ||
515 | highest_load = max_t(int, highest_load, uhci->load[phase]); | ||
516 | return highest_load; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * Set qh->phase to the optimal phase for a periodic transfer and | ||
521 | * check whether the bandwidth requirement is acceptable. | ||
522 | */ | ||
523 | static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
524 | { | ||
525 | int minimax_load; | ||
526 | |||
527 | /* Find the optimal phase (unless it is already set) and get | ||
528 | * its load value. */ | ||
529 | if (qh->phase >= 0) | ||
530 | minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); | ||
531 | else { | ||
532 | int phase, load; | ||
533 | int max_phase = min_t(int, MAX_PHASE, qh->period); | ||
534 | |||
535 | qh->phase = 0; | ||
536 | minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); | ||
537 | for (phase = 1; phase < max_phase; ++phase) { | ||
538 | load = uhci_highest_load(uhci, phase, qh->period); | ||
539 | if (load < minimax_load) { | ||
540 | minimax_load = load; | ||
541 | qh->phase = phase; | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | |||
546 | /* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */ | ||
547 | if (minimax_load + qh->load > 900) { | ||
548 | dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: " | ||
549 | "period %d, phase %d, %d + %d us\n", | ||
550 | qh->period, qh->phase, minimax_load, qh->load); | ||
551 | return -ENOSPC; | ||
552 | } | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * Reserve a periodic QH's bandwidth in the schedule | ||
558 | */ | ||
559 | static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
560 | { | ||
561 | int i; | ||
562 | int load = qh->load; | ||
563 | char *p = "??"; | ||
564 | |||
565 | for (i = qh->phase; i < MAX_PHASE; i += qh->period) { | ||
566 | uhci->load[i] += load; | ||
567 | uhci->total_load += load; | ||
568 | } | ||
569 | uhci_to_hcd(uhci)->self.bandwidth_allocated = | ||
570 | uhci->total_load / MAX_PHASE; | ||
571 | switch (qh->type) { | ||
572 | case USB_ENDPOINT_XFER_INT: | ||
573 | ++uhci_to_hcd(uhci)->self.bandwidth_int_reqs; | ||
574 | p = "INT"; | ||
575 | break; | ||
576 | case USB_ENDPOINT_XFER_ISOC: | ||
577 | ++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; | ||
578 | p = "ISO"; | ||
579 | break; | ||
580 | } | ||
581 | qh->bandwidth_reserved = 1; | ||
582 | dev_dbg(uhci_dev(uhci), | ||
583 | "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", | ||
584 | "reserve", qh->udev->devnum, | ||
585 | qh->hep->desc.bEndpointAddress, p, | ||
586 | qh->period, qh->phase, load); | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Release a periodic QH's bandwidth reservation | ||
591 | */ | ||
592 | static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
593 | { | ||
594 | int i; | ||
595 | int load = qh->load; | ||
596 | char *p = "??"; | ||
597 | |||
598 | for (i = qh->phase; i < MAX_PHASE; i += qh->period) { | ||
599 | uhci->load[i] -= load; | ||
600 | uhci->total_load -= load; | ||
601 | } | ||
602 | uhci_to_hcd(uhci)->self.bandwidth_allocated = | ||
603 | uhci->total_load / MAX_PHASE; | ||
604 | switch (qh->type) { | ||
605 | case USB_ENDPOINT_XFER_INT: | ||
606 | --uhci_to_hcd(uhci)->self.bandwidth_int_reqs; | ||
607 | p = "INT"; | ||
608 | break; | ||
609 | case USB_ENDPOINT_XFER_ISOC: | ||
610 | --uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; | ||
611 | p = "ISO"; | ||
612 | break; | ||
613 | } | ||
614 | qh->bandwidth_reserved = 0; | ||
615 | dev_dbg(uhci_dev(uhci), | ||
616 | "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", | ||
617 | "release", qh->udev->devnum, | ||
618 | qh->hep->desc.bEndpointAddress, p, | ||
619 | qh->period, qh->phase, load); | ||
620 | } | ||
621 | |||
496 | static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, | 622 | static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, |
497 | struct urb *urb) | 623 | struct urb *urb) |
498 | { | 624 | { |
@@ -796,7 +922,6 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
796 | wmb(); | 922 | wmb(); |
797 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 923 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); |
798 | qh->dummy_td = td; | 924 | qh->dummy_td = td; |
799 | qh->period = urb->interval; | ||
800 | 925 | ||
801 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 926 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
802 | usb_pipeout(urb->pipe), toggle); | 927 | usb_pipeout(urb->pipe), toggle); |
@@ -827,28 +952,42 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, | |||
827 | static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, | 952 | static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, |
828 | struct uhci_qh *qh) | 953 | struct uhci_qh *qh) |
829 | { | 954 | { |
830 | int exponent; | 955 | int ret; |
831 | 956 | ||
832 | /* USB 1.1 interrupt transfers only involve one packet per interval. | 957 | /* USB 1.1 interrupt transfers only involve one packet per interval. |
833 | * Drivers can submit URBs of any length, but longer ones will need | 958 | * Drivers can submit URBs of any length, but longer ones will need |
834 | * multiple intervals to complete. | 959 | * multiple intervals to complete. |
835 | */ | 960 | */ |
836 | 961 | ||
837 | /* Figure out which power-of-two queue to use */ | 962 | if (!qh->bandwidth_reserved) { |
838 | for (exponent = 7; exponent >= 0; --exponent) { | 963 | int exponent; |
839 | if ((1 << exponent) <= urb->interval) | ||
840 | break; | ||
841 | } | ||
842 | if (exponent < 0) | ||
843 | return -EINVAL; | ||
844 | urb->interval = 1 << exponent; | ||
845 | 964 | ||
846 | if (qh->period == 0) | 965 | /* Figure out which power-of-two queue to use */ |
966 | for (exponent = 7; exponent >= 0; --exponent) { | ||
967 | if ((1 << exponent) <= urb->interval) | ||
968 | break; | ||
969 | } | ||
970 | if (exponent < 0) | ||
971 | return -EINVAL; | ||
972 | qh->period = 1 << exponent; | ||
847 | qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; | 973 | qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; |
848 | else if (qh->period != urb->interval) | ||
849 | return -EINVAL; /* Can't change the period */ | ||
850 | 974 | ||
851 | return uhci_submit_common(uhci, urb, qh); | 975 | /* For now, interrupt phase is fixed by the layout |
976 | * of the QH lists. */ | ||
977 | qh->phase = (qh->period / 2) & (MAX_PHASE - 1); | ||
978 | ret = uhci_check_bandwidth(uhci, qh); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | } else if (qh->period > urb->interval) | ||
982 | return -EINVAL; /* Can't decrease the period */ | ||
983 | |||
984 | ret = uhci_submit_common(uhci, urb, qh); | ||
985 | if (ret == 0) { | ||
986 | urb->interval = qh->period; | ||
987 | if (!qh->bandwidth_reserved) | ||
988 | uhci_reserve_bandwidth(uhci, qh); | ||
989 | } | ||
990 | return ret; | ||
852 | } | 991 | } |
853 | 992 | ||
854 | /* | 993 | /* |
@@ -995,15 +1134,32 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
995 | return -EFBIG; | 1134 | return -EFBIG; |
996 | 1135 | ||
997 | /* Check the period and figure out the starting frame number */ | 1136 | /* Check the period and figure out the starting frame number */ |
998 | if (qh->period == 0) { | 1137 | if (!qh->bandwidth_reserved) { |
1138 | qh->period = urb->interval; | ||
999 | if (urb->transfer_flags & URB_ISO_ASAP) { | 1139 | if (urb->transfer_flags & URB_ISO_ASAP) { |
1140 | qh->phase = -1; /* Find the best phase */ | ||
1141 | i = uhci_check_bandwidth(uhci, qh); | ||
1142 | if (i) | ||
1143 | return i; | ||
1144 | |||
1145 | /* Allow a little time to allocate the TDs */ | ||
1000 | uhci_get_current_frame_number(uhci); | 1146 | uhci_get_current_frame_number(uhci); |
1001 | urb->start_frame = uhci->frame_number + 10; | 1147 | frame = uhci->frame_number + 10; |
1148 | |||
1149 | /* Move forward to the first frame having the | ||
1150 | * correct phase */ | ||
1151 | urb->start_frame = frame + ((qh->phase - frame) & | ||
1152 | (qh->period - 1)); | ||
1002 | } else { | 1153 | } else { |
1003 | i = urb->start_frame - uhci->last_iso_frame; | 1154 | i = urb->start_frame - uhci->last_iso_frame; |
1004 | if (i <= 0 || i >= UHCI_NUMFRAMES) | 1155 | if (i <= 0 || i >= UHCI_NUMFRAMES) |
1005 | return -EINVAL; | 1156 | return -EINVAL; |
1157 | qh->phase = urb->start_frame & (qh->period - 1); | ||
1158 | i = uhci_check_bandwidth(uhci, qh); | ||
1159 | if (i) | ||
1160 | return i; | ||
1006 | } | 1161 | } |
1162 | |||
1007 | } else if (qh->period != urb->interval) { | 1163 | } else if (qh->period != urb->interval) { |
1008 | return -EINVAL; /* Can't change the period */ | 1164 | return -EINVAL; /* Can't change the period */ |
1009 | 1165 | ||
@@ -1049,9 +1205,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1049 | /* Set the interrupt-on-completion flag on the last packet. */ | 1205 | /* Set the interrupt-on-completion flag on the last packet. */ |
1050 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1206 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); |
1051 | 1207 | ||
1052 | qh->skel = uhci->skel_iso_qh; | ||
1053 | qh->period = urb->interval; | ||
1054 | |||
1055 | /* Add the TDs to the frame list */ | 1208 | /* Add the TDs to the frame list */ |
1056 | frame = urb->start_frame; | 1209 | frame = urb->start_frame; |
1057 | list_for_each_entry(td, &urbp->td_list, list) { | 1210 | list_for_each_entry(td, &urbp->td_list, list) { |
@@ -1065,6 +1218,9 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1065 | qh->iso_status = 0; | 1218 | qh->iso_status = 0; |
1066 | } | 1219 | } |
1067 | 1220 | ||
1221 | qh->skel = uhci->skel_iso_qh; | ||
1222 | if (!qh->bandwidth_reserved) | ||
1223 | uhci_reserve_bandwidth(uhci, qh); | ||
1068 | return 0; | 1224 | return 0; |
1069 | } | 1225 | } |
1070 | 1226 | ||
@@ -1119,7 +1275,6 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1119 | unsigned long flags; | 1275 | unsigned long flags; |
1120 | struct urb_priv *urbp; | 1276 | struct urb_priv *urbp; |
1121 | struct uhci_qh *qh; | 1277 | struct uhci_qh *qh; |
1122 | int bustime; | ||
1123 | 1278 | ||
1124 | spin_lock_irqsave(&uhci->lock, flags); | 1279 | spin_lock_irqsave(&uhci->lock, flags); |
1125 | 1280 | ||
@@ -1149,35 +1304,11 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1149 | ret = uhci_submit_bulk(uhci, urb, qh); | 1304 | ret = uhci_submit_bulk(uhci, urb, qh); |
1150 | break; | 1305 | break; |
1151 | case USB_ENDPOINT_XFER_INT: | 1306 | case USB_ENDPOINT_XFER_INT: |
1152 | if (list_empty(&qh->queue)) { | 1307 | ret = uhci_submit_interrupt(uhci, urb, qh); |
1153 | bustime = usb_check_bandwidth(urb->dev, urb); | ||
1154 | if (bustime < 0) | ||
1155 | ret = bustime; | ||
1156 | else { | ||
1157 | ret = uhci_submit_interrupt(uhci, urb, qh); | ||
1158 | if (ret == 0) | ||
1159 | usb_claim_bandwidth(urb->dev, urb, bustime, 0); | ||
1160 | } | ||
1161 | } else { /* inherit from parent */ | ||
1162 | struct urb_priv *eurbp; | ||
1163 | |||
1164 | eurbp = list_entry(qh->queue.prev, struct urb_priv, | ||
1165 | node); | ||
1166 | urb->bandwidth = eurbp->urb->bandwidth; | ||
1167 | ret = uhci_submit_interrupt(uhci, urb, qh); | ||
1168 | } | ||
1169 | break; | 1308 | break; |
1170 | case USB_ENDPOINT_XFER_ISOC: | 1309 | case USB_ENDPOINT_XFER_ISOC: |
1171 | urb->error_count = 0; | 1310 | urb->error_count = 0; |
1172 | bustime = usb_check_bandwidth(urb->dev, urb); | ||
1173 | if (bustime < 0) { | ||
1174 | ret = bustime; | ||
1175 | break; | ||
1176 | } | ||
1177 | |||
1178 | ret = uhci_submit_isochronous(uhci, urb, qh); | 1311 | ret = uhci_submit_isochronous(uhci, urb, qh); |
1179 | if (ret == 0) | ||
1180 | usb_claim_bandwidth(urb->dev, urb, bustime, 1); | ||
1181 | break; | 1312 | break; |
1182 | } | 1313 | } |
1183 | if (ret != 0) | 1314 | if (ret != 0) |
@@ -1274,24 +1405,6 @@ __acquires(uhci->lock) | |||
1274 | 1405 | ||
1275 | uhci_free_urb_priv(uhci, urbp); | 1406 | uhci_free_urb_priv(uhci, urbp); |
1276 | 1407 | ||
1277 | switch (qh->type) { | ||
1278 | case USB_ENDPOINT_XFER_ISOC: | ||
1279 | /* Release bandwidth for Interrupt or Isoc. transfers */ | ||
1280 | if (urb->bandwidth) | ||
1281 | usb_release_bandwidth(urb->dev, urb, 1); | ||
1282 | break; | ||
1283 | case USB_ENDPOINT_XFER_INT: | ||
1284 | /* Release bandwidth for Interrupt or Isoc. transfers */ | ||
1285 | /* Make sure we don't release if we have a queued URB */ | ||
1286 | if (list_empty(&qh->queue) && urb->bandwidth) | ||
1287 | usb_release_bandwidth(urb->dev, urb, 0); | ||
1288 | else | ||
1289 | /* bandwidth was passed on to queued URB, */ | ||
1290 | /* so don't let usb_unlink_urb() release it */ | ||
1291 | urb->bandwidth = 0; | ||
1292 | break; | ||
1293 | } | ||
1294 | |||
1295 | spin_unlock(&uhci->lock); | 1408 | spin_unlock(&uhci->lock); |
1296 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); | 1409 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); |
1297 | spin_lock(&uhci->lock); | 1410 | spin_lock(&uhci->lock); |
@@ -1300,9 +1413,8 @@ __acquires(uhci->lock) | |||
1300 | * reserved bandwidth. */ | 1413 | * reserved bandwidth. */ |
1301 | if (list_empty(&qh->queue)) { | 1414 | if (list_empty(&qh->queue)) { |
1302 | uhci_unlink_qh(uhci, qh); | 1415 | uhci_unlink_qh(uhci, qh); |
1303 | 1416 | if (qh->bandwidth_reserved) | |
1304 | /* Bandwidth stuff not yet implemented */ | 1417 | uhci_release_bandwidth(uhci, qh); |
1305 | qh->period = 0; | ||
1306 | } | 1418 | } |
1307 | } | 1419 | } |
1308 | 1420 | ||
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 63a84bbc310d..d308afd06935 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -565,11 +565,15 @@ static void mdc800_usb_disconnect (struct usb_interface *intf) | |||
565 | 565 | ||
566 | usb_deregister_dev(intf, &mdc800_class); | 566 | usb_deregister_dev(intf, &mdc800_class); |
567 | 567 | ||
568 | /* must be under lock to make sure no URB | ||
569 | is submitted after usb_kill_urb() */ | ||
570 | mutex_lock(&mdc800->io_lock); | ||
568 | mdc800->state=NOT_CONNECTED; | 571 | mdc800->state=NOT_CONNECTED; |
569 | 572 | ||
570 | usb_kill_urb(mdc800->irq_urb); | 573 | usb_kill_urb(mdc800->irq_urb); |
571 | usb_kill_urb(mdc800->write_urb); | 574 | usb_kill_urb(mdc800->write_urb); |
572 | usb_kill_urb(mdc800->download_urb); | 575 | usb_kill_urb(mdc800->download_urb); |
576 | mutex_unlock(&mdc800->io_lock); | ||
573 | 577 | ||
574 | mdc800->dev = NULL; | 578 | mdc800->dev = NULL; |
575 | usb_set_intfdata(intf, NULL); | 579 | usb_set_intfdata(intf, NULL); |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index aa6a620c162f..2e71d3cca198 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -352,3 +352,15 @@ config USB_APPLETOUCH | |||
352 | 352 | ||
353 | To compile this driver as a module, choose M here: the | 353 | To compile this driver as a module, choose M here: the |
354 | module will be called appletouch. | 354 | module will be called appletouch. |
355 | |||
356 | config USB_GTCO | ||
357 | tristate "GTCO CalComp/InterWrite USB Support" | ||
358 | depends on USB && INPUT | ||
359 | ---help--- | ||
360 | Say Y here if you want to use the USB version of the GTCO | ||
361 | CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" | ||
362 | (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" | ||
363 | (CONFIG_INPUT_EVDEV) as well. | ||
364 | |||
365 | To compile this driver as a module, choose M here: the | ||
366 | module will be called gtco. | ||
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index a06024e5cd56..a9d206c945e9 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o | |||
48 | obj-$(CONFIG_USB_YEALINK) += yealink.o | 48 | obj-$(CONFIG_USB_YEALINK) += yealink.o |
49 | obj-$(CONFIG_USB_XPAD) += xpad.o | 49 | obj-$(CONFIG_USB_XPAD) += xpad.o |
50 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o | 50 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o |
51 | obj-$(CONFIG_USB_GTCO) += gtco.o | ||
51 | 52 | ||
52 | ifeq ($(CONFIG_USB_DEBUG),y) | 53 | ifeq ($(CONFIG_USB_DEBUG),y) |
53 | EXTRA_CFLAGS += -DDEBUG | 54 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/usb/input/gtco.c b/drivers/usb/input/gtco.c new file mode 100644 index 000000000000..203cdc1bbba4 --- /dev/null +++ b/drivers/usb/input/gtco.c | |||
@@ -0,0 +1,1104 @@ | |||
1 | /* -*- linux-c -*- | ||
2 | |||
3 | GTCO digitizer USB driver | ||
4 | |||
5 | Use the err(), dbg() and info() macros from usb.h for system logging | ||
6 | |||
7 | TO CHECK: Is pressure done right on report 5? | ||
8 | |||
9 | Copyright (C) 2006 GTCO CalComp | ||
10 | |||
11 | This program is free software; you can redistribute it and/or | ||
12 | modify it under the terms of the GNU General Public License | ||
13 | as published by the Free Software Foundation; version 2 | ||
14 | of the License. | ||
15 | |||
16 | This program is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | GNU General Public License for more details. | ||
20 | |||
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
24 | |||
25 | Permission to use, copy, modify, distribute, and sell this software and its | ||
26 | documentation for any purpose is hereby granted without fee, provided that | ||
27 | the above copyright notice appear in all copies and that both that | ||
28 | copyright notice and this permission notice appear in supporting | ||
29 | documentation, and that the name of GTCO-CalComp not be used in advertising | ||
30 | or publicity pertaining to distribution of the software without specific, | ||
31 | written prior permission. GTCO-CalComp makes no representations about the | ||
32 | suitability of this software for any purpose. It is provided "as is" | ||
33 | without express or implied warranty. | ||
34 | |||
35 | GTCO-CALCOMP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
36 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
37 | EVENT SHALL GTCO-CALCOMP BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
38 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
39 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
40 | TORTIOUS ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
41 | PERFORMANCE OF THIS SOFTWARE. | ||
42 | |||
43 | GTCO CalComp, Inc. | ||
44 | 7125 Riverwood Drive | ||
45 | Columbia, MD 21046 | ||
46 | |||
47 | Jeremy Roberson jroberson@gtcocalcomp.com | ||
48 | Scott Hill shill@gtcocalcomp.com | ||
49 | */ | ||
50 | |||
51 | |||
52 | |||
53 | /*#define DEBUG*/ | ||
54 | |||
55 | #include <linux/kernel.h> | ||
56 | #include <linux/module.h> | ||
57 | #include <linux/errno.h> | ||
58 | #include <linux/init.h> | ||
59 | #include <linux/slab.h> | ||
60 | #include <linux/input.h> | ||
61 | #include <linux/usb.h> | ||
62 | #include <asm/uaccess.h> | ||
63 | #include <asm/unaligned.h> | ||
64 | #include <asm/byteorder.h> | ||
65 | |||
66 | |||
67 | #include <linux/version.h> | ||
68 | #include <linux/usb/input.h> | ||
69 | |||
70 | /* Version with a Major number of 2 is for kernel inclusion only. */ | ||
71 | #define GTCO_VERSION "2.00.0006" | ||
72 | |||
73 | |||
74 | /* MACROS */ | ||
75 | |||
76 | #define VENDOR_ID_GTCO 0x078C | ||
77 | #define PID_400 0x400 | ||
78 | #define PID_401 0x401 | ||
79 | #define PID_1000 0x1000 | ||
80 | #define PID_1001 0x1001 | ||
81 | #define PID_1002 0x1002 | ||
82 | |||
83 | /* Max size of a single report */ | ||
84 | #define REPORT_MAX_SIZE 10 | ||
85 | |||
86 | |||
87 | /* Bitmask whether pen is in range */ | ||
88 | #define MASK_INRANGE 0x20 | ||
89 | #define MASK_BUTTON 0x01F | ||
90 | |||
91 | #define PATHLENGTH 64 | ||
92 | |||
93 | /* DATA STRUCTURES */ | ||
94 | |||
95 | /* Device table */ | ||
96 | static struct usb_device_id gtco_usbid_table [] = { | ||
97 | { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, | ||
98 | { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, | ||
99 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, | ||
100 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1001) }, | ||
101 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1002) }, | ||
102 | { } | ||
103 | }; | ||
104 | MODULE_DEVICE_TABLE (usb, gtco_usbid_table); | ||
105 | |||
106 | |||
107 | /* Structure to hold all of our device specific stuff */ | ||
108 | struct gtco { | ||
109 | |||
110 | struct input_dev *inputdevice; /* input device struct pointer */ | ||
111 | struct usb_device *usbdev; /* the usb device for this device */ | ||
112 | struct urb *urbinfo; /* urb for incoming reports */ | ||
113 | dma_addr_t buf_dma; /* dma addr of the data buffer*/ | ||
114 | unsigned char * buffer; /* databuffer for reports */ | ||
115 | |||
116 | char usbpath[PATHLENGTH]; | ||
117 | int openCount; | ||
118 | |||
119 | /* Information pulled from Report Descriptor */ | ||
120 | u32 usage; | ||
121 | u32 min_X; | ||
122 | u32 max_X; | ||
123 | u32 min_Y; | ||
124 | u32 max_Y; | ||
125 | s8 mintilt_X; | ||
126 | s8 maxtilt_X; | ||
127 | s8 mintilt_Y; | ||
128 | s8 maxtilt_Y; | ||
129 | u32 maxpressure; | ||
130 | u32 minpressure; | ||
131 | }; | ||
132 | |||
133 | |||
134 | |||
135 | /* Code for parsing the HID REPORT DESCRIPTOR */ | ||
136 | |||
137 | /* From HID1.11 spec */ | ||
138 | struct hid_descriptor | ||
139 | { | ||
140 | struct usb_descriptor_header header; | ||
141 | __le16 bcdHID; | ||
142 | u8 bCountryCode; | ||
143 | u8 bNumDescriptors; | ||
144 | u8 bDescriptorType; | ||
145 | __le16 wDescriptorLength; | ||
146 | } __attribute__ ((packed)); | ||
147 | |||
148 | |||
149 | #define HID_DESCRIPTOR_SIZE 9 | ||
150 | #define HID_DEVICE_TYPE 33 | ||
151 | #define REPORT_DEVICE_TYPE 34 | ||
152 | |||
153 | |||
154 | #define PREF_TAG(x) ((x)>>4) | ||
155 | #define PREF_TYPE(x) ((x>>2)&0x03) | ||
156 | #define PREF_SIZE(x) ((x)&0x03) | ||
157 | |||
158 | #define TYPE_MAIN 0 | ||
159 | #define TYPE_GLOBAL 1 | ||
160 | #define TYPE_LOCAL 2 | ||
161 | #define TYPE_RESERVED 3 | ||
162 | |||
163 | #define TAG_MAIN_INPUT 0x8 | ||
164 | #define TAG_MAIN_OUTPUT 0x9 | ||
165 | #define TAG_MAIN_FEATURE 0xB | ||
166 | #define TAG_MAIN_COL_START 0xA | ||
167 | #define TAG_MAIN_COL_END 0xC | ||
168 | |||
169 | #define TAG_GLOB_USAGE 0 | ||
170 | #define TAG_GLOB_LOG_MIN 1 | ||
171 | #define TAG_GLOB_LOG_MAX 2 | ||
172 | #define TAG_GLOB_PHYS_MIN 3 | ||
173 | #define TAG_GLOB_PHYS_MAX 4 | ||
174 | #define TAG_GLOB_UNIT_EXP 5 | ||
175 | #define TAG_GLOB_UNIT 6 | ||
176 | #define TAG_GLOB_REPORT_SZ 7 | ||
177 | #define TAG_GLOB_REPORT_ID 8 | ||
178 | #define TAG_GLOB_REPORT_CNT 9 | ||
179 | #define TAG_GLOB_PUSH 10 | ||
180 | #define TAG_GLOB_POP 11 | ||
181 | |||
182 | #define TAG_GLOB_MAX 12 | ||
183 | |||
184 | #define DIGITIZER_USAGE_TIP_PRESSURE 0x30 | ||
185 | #define DIGITIZER_USAGE_TILT_X 0x3D | ||
186 | #define DIGITIZER_USAGE_TILT_Y 0x3E | ||
187 | |||
188 | |||
189 | /* | ||
190 | * | ||
191 | * This is an abbreviated parser for the HID Report Descriptor. We | ||
192 | * know what devices we are talking to, so this is by no means meant | ||
193 | * to be generic. We can make some safe assumptions: | ||
194 | * | ||
195 | * - We know there are no LONG tags, all short | ||
196 | * - We know that we have no MAIN Feature and MAIN Output items | ||
197 | * - We know what the IRQ reports are supposed to look like. | ||
198 | * | ||
199 | * The main purpose of this is to use the HID report desc to figure | ||
200 | * out the mins and maxs of the fields in the IRQ reports. The IRQ | ||
201 | * reports for 400/401 change slightly if the max X is bigger than 64K. | ||
202 | * | ||
203 | */ | ||
204 | static void parse_hid_report_descriptor(struct gtco *device, char * report, | ||
205 | int length) | ||
206 | { | ||
207 | int x,i=0; | ||
208 | |||
209 | /* Tag primitive vars */ | ||
210 | __u8 prefix; | ||
211 | __u8 size; | ||
212 | __u8 tag; | ||
213 | __u8 type; | ||
214 | __u8 data = 0; | ||
215 | __u16 data16 = 0; | ||
216 | __u32 data32 = 0; | ||
217 | |||
218 | |||
219 | /* For parsing logic */ | ||
220 | int inputnum = 0; | ||
221 | __u32 usage = 0; | ||
222 | |||
223 | /* Global Values, indexed by TAG */ | ||
224 | __u32 globalval[TAG_GLOB_MAX]; | ||
225 | __u32 oldval[TAG_GLOB_MAX]; | ||
226 | |||
227 | /* Debug stuff */ | ||
228 | char maintype='x'; | ||
229 | char globtype[12]; | ||
230 | int indent=0; | ||
231 | char indentstr[10]=""; | ||
232 | |||
233 | |||
234 | |||
235 | dbg("======>>>>>>PARSE<<<<<<======"); | ||
236 | |||
237 | /* Walk this report and pull out the info we need */ | ||
238 | while (i<length){ | ||
239 | prefix=report[i]; | ||
240 | |||
241 | /* Skip over prefix */ | ||
242 | i++; | ||
243 | |||
244 | /* Determine data size and save the data in the proper variable */ | ||
245 | size = PREF_SIZE(prefix); | ||
246 | switch(size){ | ||
247 | case 1: | ||
248 | data = report[i]; | ||
249 | break; | ||
250 | case 2: | ||
251 | data16 = le16_to_cpu(get_unaligned((__le16*)(&(report[i])))); | ||
252 | break; | ||
253 | case 3: | ||
254 | size = 4; | ||
255 | data32 = le32_to_cpu(get_unaligned((__le32*)(&(report[i])))); | ||
256 | } | ||
257 | |||
258 | /* Skip size of data */ | ||
259 | i+=size; | ||
260 | |||
261 | /* What we do depends on the tag type */ | ||
262 | tag = PREF_TAG(prefix); | ||
263 | type = PREF_TYPE(prefix); | ||
264 | switch(type){ | ||
265 | case TYPE_MAIN: | ||
266 | strcpy(globtype,""); | ||
267 | switch(tag){ | ||
268 | |||
269 | case TAG_MAIN_INPUT: | ||
270 | /* | ||
271 | * The INPUT MAIN tag signifies this is | ||
272 | * information from a report. We need to | ||
273 | * figure out what it is and store the | ||
274 | * min/max values | ||
275 | */ | ||
276 | |||
277 | maintype='I'; | ||
278 | if (data==2){ | ||
279 | strcpy(globtype,"Variable"); | ||
280 | } | ||
281 | if (data==3){ | ||
282 | strcpy(globtype,"Var|Const"); | ||
283 | } | ||
284 | |||
285 | dbg("::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits", | ||
286 | globalval[TAG_GLOB_REPORT_ID],inputnum, | ||
287 | globalval[TAG_GLOB_LOG_MAX],globalval[TAG_GLOB_LOG_MAX], | ||
288 | globalval[TAG_GLOB_LOG_MIN],globalval[TAG_GLOB_LOG_MIN], | ||
289 | (globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT])); | ||
290 | |||
291 | |||
292 | /* | ||
293 | We can assume that the first two input items | ||
294 | are always the X and Y coordinates. After | ||
295 | that, we look for everything else by | ||
296 | local usage value | ||
297 | */ | ||
298 | switch (inputnum){ | ||
299 | case 0: /* X coord */ | ||
300 | dbg("GER: X Usage: 0x%x",usage); | ||
301 | if (device->max_X == 0){ | ||
302 | device->max_X = globalval[TAG_GLOB_LOG_MAX]; | ||
303 | device->min_X = globalval[TAG_GLOB_LOG_MIN]; | ||
304 | } | ||
305 | |||
306 | break; | ||
307 | case 1: /* Y coord */ | ||
308 | dbg("GER: Y Usage: 0x%x",usage); | ||
309 | if (device->max_Y == 0){ | ||
310 | device->max_Y = globalval[TAG_GLOB_LOG_MAX]; | ||
311 | device->min_Y = globalval[TAG_GLOB_LOG_MIN]; | ||
312 | } | ||
313 | break; | ||
314 | default: | ||
315 | /* Tilt X */ | ||
316 | if (usage == DIGITIZER_USAGE_TILT_X){ | ||
317 | if (device->maxtilt_X == 0){ | ||
318 | device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX]; | ||
319 | device->mintilt_X = globalval[TAG_GLOB_LOG_MIN]; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | /* Tilt Y */ | ||
324 | if (usage == DIGITIZER_USAGE_TILT_Y){ | ||
325 | if (device->maxtilt_Y == 0){ | ||
326 | device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX]; | ||
327 | device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN]; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | |||
332 | /* Pressure */ | ||
333 | if (usage == DIGITIZER_USAGE_TIP_PRESSURE){ | ||
334 | if (device->maxpressure == 0){ | ||
335 | device->maxpressure = globalval[TAG_GLOB_LOG_MAX]; | ||
336 | device->minpressure = globalval[TAG_GLOB_LOG_MIN]; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | break; | ||
341 | } | ||
342 | |||
343 | inputnum++; | ||
344 | |||
345 | |||
346 | break; | ||
347 | case TAG_MAIN_OUTPUT: | ||
348 | maintype='O'; | ||
349 | break; | ||
350 | case TAG_MAIN_FEATURE: | ||
351 | maintype='F'; | ||
352 | break; | ||
353 | case TAG_MAIN_COL_START: | ||
354 | maintype='S'; | ||
355 | |||
356 | if (data==0){ | ||
357 | dbg("======>>>>>> Physical"); | ||
358 | strcpy(globtype,"Physical"); | ||
359 | }else{ | ||
360 | dbg("======>>>>>>"); | ||
361 | } | ||
362 | |||
363 | /* Indent the debug output */ | ||
364 | indent++; | ||
365 | for (x=0;x<indent;x++){ | ||
366 | indentstr[x]='-'; | ||
367 | } | ||
368 | indentstr[x]=0; | ||
369 | |||
370 | /* Save global tags */ | ||
371 | for (x=0;x<TAG_GLOB_MAX;x++){ | ||
372 | oldval[x] = globalval[x]; | ||
373 | } | ||
374 | |||
375 | break; | ||
376 | case TAG_MAIN_COL_END: | ||
377 | dbg("<<<<<<======"); | ||
378 | maintype='E'; | ||
379 | indent--; | ||
380 | for (x=0;x<indent;x++){ | ||
381 | indentstr[x]='-'; | ||
382 | } | ||
383 | indentstr[x]=0; | ||
384 | |||
385 | /* Copy global tags back */ | ||
386 | for (x=0;x<TAG_GLOB_MAX;x++){ | ||
387 | globalval[x] = oldval[x]; | ||
388 | } | ||
389 | |||
390 | break; | ||
391 | } | ||
392 | |||
393 | switch (size){ | ||
394 | case 1: | ||
395 | dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x", | ||
396 | indentstr,tag,maintype,size,globtype,data); | ||
397 | break; | ||
398 | case 2: | ||
399 | dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x", | ||
400 | indentstr,tag,maintype,size,globtype, data16); | ||
401 | break; | ||
402 | case 4: | ||
403 | dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x", | ||
404 | indentstr,tag,maintype,size,globtype,data32); | ||
405 | break; | ||
406 | } | ||
407 | break; | ||
408 | case TYPE_GLOBAL: | ||
409 | switch(tag){ | ||
410 | case TAG_GLOB_USAGE: | ||
411 | /* | ||
412 | * First time we hit the global usage tag, | ||
413 | * it should tell us the type of device | ||
414 | */ | ||
415 | if (device->usage == 0){ | ||
416 | device->usage = data; | ||
417 | } | ||
418 | strcpy(globtype,"USAGE"); | ||
419 | break; | ||
420 | case TAG_GLOB_LOG_MIN : | ||
421 | strcpy(globtype,"LOG_MIN"); | ||
422 | break; | ||
423 | case TAG_GLOB_LOG_MAX : | ||
424 | strcpy(globtype,"LOG_MAX"); | ||
425 | break; | ||
426 | case TAG_GLOB_PHYS_MIN : | ||
427 | strcpy(globtype,"PHYS_MIN"); | ||
428 | break; | ||
429 | case TAG_GLOB_PHYS_MAX : | ||
430 | strcpy(globtype,"PHYS_MAX"); | ||
431 | break; | ||
432 | case TAG_GLOB_UNIT_EXP : | ||
433 | strcpy(globtype,"EXP"); | ||
434 | break; | ||
435 | case TAG_GLOB_UNIT : | ||
436 | strcpy(globtype,"UNIT"); | ||
437 | break; | ||
438 | case TAG_GLOB_REPORT_SZ : | ||
439 | strcpy(globtype,"REPORT_SZ"); | ||
440 | break; | ||
441 | case TAG_GLOB_REPORT_ID : | ||
442 | strcpy(globtype,"REPORT_ID"); | ||
443 | /* New report, restart numbering */ | ||
444 | inputnum=0; | ||
445 | break; | ||
446 | case TAG_GLOB_REPORT_CNT: | ||
447 | strcpy(globtype,"REPORT_CNT"); | ||
448 | break; | ||
449 | case TAG_GLOB_PUSH : | ||
450 | strcpy(globtype,"PUSH"); | ||
451 | break; | ||
452 | case TAG_GLOB_POP: | ||
453 | strcpy(globtype,"POP"); | ||
454 | break; | ||
455 | } | ||
456 | |||
457 | |||
458 | /* Check to make sure we have a good tag number | ||
459 | so we don't overflow array */ | ||
460 | if (tag < TAG_GLOB_MAX){ | ||
461 | switch (size){ | ||
462 | case 1: | ||
463 | dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data); | ||
464 | globalval[tag]=data; | ||
465 | break; | ||
466 | case 2: | ||
467 | dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data16); | ||
468 | globalval[tag]=data16; | ||
469 | break; | ||
470 | case 4: | ||
471 | dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data32); | ||
472 | globalval[tag]=data32; | ||
473 | break; | ||
474 | } | ||
475 | }else{ | ||
476 | dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ", | ||
477 | indentstr,tag,size); | ||
478 | } | ||
479 | |||
480 | |||
481 | break; | ||
482 | |||
483 | case TYPE_LOCAL: | ||
484 | switch(tag){ | ||
485 | case TAG_GLOB_USAGE: | ||
486 | strcpy(globtype,"USAGE"); | ||
487 | /* Always 1 byte */ | ||
488 | usage = data; | ||
489 | break; | ||
490 | case TAG_GLOB_LOG_MIN : | ||
491 | strcpy(globtype,"MIN"); | ||
492 | break; | ||
493 | case TAG_GLOB_LOG_MAX : | ||
494 | strcpy(globtype,"MAX"); | ||
495 | break; | ||
496 | default: | ||
497 | strcpy(globtype,"UNKNOWN"); | ||
498 | } | ||
499 | |||
500 | switch (size){ | ||
501 | case 1: | ||
502 | dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", | ||
503 | indentstr,tag,globtype,size,data); | ||
504 | break; | ||
505 | case 2: | ||
506 | dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", | ||
507 | indentstr,tag,globtype,size,data16); | ||
508 | break; | ||
509 | case 4: | ||
510 | dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", | ||
511 | indentstr,tag,globtype,size,data32); | ||
512 | break; | ||
513 | } | ||
514 | |||
515 | break; | ||
516 | } | ||
517 | |||
518 | } | ||
519 | |||
520 | } | ||
521 | |||
522 | |||
523 | |||
524 | /* INPUT DRIVER Routines */ | ||
525 | |||
526 | |||
527 | /* | ||
528 | * Called when opening the input device. This will submit the URB to | ||
529 | * the usb system so we start getting reports | ||
530 | */ | ||
531 | static int gtco_input_open(struct input_dev *inputdev) | ||
532 | { | ||
533 | struct gtco *device; | ||
534 | device = inputdev->private; | ||
535 | |||
536 | device->urbinfo->dev = device->usbdev; | ||
537 | if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) { | ||
538 | return -EIO; | ||
539 | } | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | /** | ||
544 | Called when closing the input device. This will unlink the URB | ||
545 | */ | ||
546 | static void gtco_input_close(struct input_dev *inputdev) | ||
547 | { | ||
548 | struct gtco *device = inputdev->private; | ||
549 | |||
550 | usb_kill_urb(device->urbinfo); | ||
551 | |||
552 | } | ||
553 | |||
554 | |||
555 | /* | ||
556 | * Setup input device capabilities. Tell the input system what this | ||
557 | * device is capable of generating. | ||
558 | * | ||
559 | * This information is based on what is read from the HID report and | ||
560 | * placed in the struct gtco structure | ||
561 | * | ||
562 | */ | ||
563 | static void gtco_setup_caps(struct input_dev *inputdev) | ||
564 | { | ||
565 | struct gtco *device = inputdev->private; | ||
566 | |||
567 | |||
568 | /* Which events */ | ||
569 | inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); | ||
570 | |||
571 | |||
572 | /* Misc event menu block */ | ||
573 | inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ; | ||
574 | |||
575 | |||
576 | /* Absolute values based on HID report info */ | ||
577 | input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X, | ||
578 | 0, 0); | ||
579 | input_set_abs_params(inputdev, ABS_Y, device->min_Y, device->max_Y, | ||
580 | 0, 0); | ||
581 | |||
582 | /* Proximity */ | ||
583 | input_set_abs_params(inputdev, ABS_DISTANCE, 0, 1, 0, 0); | ||
584 | |||
585 | /* Tilt & pressure */ | ||
586 | input_set_abs_params(inputdev, ABS_TILT_X, device->mintilt_X, | ||
587 | device->maxtilt_X, 0, 0); | ||
588 | input_set_abs_params(inputdev, ABS_TILT_Y, device->mintilt_Y, | ||
589 | device->maxtilt_Y, 0, 0); | ||
590 | input_set_abs_params(inputdev, ABS_PRESSURE, device->minpressure, | ||
591 | device->maxpressure, 0, 0); | ||
592 | |||
593 | |||
594 | /* Transducer */ | ||
595 | input_set_abs_params(inputdev, ABS_MISC, 0,0xFF, 0, 0); | ||
596 | |||
597 | } | ||
598 | |||
599 | |||
600 | |||
601 | /* USB Routines */ | ||
602 | |||
603 | |||
604 | /* | ||
605 | * URB callback routine. Called when we get IRQ reports from the | ||
606 | * digitizer. | ||
607 | * | ||
608 | * This bridges the USB and input device worlds. It generates events | ||
609 | * on the input device based on the USB reports. | ||
610 | */ | ||
611 | static void gtco_urb_callback(struct urb *urbinfo) | ||
612 | { | ||
613 | |||
614 | |||
615 | struct gtco *device = urbinfo->context; | ||
616 | struct input_dev *inputdev; | ||
617 | int rc; | ||
618 | u32 val = 0; | ||
619 | s8 valsigned = 0; | ||
620 | char le_buffer[2]; | ||
621 | |||
622 | inputdev = device->inputdevice; | ||
623 | |||
624 | |||
625 | /* Was callback OK? */ | ||
626 | if ((urbinfo->status == -ECONNRESET ) || | ||
627 | (urbinfo->status == -ENOENT ) || | ||
628 | (urbinfo->status == -ESHUTDOWN )){ | ||
629 | |||
630 | /* Shutdown is occurring. Return and don't queue up any more */ | ||
631 | return; | ||
632 | } | ||
633 | |||
634 | if (urbinfo->status != 0 ) { | ||
635 | /* Some unknown error. Hopefully temporary. Just go and */ | ||
636 | /* requeue an URB */ | ||
637 | goto resubmit; | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * Good URB, now process | ||
642 | */ | ||
643 | |||
644 | /* PID dependent when we interpret the report */ | ||
645 | if ((inputdev->id.product == PID_1000 )|| | ||
646 | (inputdev->id.product == PID_1001 )|| | ||
647 | (inputdev->id.product == PID_1002 )) | ||
648 | { | ||
649 | |||
650 | /* | ||
651 | * Switch on the report ID | ||
652 | * Conveniently, the reports have more information, the higher | ||
653 | * the report number. We can just fall through the case | ||
654 | * statements if we start with the highest number report | ||
655 | */ | ||
656 | switch(device->buffer[0]){ | ||
657 | case 5: | ||
658 | /* Pressure is 9 bits */ | ||
659 | val = ((u16)(device->buffer[8]) << 1); | ||
660 | val |= (u16)(device->buffer[7] >> 7); | ||
661 | input_report_abs(inputdev, ABS_PRESSURE, | ||
662 | device->buffer[8]); | ||
663 | |||
664 | /* Mask out the Y tilt value used for pressure */ | ||
665 | device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); | ||
666 | |||
667 | |||
668 | /* Fall thru */ | ||
669 | case 4: | ||
670 | /* Tilt */ | ||
671 | |||
672 | /* Sign extend these 7 bit numbers. */ | ||
673 | if (device->buffer[6] & 0x40) | ||
674 | device->buffer[6] |= 0x80; | ||
675 | |||
676 | if (device->buffer[7] & 0x40) | ||
677 | device->buffer[7] |= 0x80; | ||
678 | |||
679 | |||
680 | valsigned = (device->buffer[6]); | ||
681 | input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned); | ||
682 | |||
683 | valsigned = (device->buffer[7]); | ||
684 | input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); | ||
685 | |||
686 | /* Fall thru */ | ||
687 | |||
688 | case 2: | ||
689 | case 3: | ||
690 | /* Convert buttons, only 5 bits possible */ | ||
691 | val = (device->buffer[5])&MASK_BUTTON; | ||
692 | |||
693 | /* We don't apply any meaning to the bitmask, | ||
694 | just report */ | ||
695 | input_event(inputdev, EV_MSC, MSC_SERIAL, val); | ||
696 | |||
697 | /* Fall thru */ | ||
698 | case 1: | ||
699 | |||
700 | /* All reports have X and Y coords in the same place */ | ||
701 | val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[1]))); | ||
702 | input_report_abs(inputdev, ABS_X, val); | ||
703 | |||
704 | val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[3]))); | ||
705 | input_report_abs(inputdev, ABS_Y, val); | ||
706 | |||
707 | |||
708 | /* Ditto for proximity bit */ | ||
709 | if (device->buffer[5]& MASK_INRANGE){ | ||
710 | val = 1; | ||
711 | }else{ | ||
712 | val=0; | ||
713 | } | ||
714 | input_report_abs(inputdev, ABS_DISTANCE, val); | ||
715 | |||
716 | |||
717 | /* Report 1 is an exception to how we handle buttons */ | ||
718 | /* Buttons are an index, not a bitmask */ | ||
719 | if (device->buffer[0] == 1){ | ||
720 | |||
721 | /* Convert buttons, 5 bit index */ | ||
722 | /* Report value of index set as one, | ||
723 | the rest as 0 */ | ||
724 | val = device->buffer[5]& MASK_BUTTON; | ||
725 | dbg("======>>>>>>REPORT 1: val 0x%X(%d)", | ||
726 | val,val); | ||
727 | |||
728 | /* | ||
729 | * We don't apply any meaning to the button | ||
730 | * index, just report it | ||
731 | */ | ||
732 | input_event(inputdev, EV_MSC, MSC_SERIAL, val); | ||
733 | |||
734 | |||
735 | } | ||
736 | |||
737 | break; | ||
738 | case 7: | ||
739 | /* Menu blocks */ | ||
740 | input_event(inputdev, EV_MSC, MSC_SCAN, | ||
741 | device->buffer[1]); | ||
742 | |||
743 | |||
744 | break; | ||
745 | |||
746 | } | ||
747 | |||
748 | |||
749 | } | ||
750 | /* Other pid class */ | ||
751 | if ((inputdev->id.product == PID_400 )|| | ||
752 | (inputdev->id.product == PID_401 )) | ||
753 | { | ||
754 | |||
755 | /* Report 2 */ | ||
756 | if (device->buffer[0] == 2){ | ||
757 | /* Menu blocks */ | ||
758 | input_event(inputdev, EV_MSC, MSC_SCAN, | ||
759 | device->buffer[1]); | ||
760 | } | ||
761 | |||
762 | /* Report 1 */ | ||
763 | if (device->buffer[0] == 1){ | ||
764 | char buttonbyte; | ||
765 | |||
766 | |||
767 | /* IF X max > 64K, we still a bit from the y report */ | ||
768 | if (device->max_X > 0x10000){ | ||
769 | |||
770 | val = (u16)(((u16)(device->buffer[2]<<8))|((u8)(device->buffer[1]))); | ||
771 | val |= (u32)(((u8)device->buffer[3]&0x1)<< 16); | ||
772 | |||
773 | input_report_abs(inputdev, ABS_X, val); | ||
774 | |||
775 | le_buffer[0] = (u8)((u8)(device->buffer[3])>>1); | ||
776 | le_buffer[0] |= (u8)((device->buffer[3]&0x1)<<7); | ||
777 | |||
778 | le_buffer[1] = (u8)(device->buffer[4]>>1); | ||
779 | le_buffer[1] |= (u8)((device->buffer[5]&0x1)<<7); | ||
780 | |||
781 | val = le16_to_cpu(get_unaligned((__le16 *)(le_buffer))); | ||
782 | |||
783 | input_report_abs(inputdev, ABS_Y, val); | ||
784 | |||
785 | |||
786 | /* | ||
787 | * Shift the button byte right by one to | ||
788 | * make it look like the standard report | ||
789 | */ | ||
790 | buttonbyte = (device->buffer[5])>>1; | ||
791 | }else{ | ||
792 | |||
793 | val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[1])))); | ||
794 | input_report_abs(inputdev, ABS_X, val); | ||
795 | |||
796 | val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[3])))); | ||
797 | input_report_abs(inputdev, ABS_Y, val); | ||
798 | |||
799 | buttonbyte = device->buffer[5]; | ||
800 | |||
801 | } | ||
802 | |||
803 | |||
804 | /* BUTTONS and PROXIMITY */ | ||
805 | if (buttonbyte& MASK_INRANGE){ | ||
806 | val = 1; | ||
807 | }else{ | ||
808 | val=0; | ||
809 | } | ||
810 | input_report_abs(inputdev, ABS_DISTANCE, val); | ||
811 | |||
812 | /* Convert buttons, only 4 bits possible */ | ||
813 | val = buttonbyte&0x0F; | ||
814 | #ifdef USE_BUTTONS | ||
815 | for ( i=0;i<5;i++){ | ||
816 | input_report_key(inputdev, BTN_DIGI+i,val&(1<<i)); | ||
817 | } | ||
818 | #else | ||
819 | /* We don't apply any meaning to the bitmask, just report */ | ||
820 | input_event(inputdev, EV_MSC, MSC_SERIAL, val); | ||
821 | #endif | ||
822 | /* TRANSDUCER */ | ||
823 | input_report_abs(inputdev, ABS_MISC, device->buffer[6]); | ||
824 | |||
825 | } | ||
826 | } | ||
827 | |||
828 | /* Everybody gets report ID's */ | ||
829 | input_event(inputdev, EV_MSC, MSC_RAW, device->buffer[0]); | ||
830 | |||
831 | /* Sync it up */ | ||
832 | input_sync(inputdev); | ||
833 | |||
834 | resubmit: | ||
835 | rc = usb_submit_urb(urbinfo, GFP_ATOMIC); | ||
836 | if (rc != 0) { | ||
837 | err("usb_submit_urb failed rc=0x%x",rc); | ||
838 | } | ||
839 | |||
840 | } | ||
841 | |||
842 | /* | ||
843 | * The probe routine. This is called when the kernel find the matching USB | ||
844 | * vendor/product. We do the following: | ||
845 | * | ||
846 | * - Allocate mem for a local structure to manage the device | ||
847 | * - Request a HID Report Descriptor from the device and parse it to | ||
848 | * find out the device parameters | ||
849 | * - Create an input device and assign it attributes | ||
850 | * - Allocate an URB so the device can talk to us when the input | ||
851 | * queue is open | ||
852 | */ | ||
853 | static int gtco_probe(struct usb_interface *usbinterface, | ||
854 | const struct usb_device_id *id) | ||
855 | { | ||
856 | |||
857 | struct gtco *device = NULL; | ||
858 | char path[PATHLENGTH]; | ||
859 | struct input_dev *inputdev; | ||
860 | struct hid_descriptor *hid_desc; | ||
861 | char *report; | ||
862 | int result=0, retry; | ||
863 | struct usb_endpoint_descriptor *endpoint; | ||
864 | |||
865 | /* Allocate memory for device structure */ | ||
866 | device = kzalloc(sizeof(struct gtco), GFP_KERNEL); | ||
867 | if (device == NULL) { | ||
868 | err("No more memory"); | ||
869 | return -ENOMEM; | ||
870 | } | ||
871 | |||
872 | |||
873 | device->inputdevice = input_allocate_device(); | ||
874 | if (!device->inputdevice){ | ||
875 | kfree(device); | ||
876 | err("No more memory"); | ||
877 | return -ENOMEM; | ||
878 | } | ||
879 | |||
880 | /* Get pointer to the input device */ | ||
881 | inputdev = device->inputdevice; | ||
882 | |||
883 | /* Save interface information */ | ||
884 | device->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); | ||
885 | |||
886 | |||
887 | /* Allocate some data for incoming reports */ | ||
888 | device->buffer = usb_buffer_alloc(device->usbdev, REPORT_MAX_SIZE, | ||
889 | GFP_KERNEL, &(device->buf_dma)); | ||
890 | if (!device->buffer){ | ||
891 | input_free_device(device->inputdevice); | ||
892 | kfree(device); | ||
893 | err("No more memory"); | ||
894 | return -ENOMEM; | ||
895 | } | ||
896 | |||
897 | /* Allocate URB for reports */ | ||
898 | device->urbinfo = usb_alloc_urb(0, GFP_KERNEL); | ||
899 | if (!device->urbinfo) { | ||
900 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
901 | device->buffer, device->buf_dma); | ||
902 | input_free_device(device->inputdevice); | ||
903 | kfree(device); | ||
904 | err("No more memory"); | ||
905 | return -ENOMEM; | ||
906 | } | ||
907 | |||
908 | |||
909 | /* | ||
910 | * The endpoint is always altsetting 0, we know this since we know | ||
911 | * this device only has one interrupt endpoint | ||
912 | */ | ||
913 | endpoint = &usbinterface->altsetting[0].endpoint[0].desc; | ||
914 | |||
915 | /* Some debug */ | ||
916 | dbg("gtco # interfaces: %d",usbinterface->num_altsetting); | ||
917 | dbg("num endpoints: %d",usbinterface->cur_altsetting->desc.bNumEndpoints); | ||
918 | dbg("interface class: %d",usbinterface->cur_altsetting->desc.bInterfaceClass); | ||
919 | dbg("endpoint: attribute:0x%x type:0x%x",endpoint->bmAttributes,endpoint->bDescriptorType); | ||
920 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) | ||
921 | dbg("endpoint: we have interrupt endpoint\n"); | ||
922 | |||
923 | dbg("endpoint extra len:%d ",usbinterface->altsetting[0].extralen); | ||
924 | |||
925 | |||
926 | |||
927 | /* | ||
928 | * Find the HID descriptor so we can find out the size of the | ||
929 | * HID report descriptor | ||
930 | */ | ||
931 | if (usb_get_extra_descriptor(usbinterface->cur_altsetting, | ||
932 | HID_DEVICE_TYPE,&hid_desc) != 0){ | ||
933 | err("Can't retrieve exta USB descriptor to get hid report descriptor length"); | ||
934 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
935 | device->buffer, device->buf_dma); | ||
936 | input_free_device(device->inputdevice); | ||
937 | kfree(device); | ||
938 | return -EIO; | ||
939 | } | ||
940 | |||
941 | dbg("Extra descriptor success: type:%d len:%d", | ||
942 | hid_desc->bDescriptorType, hid_desc->wDescriptorLength); | ||
943 | |||
944 | if (!(report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL))) { | ||
945 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
946 | device->buffer, device->buf_dma); | ||
947 | |||
948 | input_free_device(device->inputdevice); | ||
949 | kfree(device); | ||
950 | err("No more memory"); | ||
951 | return -ENOMEM; | ||
952 | } | ||
953 | |||
954 | /* Couple of tries to get reply */ | ||
955 | for (retry=0;retry<3;retry++) { | ||
956 | result = usb_control_msg(device->usbdev, | ||
957 | usb_rcvctrlpipe(device->usbdev, 0), | ||
958 | USB_REQ_GET_DESCRIPTOR, | ||
959 | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
960 | (REPORT_DEVICE_TYPE << 8), | ||
961 | 0, /* interface */ | ||
962 | report, | ||
963 | hid_desc->wDescriptorLength, | ||
964 | 5000); /* 5 secs */ | ||
965 | |||
966 | if (result == hid_desc->wDescriptorLength) | ||
967 | break; | ||
968 | } | ||
969 | |||
970 | /* If we didn't get the report, fail */ | ||
971 | dbg("usb_control_msg result: :%d", result); | ||
972 | if (result != hid_desc->wDescriptorLength){ | ||
973 | kfree(report); | ||
974 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
975 | device->buffer, device->buf_dma); | ||
976 | input_free_device(device->inputdevice); | ||
977 | kfree(device); | ||
978 | err("Failed to get HID Report Descriptor of size: %d", | ||
979 | hid_desc->wDescriptorLength); | ||
980 | return -EIO; | ||
981 | } | ||
982 | |||
983 | |||
984 | /* Now we parse the report */ | ||
985 | parse_hid_report_descriptor(device,report,result); | ||
986 | |||
987 | /* Now we delete it */ | ||
988 | kfree(report); | ||
989 | |||
990 | /* Create a device file node */ | ||
991 | usb_make_path(device->usbdev, path, PATHLENGTH); | ||
992 | sprintf(device->usbpath, "%s/input0", path); | ||
993 | |||
994 | |||
995 | /* Set Input device functions */ | ||
996 | inputdev->open = gtco_input_open; | ||
997 | inputdev->close = gtco_input_close; | ||
998 | |||
999 | /* Set input device information */ | ||
1000 | inputdev->name = "GTCO_CalComp"; | ||
1001 | inputdev->phys = device->usbpath; | ||
1002 | inputdev->private = device; | ||
1003 | |||
1004 | |||
1005 | /* Now set up all the input device capabilities */ | ||
1006 | gtco_setup_caps(inputdev); | ||
1007 | |||
1008 | /* Set input device required ID information */ | ||
1009 | usb_to_input_id(device->usbdev, &device->inputdevice->id); | ||
1010 | inputdev->cdev.dev = &usbinterface->dev; | ||
1011 | |||
1012 | /* Setup the URB, it will be posted later on open of input device */ | ||
1013 | endpoint = &usbinterface->altsetting[0].endpoint[0].desc; | ||
1014 | |||
1015 | usb_fill_int_urb(device->urbinfo, | ||
1016 | device->usbdev, | ||
1017 | usb_rcvintpipe(device->usbdev, | ||
1018 | endpoint->bEndpointAddress), | ||
1019 | device->buffer, | ||
1020 | REPORT_MAX_SIZE, | ||
1021 | gtco_urb_callback, | ||
1022 | device, | ||
1023 | endpoint->bInterval); | ||
1024 | |||
1025 | device->urbinfo->transfer_dma = device->buf_dma; | ||
1026 | device->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
1027 | |||
1028 | |||
1029 | /* Save device pointer in USB interface device */ | ||
1030 | usb_set_intfdata(usbinterface, device); | ||
1031 | |||
1032 | /* All done, now register the input device */ | ||
1033 | input_register_device(inputdev); | ||
1034 | |||
1035 | info( "gtco driver created usb: %s\n", path); | ||
1036 | return 0; | ||
1037 | |||
1038 | } | ||
1039 | |||
1040 | /* | ||
1041 | * This function is a standard USB function called when the USB device | ||
1042 | * is disconnected. We will get rid of the URV, de-register the input | ||
1043 | * device, and free up allocated memory | ||
1044 | */ | ||
1045 | static void gtco_disconnect(struct usb_interface *interface) | ||
1046 | { | ||
1047 | |||
1048 | /* Grab private device ptr */ | ||
1049 | struct gtco *device = usb_get_intfdata (interface); | ||
1050 | struct input_dev *inputdev; | ||
1051 | |||
1052 | inputdev = device->inputdevice; | ||
1053 | |||
1054 | /* Now reverse all the registration stuff */ | ||
1055 | if (device) { | ||
1056 | input_unregister_device(inputdev); | ||
1057 | usb_kill_urb(device->urbinfo); | ||
1058 | usb_free_urb(device->urbinfo); | ||
1059 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
1060 | device->buffer, device->buf_dma); | ||
1061 | kfree(device); | ||
1062 | } | ||
1063 | |||
1064 | info("gtco driver disconnected"); | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | /* STANDARD MODULE LOAD ROUTINES */ | ||
1069 | |||
1070 | static struct usb_driver gtco_driverinfo_table = { | ||
1071 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) | ||
1072 | .owner = THIS_MODULE, | ||
1073 | #endif | ||
1074 | .name = "gtco", | ||
1075 | .id_table = gtco_usbid_table, | ||
1076 | .probe = gtco_probe, | ||
1077 | .disconnect = gtco_disconnect, | ||
1078 | }; | ||
1079 | /* | ||
1080 | * Register this module with the USB subsystem | ||
1081 | */ | ||
1082 | static int __init gtco_init(void) | ||
1083 | { | ||
1084 | int rc; | ||
1085 | rc = usb_register(>co_driverinfo_table); | ||
1086 | if (rc) { | ||
1087 | err("usb_register() failed rc=0x%x", rc); | ||
1088 | } | ||
1089 | printk("GTCO usb driver version: %s",GTCO_VERSION); | ||
1090 | return rc; | ||
1091 | } | ||
1092 | |||
1093 | /* | ||
1094 | * Deregister this module with the USB subsystem | ||
1095 | */ | ||
1096 | static void __exit gtco_exit(void) | ||
1097 | { | ||
1098 | usb_deregister(>co_driverinfo_table); | ||
1099 | } | ||
1100 | |||
1101 | module_init (gtco_init); | ||
1102 | module_exit (gtco_exit); | ||
1103 | |||
1104 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index e07a30490726..84983d1b7164 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -768,6 +768,9 @@ void usbhid_init_reports(struct hid_device *hid) | |||
768 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 | 768 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 |
769 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 | 769 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 |
770 | 770 | ||
771 | #define USB_VENDOR_ID_SONY 0x054c | ||
772 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | ||
773 | |||
771 | /* | 774 | /* |
772 | * Alphabetically sorted blacklist by quirk type. | 775 | * Alphabetically sorted blacklist by quirk type. |
773 | */ | 776 | */ |
@@ -949,6 +952,8 @@ static const struct hid_blacklist { | |||
949 | 952 | ||
950 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 953 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
951 | 954 | ||
955 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, | ||
956 | |||
952 | { 0, 0 } | 957 | { 0, 0 } |
953 | }; | 958 | }; |
954 | 959 | ||
@@ -1013,6 +1018,32 @@ static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) | |||
1013 | } | 1018 | } |
1014 | } | 1019 | } |
1015 | 1020 | ||
1021 | /* | ||
1022 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | ||
1023 | * to "operational". Without this, the ps3 controller will not report any | ||
1024 | * events. | ||
1025 | */ | ||
1026 | static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) | ||
1027 | { | ||
1028 | int result; | ||
1029 | char *buf = kmalloc(18, GFP_KERNEL); | ||
1030 | |||
1031 | if (!buf) | ||
1032 | return; | ||
1033 | |||
1034 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
1035 | HID_REQ_GET_REPORT, | ||
1036 | USB_DIR_IN | USB_TYPE_CLASS | | ||
1037 | USB_RECIP_INTERFACE, | ||
1038 | (3 << 8) | 0xf2, ifnum, buf, 17, | ||
1039 | USB_CTRL_GET_TIMEOUT); | ||
1040 | |||
1041 | if (result < 0) | ||
1042 | err("%s failed: %d\n", __func__, result); | ||
1043 | |||
1044 | kfree(buf); | ||
1045 | } | ||
1046 | |||
1016 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) | 1047 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) |
1017 | { | 1048 | { |
1018 | struct usb_host_interface *interface = intf->cur_altsetting; | 1049 | struct usb_host_interface *interface = intf->cur_altsetting; |
@@ -1303,6 +1334,10 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1303 | if ((hid->claimed & HID_CLAIMED_INPUT)) | 1334 | if ((hid->claimed & HID_CLAIMED_INPUT)) |
1304 | hid_ff_init(hid); | 1335 | hid_ff_init(hid); |
1305 | 1336 | ||
1337 | if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) | ||
1338 | hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), | ||
1339 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
1340 | |||
1306 | printk(KERN_INFO); | 1341 | printk(KERN_INFO); |
1307 | 1342 | ||
1308 | if (hid->claimed & HID_CLAIMED_INPUT) | 1343 | if (hid->claimed & HID_CLAIMED_INPUT) |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index c9418535bef8..15c70bd048c4 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -269,7 +269,7 @@ static int idmouse_release(struct inode *inode, struct file *file) | |||
269 | /* prevent a race condition with open() */ | 269 | /* prevent a race condition with open() */ |
270 | mutex_lock(&disconnect_mutex); | 270 | mutex_lock(&disconnect_mutex); |
271 | 271 | ||
272 | dev = (struct usb_idmouse *) file->private_data; | 272 | dev = file->private_data; |
273 | 273 | ||
274 | if (dev == NULL) { | 274 | if (dev == NULL) { |
275 | mutex_unlock(&disconnect_mutex); | 275 | mutex_unlock(&disconnect_mutex); |
@@ -304,17 +304,15 @@ static int idmouse_release(struct inode *inode, struct file *file) | |||
304 | static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count, | 304 | static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count, |
305 | loff_t * ppos) | 305 | loff_t * ppos) |
306 | { | 306 | { |
307 | struct usb_idmouse *dev; | 307 | struct usb_idmouse *dev = file->private_data; |
308 | int result; | 308 | int result; |
309 | 309 | ||
310 | dev = (struct usb_idmouse *) file->private_data; | ||
311 | |||
312 | /* lock this object */ | 310 | /* lock this object */ |
313 | down (&dev->sem); | 311 | down(&dev->sem); |
314 | 312 | ||
315 | /* verify that the device wasn't unplugged */ | 313 | /* verify that the device wasn't unplugged */ |
316 | if (!dev->present) { | 314 | if (!dev->present) { |
317 | up (&dev->sem); | 315 | up(&dev->sem); |
318 | return -ENODEV; | 316 | return -ENODEV; |
319 | } | 317 | } |
320 | 318 | ||
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 384fa3769805..fdf68479a166 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -69,7 +69,7 @@ struct rio_usb_data { | |||
69 | char *obuf, *ibuf; /* transfer buffers */ | 69 | char *obuf, *ibuf; /* transfer buffers */ |
70 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ | 70 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ |
71 | wait_queue_head_t wait_q; /* for timeouts */ | 71 | wait_queue_head_t wait_q; /* for timeouts */ |
72 | struct semaphore lock; /* general race avoidance */ | 72 | struct mutex lock; /* general race avoidance */ |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static struct rio_usb_data rio_instance; | 75 | static struct rio_usb_data rio_instance; |
@@ -78,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file) | |||
78 | { | 78 | { |
79 | struct rio_usb_data *rio = &rio_instance; | 79 | struct rio_usb_data *rio = &rio_instance; |
80 | 80 | ||
81 | down(&(rio->lock)); | 81 | mutex_lock(&(rio->lock)); |
82 | 82 | ||
83 | if (rio->isopen || !rio->present) { | 83 | if (rio->isopen || !rio->present) { |
84 | up(&(rio->lock)); | 84 | mutex_unlock(&(rio->lock)); |
85 | return -EBUSY; | 85 | return -EBUSY; |
86 | } | 86 | } |
87 | rio->isopen = 1; | 87 | rio->isopen = 1; |
88 | 88 | ||
89 | init_waitqueue_head(&rio->wait_q); | 89 | init_waitqueue_head(&rio->wait_q); |
90 | 90 | ||
91 | up(&(rio->lock)); | 91 | mutex_unlock(&(rio->lock)); |
92 | 92 | ||
93 | info("Rio opened."); | 93 | info("Rio opened."); |
94 | 94 | ||
@@ -117,7 +117,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, | |||
117 | int retries; | 117 | int retries; |
118 | int retval=0; | 118 | int retval=0; |
119 | 119 | ||
120 | down(&(rio->lock)); | 120 | mutex_lock(&(rio->lock)); |
121 | /* Sanity check to make sure rio is connected, powered, etc */ | 121 | /* Sanity check to make sure rio is connected, powered, etc */ |
122 | if ( rio == NULL || | 122 | if ( rio == NULL || |
123 | rio->present == 0 || | 123 | rio->present == 0 || |
@@ -257,7 +257,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, | |||
257 | 257 | ||
258 | 258 | ||
259 | err_out: | 259 | err_out: |
260 | up(&(rio->lock)); | 260 | mutex_unlock(&(rio->lock)); |
261 | return retval; | 261 | return retval; |
262 | } | 262 | } |
263 | 263 | ||
@@ -275,14 +275,17 @@ write_rio(struct file *file, const char __user *buffer, | |||
275 | int result = 0; | 275 | int result = 0; |
276 | int maxretry; | 276 | int maxretry; |
277 | int errn = 0; | 277 | int errn = 0; |
278 | int intr; | ||
278 | 279 | ||
279 | down(&(rio->lock)); | 280 | intr = mutex_lock_interruptible(&(rio->lock)); |
281 | if (intr) | ||
282 | return -EINTR; | ||
280 | /* Sanity check to make sure rio is connected, powered, etc */ | 283 | /* Sanity check to make sure rio is connected, powered, etc */ |
281 | if ( rio == NULL || | 284 | if ( rio == NULL || |
282 | rio->present == 0 || | 285 | rio->present == 0 || |
283 | rio->rio_dev == NULL ) | 286 | rio->rio_dev == NULL ) |
284 | { | 287 | { |
285 | up(&(rio->lock)); | 288 | mutex_unlock(&(rio->lock)); |
286 | return -ENODEV; | 289 | return -ENODEV; |
287 | } | 290 | } |
288 | 291 | ||
@@ -305,7 +308,7 @@ write_rio(struct file *file, const char __user *buffer, | |||
305 | goto error; | 308 | goto error; |
306 | } | 309 | } |
307 | if (signal_pending(current)) { | 310 | if (signal_pending(current)) { |
308 | up(&(rio->lock)); | 311 | mutex_unlock(&(rio->lock)); |
309 | return bytes_written ? bytes_written : -EINTR; | 312 | return bytes_written ? bytes_written : -EINTR; |
310 | } | 313 | } |
311 | 314 | ||
@@ -341,12 +344,12 @@ write_rio(struct file *file, const char __user *buffer, | |||
341 | buffer += copy_size; | 344 | buffer += copy_size; |
342 | } while (count > 0); | 345 | } while (count > 0); |
343 | 346 | ||
344 | up(&(rio->lock)); | 347 | mutex_unlock(&(rio->lock)); |
345 | 348 | ||
346 | return bytes_written ? bytes_written : -EIO; | 349 | return bytes_written ? bytes_written : -EIO; |
347 | 350 | ||
348 | error: | 351 | error: |
349 | up(&(rio->lock)); | 352 | mutex_unlock(&(rio->lock)); |
350 | return errn; | 353 | return errn; |
351 | } | 354 | } |
352 | 355 | ||
@@ -361,14 +364,17 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
361 | int result; | 364 | int result; |
362 | int maxretry = 10; | 365 | int maxretry = 10; |
363 | char *ibuf; | 366 | char *ibuf; |
367 | int intr; | ||
364 | 368 | ||
365 | down(&(rio->lock)); | 369 | intr = mutex_lock_interruptible(&(rio->lock)); |
370 | if (intr) | ||
371 | return -EINTR; | ||
366 | /* Sanity check to make sure rio is connected, powered, etc */ | 372 | /* Sanity check to make sure rio is connected, powered, etc */ |
367 | if ( rio == NULL || | 373 | if ( rio == NULL || |
368 | rio->present == 0 || | 374 | rio->present == 0 || |
369 | rio->rio_dev == NULL ) | 375 | rio->rio_dev == NULL ) |
370 | { | 376 | { |
371 | up(&(rio->lock)); | 377 | mutex_unlock(&(rio->lock)); |
372 | return -ENODEV; | 378 | return -ENODEV; |
373 | } | 379 | } |
374 | 380 | ||
@@ -379,11 +385,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
379 | 385 | ||
380 | while (count > 0) { | 386 | while (count > 0) { |
381 | if (signal_pending(current)) { | 387 | if (signal_pending(current)) { |
382 | up(&(rio->lock)); | 388 | mutex_unlock(&(rio->lock)); |
383 | return read_count ? read_count : -EINTR; | 389 | return read_count ? read_count : -EINTR; |
384 | } | 390 | } |
385 | if (!rio->rio_dev) { | 391 | if (!rio->rio_dev) { |
386 | up(&(rio->lock)); | 392 | mutex_unlock(&(rio->lock)); |
387 | return -ENODEV; | 393 | return -ENODEV; |
388 | } | 394 | } |
389 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; | 395 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; |
@@ -400,7 +406,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
400 | count = this_read = partial; | 406 | count = this_read = partial; |
401 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ | 407 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ |
402 | if (!maxretry--) { | 408 | if (!maxretry--) { |
403 | up(&(rio->lock)); | 409 | mutex_unlock(&(rio->lock)); |
404 | err("read_rio: maxretry timeout"); | 410 | err("read_rio: maxretry timeout"); |
405 | return -ETIME; | 411 | return -ETIME; |
406 | } | 412 | } |
@@ -409,18 +415,18 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
409 | finish_wait(&rio->wait_q, &wait); | 415 | finish_wait(&rio->wait_q, &wait); |
410 | continue; | 416 | continue; |
411 | } else if (result != -EREMOTEIO) { | 417 | } else if (result != -EREMOTEIO) { |
412 | up(&(rio->lock)); | 418 | mutex_unlock(&(rio->lock)); |
413 | err("Read Whoops - result:%u partial:%u this_read:%u", | 419 | err("Read Whoops - result:%u partial:%u this_read:%u", |
414 | result, partial, this_read); | 420 | result, partial, this_read); |
415 | return -EIO; | 421 | return -EIO; |
416 | } else { | 422 | } else { |
417 | up(&(rio->lock)); | 423 | mutex_unlock(&(rio->lock)); |
418 | return (0); | 424 | return (0); |
419 | } | 425 | } |
420 | 426 | ||
421 | if (this_read) { | 427 | if (this_read) { |
422 | if (copy_to_user(buffer, ibuf, this_read)) { | 428 | if (copy_to_user(buffer, ibuf, this_read)) { |
423 | up(&(rio->lock)); | 429 | mutex_unlock(&(rio->lock)); |
424 | return -EFAULT; | 430 | return -EFAULT; |
425 | } | 431 | } |
426 | count -= this_read; | 432 | count -= this_read; |
@@ -428,7 +434,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
428 | buffer += this_read; | 434 | buffer += this_read; |
429 | } | 435 | } |
430 | } | 436 | } |
431 | up(&(rio->lock)); | 437 | mutex_unlock(&(rio->lock)); |
432 | return read_count; | 438 | return read_count; |
433 | } | 439 | } |
434 | 440 | ||
@@ -480,7 +486,7 @@ static int probe_rio(struct usb_interface *intf, | |||
480 | } | 486 | } |
481 | dbg("probe_rio: ibuf address:%p", rio->ibuf); | 487 | dbg("probe_rio: ibuf address:%p", rio->ibuf); |
482 | 488 | ||
483 | init_MUTEX(&(rio->lock)); | 489 | mutex_init(&(rio->lock)); |
484 | 490 | ||
485 | usb_set_intfdata (intf, rio); | 491 | usb_set_intfdata (intf, rio); |
486 | rio->present = 1; | 492 | rio->present = 1; |
@@ -496,12 +502,12 @@ static void disconnect_rio(struct usb_interface *intf) | |||
496 | if (rio) { | 502 | if (rio) { |
497 | usb_deregister_dev(intf, &usb_rio_class); | 503 | usb_deregister_dev(intf, &usb_rio_class); |
498 | 504 | ||
499 | down(&(rio->lock)); | 505 | mutex_lock(&(rio->lock)); |
500 | if (rio->isopen) { | 506 | if (rio->isopen) { |
501 | rio->isopen = 0; | 507 | rio->isopen = 0; |
502 | /* better let it finish - the release will do whats needed */ | 508 | /* better let it finish - the release will do whats needed */ |
503 | rio->rio_dev = NULL; | 509 | rio->rio_dev = NULL; |
504 | up(&(rio->lock)); | 510 | mutex_unlock(&(rio->lock)); |
505 | return; | 511 | return; |
506 | } | 512 | } |
507 | kfree(rio->ibuf); | 513 | kfree(rio->ibuf); |
@@ -510,7 +516,7 @@ static void disconnect_rio(struct usb_interface *intf) | |||
510 | info("USB Rio disconnected."); | 516 | info("USB Rio disconnected."); |
511 | 517 | ||
512 | rio->present = 0; | 518 | rio->present = 0; |
513 | up(&(rio->lock)); | 519 | mutex_unlock(&(rio->lock)); |
514 | } | 520 | } |
515 | } | 521 | } |
516 | 522 | ||
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index 3cf3ea3a88ed..90c59535778d 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for USB Core files and filesystem | 2 | # Makefile for USB Core files and filesystem |
3 | # | 3 | # |
4 | 4 | ||
5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_dma.o | 5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_bin.o mon_dma.o |
6 | 6 | ||
7 | # This does not use CONFIG_USB_MON because we want this to use a tristate. | 7 | # This does not use CONFIG_USB_MON because we want this to use a tristate. |
8 | obj-$(CONFIG_USB) += usbmon.o | 8 | obj-$(CONFIG_USB) += usbmon.o |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c new file mode 100644 index 000000000000..c01dfe603672 --- /dev/null +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -0,0 +1,1172 @@ | |||
1 | /* | ||
2 | * The USB Monitor, inspired by Dave Harding's USBMon. | ||
3 | * | ||
4 | * This is a binary format reader. | ||
5 | * | ||
6 | * Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it) | ||
7 | * Copyright (C) 2006 Pete Zaitcev (zaitcev@redhat.com) | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/cdev.h> | ||
14 | #include <linux/usb.h> | ||
15 | #include <linux/poll.h> | ||
16 | #include <linux/compat.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/uaccess.h> | ||
20 | |||
21 | #include "usb_mon.h" | ||
22 | |||
23 | /* | ||
24 | * Defined by USB 2.0 clause 9.3, table 9.2. | ||
25 | */ | ||
26 | #define SETUP_LEN 8 | ||
27 | |||
28 | /* ioctl macros */ | ||
29 | #define MON_IOC_MAGIC 0x92 | ||
30 | |||
31 | #define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1) | ||
32 | /* #2 used to be MON_IOCX_URB, removed before it got into Linus tree */ | ||
33 | #define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) | ||
34 | #define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4) | ||
35 | #define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5) | ||
36 | #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) | ||
37 | #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) | ||
38 | #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) | ||
39 | #ifdef CONFIG_COMPAT | ||
40 | #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) | ||
41 | #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) | ||
42 | #endif | ||
43 | |||
44 | /* | ||
45 | * Some architectures have enormous basic pages (16KB for ia64, 64KB for ppc). | ||
46 | * But it's all right. Just use a simple way to make sure the chunk is never | ||
47 | * smaller than a page. | ||
48 | * | ||
49 | * N.B. An application does not know our chunk size. | ||
50 | * | ||
51 | * Woops, get_zeroed_page() returns a single page. I guess we're stuck with | ||
52 | * page-sized chunks for the time being. | ||
53 | */ | ||
54 | #define CHUNK_SIZE PAGE_SIZE | ||
55 | #define CHUNK_ALIGN(x) (((x)+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1)) | ||
56 | |||
57 | /* | ||
58 | * The magic limit was calculated so that it allows the monitoring | ||
59 | * application to pick data once in two ticks. This way, another application, | ||
60 | * which presumably drives the bus, gets to hog CPU, yet we collect our data. | ||
61 | * If HZ is 100, a 480 mbit/s bus drives 614 KB every jiffy. USB has an | ||
62 | * enormous overhead built into the bus protocol, so we need about 1000 KB. | ||
63 | * | ||
64 | * This is still too much for most cases, where we just snoop a few | ||
65 | * descriptor fetches for enumeration. So, the default is a "reasonable" | ||
66 | * amount for systems with HZ=250 and incomplete bus saturation. | ||
67 | * | ||
68 | * XXX What about multi-megabyte URBs which take minutes to transfer? | ||
69 | */ | ||
70 | #define BUFF_MAX CHUNK_ALIGN(1200*1024) | ||
71 | #define BUFF_DFL CHUNK_ALIGN(300*1024) | ||
72 | #define BUFF_MIN CHUNK_ALIGN(8*1024) | ||
73 | |||
74 | /* | ||
75 | * The per-event API header (2 per URB). | ||
76 | * | ||
77 | * This structure is seen in userland as defined by the documentation. | ||
78 | */ | ||
79 | struct mon_bin_hdr { | ||
80 | u64 id; /* URB ID - from submission to callback */ | ||
81 | unsigned char type; /* Same as in text API; extensible. */ | ||
82 | unsigned char xfer_type; /* ISO, Intr, Control, Bulk */ | ||
83 | unsigned char epnum; /* Endpoint number and transfer direction */ | ||
84 | unsigned char devnum; /* Device address */ | ||
85 | unsigned short busnum; /* Bus number */ | ||
86 | char flag_setup; | ||
87 | char flag_data; | ||
88 | s64 ts_sec; /* gettimeofday */ | ||
89 | s32 ts_usec; /* gettimeofday */ | ||
90 | int status; | ||
91 | unsigned int len_urb; /* Length of data (submitted or actual) */ | ||
92 | unsigned int len_cap; /* Delivered length */ | ||
93 | unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ | ||
94 | }; | ||
95 | |||
96 | /* per file statistic */ | ||
97 | struct mon_bin_stats { | ||
98 | u32 queued; | ||
99 | u32 dropped; | ||
100 | }; | ||
101 | |||
102 | struct mon_bin_get { | ||
103 | struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */ | ||
104 | void __user *data; | ||
105 | size_t alloc; /* Length of data (can be zero) */ | ||
106 | }; | ||
107 | |||
108 | struct mon_bin_mfetch { | ||
109 | u32 __user *offvec; /* Vector of events fetched */ | ||
110 | u32 nfetch; /* Number of events to fetch (out: fetched) */ | ||
111 | u32 nflush; /* Number of events to flush */ | ||
112 | }; | ||
113 | |||
114 | #ifdef CONFIG_COMPAT | ||
115 | struct mon_bin_get32 { | ||
116 | u32 hdr32; | ||
117 | u32 data32; | ||
118 | u32 alloc32; | ||
119 | }; | ||
120 | |||
121 | struct mon_bin_mfetch32 { | ||
122 | u32 offvec32; | ||
123 | u32 nfetch32; | ||
124 | u32 nflush32; | ||
125 | }; | ||
126 | #endif | ||
127 | |||
128 | /* Having these two values same prevents wrapping of the mon_bin_hdr */ | ||
129 | #define PKT_ALIGN 64 | ||
130 | #define PKT_SIZE 64 | ||
131 | |||
132 | /* max number of USB bus supported */ | ||
133 | #define MON_BIN_MAX_MINOR 128 | ||
134 | |||
135 | /* | ||
136 | * The buffer: map of used pages. | ||
137 | */ | ||
138 | struct mon_pgmap { | ||
139 | struct page *pg; | ||
140 | unsigned char *ptr; /* XXX just use page_to_virt everywhere? */ | ||
141 | }; | ||
142 | |||
143 | /* | ||
144 | * This gets associated with an open file struct. | ||
145 | */ | ||
146 | struct mon_reader_bin { | ||
147 | /* The buffer: one per open. */ | ||
148 | spinlock_t b_lock; /* Protect b_cnt, b_in */ | ||
149 | unsigned int b_size; /* Current size of the buffer - bytes */ | ||
150 | unsigned int b_cnt; /* Bytes used */ | ||
151 | unsigned int b_in, b_out; /* Offsets into buffer - bytes */ | ||
152 | unsigned int b_read; /* Amount of read data in curr. pkt. */ | ||
153 | struct mon_pgmap *b_vec; /* The map array */ | ||
154 | wait_queue_head_t b_wait; /* Wait for data here */ | ||
155 | |||
156 | struct mutex fetch_lock; /* Protect b_read, b_out */ | ||
157 | int mmap_active; | ||
158 | |||
159 | /* A list of these is needed for "bus 0". Some time later. */ | ||
160 | struct mon_reader r; | ||
161 | |||
162 | /* Stats */ | ||
163 | unsigned int cnt_lost; | ||
164 | }; | ||
165 | |||
166 | static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp, | ||
167 | unsigned int offset) | ||
168 | { | ||
169 | return (struct mon_bin_hdr *) | ||
170 | (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); | ||
171 | } | ||
172 | |||
173 | #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) | ||
174 | |||
175 | static dev_t mon_bin_dev0; | ||
176 | static struct cdev mon_bin_cdev; | ||
177 | |||
178 | static void mon_buff_area_fill(const struct mon_reader_bin *rp, | ||
179 | unsigned int offset, unsigned int size); | ||
180 | static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp); | ||
181 | static int mon_alloc_buff(struct mon_pgmap *map, int npages); | ||
182 | static void mon_free_buff(struct mon_pgmap *map, int npages); | ||
183 | |||
184 | /* | ||
185 | * This is a "chunked memcpy". It does not manipulate any counters. | ||
186 | * But it returns the new offset for repeated application. | ||
187 | */ | ||
188 | unsigned int mon_copy_to_buff(const struct mon_reader_bin *this, | ||
189 | unsigned int off, const unsigned char *from, unsigned int length) | ||
190 | { | ||
191 | unsigned int step_len; | ||
192 | unsigned char *buf; | ||
193 | unsigned int in_page; | ||
194 | |||
195 | while (length) { | ||
196 | /* | ||
197 | * Determine step_len. | ||
198 | */ | ||
199 | step_len = length; | ||
200 | in_page = CHUNK_SIZE - (off & (CHUNK_SIZE-1)); | ||
201 | if (in_page < step_len) | ||
202 | step_len = in_page; | ||
203 | |||
204 | /* | ||
205 | * Copy data and advance pointers. | ||
206 | */ | ||
207 | buf = this->b_vec[off / CHUNK_SIZE].ptr + off % CHUNK_SIZE; | ||
208 | memcpy(buf, from, step_len); | ||
209 | if ((off += step_len) >= this->b_size) off = 0; | ||
210 | from += step_len; | ||
211 | length -= step_len; | ||
212 | } | ||
213 | return off; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * This is a little worse than the above because it's "chunked copy_to_user". | ||
218 | * The return value is an error code, not an offset. | ||
219 | */ | ||
220 | static int copy_from_buf(const struct mon_reader_bin *this, unsigned int off, | ||
221 | char __user *to, int length) | ||
222 | { | ||
223 | unsigned int step_len; | ||
224 | unsigned char *buf; | ||
225 | unsigned int in_page; | ||
226 | |||
227 | while (length) { | ||
228 | /* | ||
229 | * Determine step_len. | ||
230 | */ | ||
231 | step_len = length; | ||
232 | in_page = CHUNK_SIZE - (off & (CHUNK_SIZE-1)); | ||
233 | if (in_page < step_len) | ||
234 | step_len = in_page; | ||
235 | |||
236 | /* | ||
237 | * Copy data and advance pointers. | ||
238 | */ | ||
239 | buf = this->b_vec[off / CHUNK_SIZE].ptr + off % CHUNK_SIZE; | ||
240 | if (copy_to_user(to, buf, step_len)) | ||
241 | return -EINVAL; | ||
242 | if ((off += step_len) >= this->b_size) off = 0; | ||
243 | to += step_len; | ||
244 | length -= step_len; | ||
245 | } | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Allocate an (aligned) area in the buffer. | ||
251 | * This is called under b_lock. | ||
252 | * Returns ~0 on failure. | ||
253 | */ | ||
254 | static unsigned int mon_buff_area_alloc(struct mon_reader_bin *rp, | ||
255 | unsigned int size) | ||
256 | { | ||
257 | unsigned int offset; | ||
258 | |||
259 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
260 | if (rp->b_cnt + size > rp->b_size) | ||
261 | return ~0; | ||
262 | offset = rp->b_in; | ||
263 | rp->b_cnt += size; | ||
264 | if ((rp->b_in += size) >= rp->b_size) | ||
265 | rp->b_in -= rp->b_size; | ||
266 | return offset; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * This is the same thing as mon_buff_area_alloc, only it does not allow | ||
271 | * buffers to wrap. This is needed by applications which pass references | ||
272 | * into mmap-ed buffers up their stacks (libpcap can do that). | ||
273 | * | ||
274 | * Currently, we always have the header stuck with the data, although | ||
275 | * it is not strictly speaking necessary. | ||
276 | * | ||
277 | * When a buffer would wrap, we place a filler packet to mark the space. | ||
278 | */ | ||
279 | static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp, | ||
280 | unsigned int size) | ||
281 | { | ||
282 | unsigned int offset; | ||
283 | unsigned int fill_size; | ||
284 | |||
285 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
286 | if (rp->b_cnt + size > rp->b_size) | ||
287 | return ~0; | ||
288 | if (rp->b_in + size > rp->b_size) { | ||
289 | /* | ||
290 | * This would wrap. Find if we still have space after | ||
291 | * skipping to the end of the buffer. If we do, place | ||
292 | * a filler packet and allocate a new packet. | ||
293 | */ | ||
294 | fill_size = rp->b_size - rp->b_in; | ||
295 | if (rp->b_cnt + size + fill_size > rp->b_size) | ||
296 | return ~0; | ||
297 | mon_buff_area_fill(rp, rp->b_in, fill_size); | ||
298 | |||
299 | offset = 0; | ||
300 | rp->b_in = size; | ||
301 | rp->b_cnt += size + fill_size; | ||
302 | } else if (rp->b_in + size == rp->b_size) { | ||
303 | offset = rp->b_in; | ||
304 | rp->b_in = 0; | ||
305 | rp->b_cnt += size; | ||
306 | } else { | ||
307 | offset = rp->b_in; | ||
308 | rp->b_in += size; | ||
309 | rp->b_cnt += size; | ||
310 | } | ||
311 | return offset; | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Return a few (kilo-)bytes to the head of the buffer. | ||
316 | * This is used if a DMA fetch fails. | ||
317 | */ | ||
318 | static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) | ||
319 | { | ||
320 | |||
321 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
322 | rp->b_cnt -= size; | ||
323 | if (rp->b_in < size) | ||
324 | rp->b_in += rp->b_size; | ||
325 | rp->b_in -= size; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * This has to be called under both b_lock and fetch_lock, because | ||
330 | * it accesses both b_cnt and b_out. | ||
331 | */ | ||
332 | static void mon_buff_area_free(struct mon_reader_bin *rp, unsigned int size) | ||
333 | { | ||
334 | |||
335 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
336 | rp->b_cnt -= size; | ||
337 | if ((rp->b_out += size) >= rp->b_size) | ||
338 | rp->b_out -= rp->b_size; | ||
339 | } | ||
340 | |||
341 | static void mon_buff_area_fill(const struct mon_reader_bin *rp, | ||
342 | unsigned int offset, unsigned int size) | ||
343 | { | ||
344 | struct mon_bin_hdr *ep; | ||
345 | |||
346 | ep = MON_OFF2HDR(rp, offset); | ||
347 | memset(ep, 0, PKT_SIZE); | ||
348 | ep->type = '@'; | ||
349 | ep->len_cap = size - PKT_SIZE; | ||
350 | } | ||
351 | |||
352 | static inline char mon_bin_get_setup(unsigned char *setupb, | ||
353 | const struct urb *urb, char ev_type) | ||
354 | { | ||
355 | |||
356 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | ||
357 | return '-'; | ||
358 | |||
359 | if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) | ||
360 | return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); | ||
361 | if (urb->setup_packet == NULL) | ||
362 | return 'Z'; | ||
363 | |||
364 | memcpy(setupb, urb->setup_packet, SETUP_LEN); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static char mon_bin_get_data(const struct mon_reader_bin *rp, | ||
369 | unsigned int offset, struct urb *urb, unsigned int length) | ||
370 | { | ||
371 | |||
372 | if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) { | ||
373 | mon_dmapeek_vec(rp, offset, urb->transfer_dma, length); | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | if (urb->transfer_buffer == NULL) | ||
378 | return 'Z'; | ||
379 | |||
380 | mon_copy_to_buff(rp, offset, urb->transfer_buffer, length); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | ||
385 | char ev_type) | ||
386 | { | ||
387 | unsigned long flags; | ||
388 | struct timeval ts; | ||
389 | unsigned int urb_length; | ||
390 | unsigned int offset; | ||
391 | unsigned int length; | ||
392 | struct mon_bin_hdr *ep; | ||
393 | char data_tag = 0; | ||
394 | |||
395 | do_gettimeofday(&ts); | ||
396 | |||
397 | spin_lock_irqsave(&rp->b_lock, flags); | ||
398 | |||
399 | /* | ||
400 | * Find the maximum allowable length, then allocate space. | ||
401 | */ | ||
402 | urb_length = (ev_type == 'S') ? | ||
403 | urb->transfer_buffer_length : urb->actual_length; | ||
404 | length = urb_length; | ||
405 | |||
406 | if (length >= rp->b_size/5) | ||
407 | length = rp->b_size/5; | ||
408 | |||
409 | if (usb_pipein(urb->pipe)) { | ||
410 | if (ev_type == 'S') { | ||
411 | length = 0; | ||
412 | data_tag = '<'; | ||
413 | } | ||
414 | } else { | ||
415 | if (ev_type == 'C') { | ||
416 | length = 0; | ||
417 | data_tag = '>'; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | if (rp->mmap_active) | ||
422 | offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE); | ||
423 | else | ||
424 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE); | ||
425 | if (offset == ~0) { | ||
426 | rp->cnt_lost++; | ||
427 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
428 | return; | ||
429 | } | ||
430 | |||
431 | ep = MON_OFF2HDR(rp, offset); | ||
432 | if ((offset += PKT_SIZE) >= rp->b_size) offset = 0; | ||
433 | |||
434 | /* | ||
435 | * Fill the allocated area. | ||
436 | */ | ||
437 | memset(ep, 0, PKT_SIZE); | ||
438 | ep->type = ev_type; | ||
439 | ep->xfer_type = usb_pipetype(urb->pipe); | ||
440 | /* We use the fact that usb_pipein() returns 0x80 */ | ||
441 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | ||
442 | ep->devnum = usb_pipedevice(urb->pipe); | ||
443 | ep->busnum = rp->r.m_bus->u_bus->busnum; | ||
444 | ep->id = (unsigned long) urb; | ||
445 | ep->ts_sec = ts.tv_sec; | ||
446 | ep->ts_usec = ts.tv_usec; | ||
447 | ep->status = urb->status; | ||
448 | ep->len_urb = urb_length; | ||
449 | ep->len_cap = length; | ||
450 | |||
451 | ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); | ||
452 | if (length != 0) { | ||
453 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | ||
454 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | ||
455 | ep->len_cap = 0; | ||
456 | mon_buff_area_shrink(rp, length); | ||
457 | } | ||
458 | } else { | ||
459 | ep->flag_data = data_tag; | ||
460 | } | ||
461 | |||
462 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
463 | |||
464 | wake_up(&rp->b_wait); | ||
465 | } | ||
466 | |||
467 | static void mon_bin_submit(void *data, struct urb *urb) | ||
468 | { | ||
469 | struct mon_reader_bin *rp = data; | ||
470 | mon_bin_event(rp, urb, 'S'); | ||
471 | } | ||
472 | |||
473 | static void mon_bin_complete(void *data, struct urb *urb) | ||
474 | { | ||
475 | struct mon_reader_bin *rp = data; | ||
476 | mon_bin_event(rp, urb, 'C'); | ||
477 | } | ||
478 | |||
479 | static void mon_bin_error(void *data, struct urb *urb, int error) | ||
480 | { | ||
481 | struct mon_reader_bin *rp = data; | ||
482 | unsigned long flags; | ||
483 | unsigned int offset; | ||
484 | struct mon_bin_hdr *ep; | ||
485 | |||
486 | spin_lock_irqsave(&rp->b_lock, flags); | ||
487 | |||
488 | offset = mon_buff_area_alloc(rp, PKT_SIZE); | ||
489 | if (offset == ~0) { | ||
490 | /* Not incrementing cnt_lost. Just because. */ | ||
491 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
492 | return; | ||
493 | } | ||
494 | |||
495 | ep = MON_OFF2HDR(rp, offset); | ||
496 | |||
497 | memset(ep, 0, PKT_SIZE); | ||
498 | ep->type = 'E'; | ||
499 | ep->xfer_type = usb_pipetype(urb->pipe); | ||
500 | /* We use the fact that usb_pipein() returns 0x80 */ | ||
501 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | ||
502 | ep->devnum = usb_pipedevice(urb->pipe); | ||
503 | ep->busnum = rp->r.m_bus->u_bus->busnum; | ||
504 | ep->id = (unsigned long) urb; | ||
505 | ep->status = error; | ||
506 | |||
507 | ep->flag_setup = '-'; | ||
508 | ep->flag_data = 'E'; | ||
509 | |||
510 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
511 | |||
512 | wake_up(&rp->b_wait); | ||
513 | } | ||
514 | |||
515 | static int mon_bin_open(struct inode *inode, struct file *file) | ||
516 | { | ||
517 | struct mon_bus *mbus; | ||
518 | struct usb_bus *ubus; | ||
519 | struct mon_reader_bin *rp; | ||
520 | size_t size; | ||
521 | int rc; | ||
522 | |||
523 | mutex_lock(&mon_lock); | ||
524 | if ((mbus = mon_bus_lookup(iminor(inode))) == NULL) { | ||
525 | mutex_unlock(&mon_lock); | ||
526 | return -ENODEV; | ||
527 | } | ||
528 | if ((ubus = mbus->u_bus) == NULL) { | ||
529 | printk(KERN_ERR TAG ": consistency error on open\n"); | ||
530 | mutex_unlock(&mon_lock); | ||
531 | return -ENODEV; | ||
532 | } | ||
533 | |||
534 | rp = kzalloc(sizeof(struct mon_reader_bin), GFP_KERNEL); | ||
535 | if (rp == NULL) { | ||
536 | rc = -ENOMEM; | ||
537 | goto err_alloc; | ||
538 | } | ||
539 | spin_lock_init(&rp->b_lock); | ||
540 | init_waitqueue_head(&rp->b_wait); | ||
541 | mutex_init(&rp->fetch_lock); | ||
542 | |||
543 | rp->b_size = BUFF_DFL; | ||
544 | |||
545 | size = sizeof(struct mon_pgmap) * (rp->b_size/CHUNK_SIZE); | ||
546 | if ((rp->b_vec = kzalloc(size, GFP_KERNEL)) == NULL) { | ||
547 | rc = -ENOMEM; | ||
548 | goto err_allocvec; | ||
549 | } | ||
550 | |||
551 | if ((rc = mon_alloc_buff(rp->b_vec, rp->b_size/CHUNK_SIZE)) < 0) | ||
552 | goto err_allocbuff; | ||
553 | |||
554 | rp->r.m_bus = mbus; | ||
555 | rp->r.r_data = rp; | ||
556 | rp->r.rnf_submit = mon_bin_submit; | ||
557 | rp->r.rnf_error = mon_bin_error; | ||
558 | rp->r.rnf_complete = mon_bin_complete; | ||
559 | |||
560 | mon_reader_add(mbus, &rp->r); | ||
561 | |||
562 | file->private_data = rp; | ||
563 | mutex_unlock(&mon_lock); | ||
564 | return 0; | ||
565 | |||
566 | err_allocbuff: | ||
567 | kfree(rp->b_vec); | ||
568 | err_allocvec: | ||
569 | kfree(rp); | ||
570 | err_alloc: | ||
571 | mutex_unlock(&mon_lock); | ||
572 | return rc; | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * Extract an event from buffer and copy it to user space. | ||
577 | * Wait if there is no event ready. | ||
578 | * Returns zero or error. | ||
579 | */ | ||
580 | static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | ||
581 | struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes) | ||
582 | { | ||
583 | unsigned long flags; | ||
584 | struct mon_bin_hdr *ep; | ||
585 | size_t step_len; | ||
586 | unsigned int offset; | ||
587 | int rc; | ||
588 | |||
589 | mutex_lock(&rp->fetch_lock); | ||
590 | |||
591 | if ((rc = mon_bin_wait_event(file, rp)) < 0) { | ||
592 | mutex_unlock(&rp->fetch_lock); | ||
593 | return rc; | ||
594 | } | ||
595 | |||
596 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
597 | |||
598 | if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) { | ||
599 | mutex_unlock(&rp->fetch_lock); | ||
600 | return -EFAULT; | ||
601 | } | ||
602 | |||
603 | step_len = min(ep->len_cap, nbytes); | ||
604 | if ((offset = rp->b_out + PKT_SIZE) >= rp->b_size) offset = 0; | ||
605 | |||
606 | if (copy_from_buf(rp, offset, data, step_len)) { | ||
607 | mutex_unlock(&rp->fetch_lock); | ||
608 | return -EFAULT; | ||
609 | } | ||
610 | |||
611 | spin_lock_irqsave(&rp->b_lock, flags); | ||
612 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | ||
613 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
614 | rp->b_read = 0; | ||
615 | |||
616 | mutex_unlock(&rp->fetch_lock); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static int mon_bin_release(struct inode *inode, struct file *file) | ||
621 | { | ||
622 | struct mon_reader_bin *rp = file->private_data; | ||
623 | struct mon_bus* mbus = rp->r.m_bus; | ||
624 | |||
625 | mutex_lock(&mon_lock); | ||
626 | |||
627 | if (mbus->nreaders <= 0) { | ||
628 | printk(KERN_ERR TAG ": consistency error on close\n"); | ||
629 | mutex_unlock(&mon_lock); | ||
630 | return 0; | ||
631 | } | ||
632 | mon_reader_del(mbus, &rp->r); | ||
633 | |||
634 | mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); | ||
635 | kfree(rp->b_vec); | ||
636 | kfree(rp); | ||
637 | |||
638 | mutex_unlock(&mon_lock); | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | static ssize_t mon_bin_read(struct file *file, char __user *buf, | ||
643 | size_t nbytes, loff_t *ppos) | ||
644 | { | ||
645 | struct mon_reader_bin *rp = file->private_data; | ||
646 | unsigned long flags; | ||
647 | struct mon_bin_hdr *ep; | ||
648 | unsigned int offset; | ||
649 | size_t step_len; | ||
650 | char *ptr; | ||
651 | ssize_t done = 0; | ||
652 | int rc; | ||
653 | |||
654 | mutex_lock(&rp->fetch_lock); | ||
655 | |||
656 | if ((rc = mon_bin_wait_event(file, rp)) < 0) { | ||
657 | mutex_unlock(&rp->fetch_lock); | ||
658 | return rc; | ||
659 | } | ||
660 | |||
661 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
662 | |||
663 | if (rp->b_read < sizeof(struct mon_bin_hdr)) { | ||
664 | step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read); | ||
665 | ptr = ((char *)ep) + rp->b_read; | ||
666 | if (step_len && copy_to_user(buf, ptr, step_len)) { | ||
667 | mutex_unlock(&rp->fetch_lock); | ||
668 | return -EFAULT; | ||
669 | } | ||
670 | nbytes -= step_len; | ||
671 | buf += step_len; | ||
672 | rp->b_read += step_len; | ||
673 | done += step_len; | ||
674 | } | ||
675 | |||
676 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { | ||
677 | step_len = min(nbytes, (size_t)ep->len_cap); | ||
678 | offset = rp->b_out + PKT_SIZE; | ||
679 | offset += rp->b_read - sizeof(struct mon_bin_hdr); | ||
680 | if (offset >= rp->b_size) | ||
681 | offset -= rp->b_size; | ||
682 | if (copy_from_buf(rp, offset, buf, step_len)) { | ||
683 | mutex_unlock(&rp->fetch_lock); | ||
684 | return -EFAULT; | ||
685 | } | ||
686 | nbytes -= step_len; | ||
687 | buf += step_len; | ||
688 | rp->b_read += step_len; | ||
689 | done += step_len; | ||
690 | } | ||
691 | |||
692 | /* | ||
693 | * Check if whole packet was read, and if so, jump to the next one. | ||
694 | */ | ||
695 | if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) { | ||
696 | spin_lock_irqsave(&rp->b_lock, flags); | ||
697 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | ||
698 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
699 | rp->b_read = 0; | ||
700 | } | ||
701 | |||
702 | mutex_unlock(&rp->fetch_lock); | ||
703 | return done; | ||
704 | } | ||
705 | |||
706 | /* | ||
707 | * Remove at most nevents from chunked buffer. | ||
708 | * Returns the number of removed events. | ||
709 | */ | ||
710 | static int mon_bin_flush(struct mon_reader_bin *rp, unsigned nevents) | ||
711 | { | ||
712 | unsigned long flags; | ||
713 | struct mon_bin_hdr *ep; | ||
714 | int i; | ||
715 | |||
716 | mutex_lock(&rp->fetch_lock); | ||
717 | spin_lock_irqsave(&rp->b_lock, flags); | ||
718 | for (i = 0; i < nevents; ++i) { | ||
719 | if (MON_RING_EMPTY(rp)) | ||
720 | break; | ||
721 | |||
722 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
723 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | ||
724 | } | ||
725 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
726 | rp->b_read = 0; | ||
727 | mutex_unlock(&rp->fetch_lock); | ||
728 | return i; | ||
729 | } | ||
730 | |||
731 | /* | ||
732 | * Fetch at most max event offsets into the buffer and put them into vec. | ||
733 | * The events are usually freed later with mon_bin_flush. | ||
734 | * Return the effective number of events fetched. | ||
735 | */ | ||
736 | static int mon_bin_fetch(struct file *file, struct mon_reader_bin *rp, | ||
737 | u32 __user *vec, unsigned int max) | ||
738 | { | ||
739 | unsigned int cur_out; | ||
740 | unsigned int bytes, avail; | ||
741 | unsigned int size; | ||
742 | unsigned int nevents; | ||
743 | struct mon_bin_hdr *ep; | ||
744 | unsigned long flags; | ||
745 | int rc; | ||
746 | |||
747 | mutex_lock(&rp->fetch_lock); | ||
748 | |||
749 | if ((rc = mon_bin_wait_event(file, rp)) < 0) { | ||
750 | mutex_unlock(&rp->fetch_lock); | ||
751 | return rc; | ||
752 | } | ||
753 | |||
754 | spin_lock_irqsave(&rp->b_lock, flags); | ||
755 | avail = rp->b_cnt; | ||
756 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
757 | |||
758 | cur_out = rp->b_out; | ||
759 | nevents = 0; | ||
760 | bytes = 0; | ||
761 | while (bytes < avail) { | ||
762 | if (nevents >= max) | ||
763 | break; | ||
764 | |||
765 | ep = MON_OFF2HDR(rp, cur_out); | ||
766 | if (put_user(cur_out, &vec[nevents])) { | ||
767 | mutex_unlock(&rp->fetch_lock); | ||
768 | return -EFAULT; | ||
769 | } | ||
770 | |||
771 | nevents++; | ||
772 | size = ep->len_cap + PKT_SIZE; | ||
773 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
774 | if ((cur_out += size) >= rp->b_size) | ||
775 | cur_out -= rp->b_size; | ||
776 | bytes += size; | ||
777 | } | ||
778 | |||
779 | mutex_unlock(&rp->fetch_lock); | ||
780 | return nevents; | ||
781 | } | ||
782 | |||
783 | /* | ||
784 | * Count events. This is almost the same as the above mon_bin_fetch, | ||
785 | * only we do not store offsets into user vector, and we have no limit. | ||
786 | */ | ||
787 | static int mon_bin_queued(struct mon_reader_bin *rp) | ||
788 | { | ||
789 | unsigned int cur_out; | ||
790 | unsigned int bytes, avail; | ||
791 | unsigned int size; | ||
792 | unsigned int nevents; | ||
793 | struct mon_bin_hdr *ep; | ||
794 | unsigned long flags; | ||
795 | |||
796 | mutex_lock(&rp->fetch_lock); | ||
797 | |||
798 | spin_lock_irqsave(&rp->b_lock, flags); | ||
799 | avail = rp->b_cnt; | ||
800 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
801 | |||
802 | cur_out = rp->b_out; | ||
803 | nevents = 0; | ||
804 | bytes = 0; | ||
805 | while (bytes < avail) { | ||
806 | ep = MON_OFF2HDR(rp, cur_out); | ||
807 | |||
808 | nevents++; | ||
809 | size = ep->len_cap + PKT_SIZE; | ||
810 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
811 | if ((cur_out += size) >= rp->b_size) | ||
812 | cur_out -= rp->b_size; | ||
813 | bytes += size; | ||
814 | } | ||
815 | |||
816 | mutex_unlock(&rp->fetch_lock); | ||
817 | return nevents; | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | */ | ||
822 | static int mon_bin_ioctl(struct inode *inode, struct file *file, | ||
823 | unsigned int cmd, unsigned long arg) | ||
824 | { | ||
825 | struct mon_reader_bin *rp = file->private_data; | ||
826 | // struct mon_bus* mbus = rp->r.m_bus; | ||
827 | int ret = 0; | ||
828 | struct mon_bin_hdr *ep; | ||
829 | unsigned long flags; | ||
830 | |||
831 | switch (cmd) { | ||
832 | |||
833 | case MON_IOCQ_URB_LEN: | ||
834 | /* | ||
835 | * N.B. This only returns the size of data, without the header. | ||
836 | */ | ||
837 | spin_lock_irqsave(&rp->b_lock, flags); | ||
838 | if (!MON_RING_EMPTY(rp)) { | ||
839 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
840 | ret = ep->len_cap; | ||
841 | } | ||
842 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
843 | break; | ||
844 | |||
845 | case MON_IOCQ_RING_SIZE: | ||
846 | ret = rp->b_size; | ||
847 | break; | ||
848 | |||
849 | case MON_IOCT_RING_SIZE: | ||
850 | /* | ||
851 | * Changing the buffer size will flush it's contents; the new | ||
852 | * buffer is allocated before releasing the old one to be sure | ||
853 | * the device will stay functional also in case of memory | ||
854 | * pressure. | ||
855 | */ | ||
856 | { | ||
857 | int size; | ||
858 | struct mon_pgmap *vec; | ||
859 | |||
860 | if (arg < BUFF_MIN || arg > BUFF_MAX) | ||
861 | return -EINVAL; | ||
862 | |||
863 | size = CHUNK_ALIGN(arg); | ||
864 | if ((vec = kzalloc(sizeof(struct mon_pgmap) * (size/CHUNK_SIZE), | ||
865 | GFP_KERNEL)) == NULL) { | ||
866 | ret = -ENOMEM; | ||
867 | break; | ||
868 | } | ||
869 | |||
870 | ret = mon_alloc_buff(vec, size/CHUNK_SIZE); | ||
871 | if (ret < 0) { | ||
872 | kfree(vec); | ||
873 | break; | ||
874 | } | ||
875 | |||
876 | mutex_lock(&rp->fetch_lock); | ||
877 | spin_lock_irqsave(&rp->b_lock, flags); | ||
878 | mon_free_buff(rp->b_vec, size/CHUNK_SIZE); | ||
879 | kfree(rp->b_vec); | ||
880 | rp->b_vec = vec; | ||
881 | rp->b_size = size; | ||
882 | rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; | ||
883 | rp->cnt_lost = 0; | ||
884 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
885 | mutex_unlock(&rp->fetch_lock); | ||
886 | } | ||
887 | break; | ||
888 | |||
889 | case MON_IOCH_MFLUSH: | ||
890 | ret = mon_bin_flush(rp, arg); | ||
891 | break; | ||
892 | |||
893 | case MON_IOCX_GET: | ||
894 | { | ||
895 | struct mon_bin_get getb; | ||
896 | |||
897 | if (copy_from_user(&getb, (void __user *)arg, | ||
898 | sizeof(struct mon_bin_get))) | ||
899 | return -EFAULT; | ||
900 | |||
901 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ | ||
902 | return -EINVAL; | ||
903 | ret = mon_bin_get_event(file, rp, | ||
904 | getb.hdr, getb.data, (unsigned int)getb.alloc); | ||
905 | } | ||
906 | break; | ||
907 | |||
908 | #ifdef CONFIG_COMPAT | ||
909 | case MON_IOCX_GET32: { | ||
910 | struct mon_bin_get32 getb; | ||
911 | |||
912 | if (copy_from_user(&getb, (void __user *)arg, | ||
913 | sizeof(struct mon_bin_get32))) | ||
914 | return -EFAULT; | ||
915 | |||
916 | ret = mon_bin_get_event(file, rp, | ||
917 | compat_ptr(getb.hdr32), compat_ptr(getb.data32), | ||
918 | getb.alloc32); | ||
919 | } | ||
920 | break; | ||
921 | #endif | ||
922 | |||
923 | case MON_IOCX_MFETCH: | ||
924 | { | ||
925 | struct mon_bin_mfetch mfetch; | ||
926 | struct mon_bin_mfetch __user *uptr; | ||
927 | |||
928 | uptr = (struct mon_bin_mfetch __user *)arg; | ||
929 | |||
930 | if (copy_from_user(&mfetch, uptr, sizeof(mfetch))) | ||
931 | return -EFAULT; | ||
932 | |||
933 | if (mfetch.nflush) { | ||
934 | ret = mon_bin_flush(rp, mfetch.nflush); | ||
935 | if (ret < 0) | ||
936 | return ret; | ||
937 | if (put_user(ret, &uptr->nflush)) | ||
938 | return -EFAULT; | ||
939 | } | ||
940 | ret = mon_bin_fetch(file, rp, mfetch.offvec, mfetch.nfetch); | ||
941 | if (ret < 0) | ||
942 | return ret; | ||
943 | if (put_user(ret, &uptr->nfetch)) | ||
944 | return -EFAULT; | ||
945 | ret = 0; | ||
946 | } | ||
947 | break; | ||
948 | |||
949 | #ifdef CONFIG_COMPAT | ||
950 | case MON_IOCX_MFETCH32: | ||
951 | { | ||
952 | struct mon_bin_mfetch32 mfetch; | ||
953 | struct mon_bin_mfetch32 __user *uptr; | ||
954 | |||
955 | uptr = (struct mon_bin_mfetch32 __user *) compat_ptr(arg); | ||
956 | |||
957 | if (copy_from_user(&mfetch, uptr, sizeof(mfetch))) | ||
958 | return -EFAULT; | ||
959 | |||
960 | if (mfetch.nflush32) { | ||
961 | ret = mon_bin_flush(rp, mfetch.nflush32); | ||
962 | if (ret < 0) | ||
963 | return ret; | ||
964 | if (put_user(ret, &uptr->nflush32)) | ||
965 | return -EFAULT; | ||
966 | } | ||
967 | ret = mon_bin_fetch(file, rp, compat_ptr(mfetch.offvec32), | ||
968 | mfetch.nfetch32); | ||
969 | if (ret < 0) | ||
970 | return ret; | ||
971 | if (put_user(ret, &uptr->nfetch32)) | ||
972 | return -EFAULT; | ||
973 | ret = 0; | ||
974 | } | ||
975 | break; | ||
976 | #endif | ||
977 | |||
978 | case MON_IOCG_STATS: { | ||
979 | struct mon_bin_stats __user *sp; | ||
980 | unsigned int nevents; | ||
981 | unsigned int ndropped; | ||
982 | |||
983 | spin_lock_irqsave(&rp->b_lock, flags); | ||
984 | ndropped = rp->cnt_lost; | ||
985 | rp->cnt_lost = 0; | ||
986 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
987 | nevents = mon_bin_queued(rp); | ||
988 | |||
989 | sp = (struct mon_bin_stats __user *)arg; | ||
990 | if (put_user(rp->cnt_lost, &sp->dropped)) | ||
991 | return -EFAULT; | ||
992 | if (put_user(nevents, &sp->queued)) | ||
993 | return -EFAULT; | ||
994 | |||
995 | } | ||
996 | break; | ||
997 | |||
998 | default: | ||
999 | return -ENOTTY; | ||
1000 | } | ||
1001 | |||
1002 | return ret; | ||
1003 | } | ||
1004 | |||
1005 | static unsigned int | ||
1006 | mon_bin_poll(struct file *file, struct poll_table_struct *wait) | ||
1007 | { | ||
1008 | struct mon_reader_bin *rp = file->private_data; | ||
1009 | unsigned int mask = 0; | ||
1010 | unsigned long flags; | ||
1011 | |||
1012 | if (file->f_mode & FMODE_READ) | ||
1013 | poll_wait(file, &rp->b_wait, wait); | ||
1014 | |||
1015 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1016 | if (!MON_RING_EMPTY(rp)) | ||
1017 | mask |= POLLIN | POLLRDNORM; /* readable */ | ||
1018 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1019 | return mask; | ||
1020 | } | ||
1021 | |||
1022 | /* | ||
1023 | * open and close: just keep track of how many times the device is | ||
1024 | * mapped, to use the proper memory allocation function. | ||
1025 | */ | ||
1026 | static void mon_bin_vma_open(struct vm_area_struct *vma) | ||
1027 | { | ||
1028 | struct mon_reader_bin *rp = vma->vm_private_data; | ||
1029 | rp->mmap_active++; | ||
1030 | } | ||
1031 | |||
1032 | static void mon_bin_vma_close(struct vm_area_struct *vma) | ||
1033 | { | ||
1034 | struct mon_reader_bin *rp = vma->vm_private_data; | ||
1035 | rp->mmap_active--; | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * Map ring pages to user space. | ||
1040 | */ | ||
1041 | struct page *mon_bin_vma_nopage(struct vm_area_struct *vma, | ||
1042 | unsigned long address, int *type) | ||
1043 | { | ||
1044 | struct mon_reader_bin *rp = vma->vm_private_data; | ||
1045 | unsigned long offset, chunk_idx; | ||
1046 | struct page *pageptr; | ||
1047 | |||
1048 | offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | ||
1049 | if (offset >= rp->b_size) | ||
1050 | return NOPAGE_SIGBUS; | ||
1051 | chunk_idx = offset / CHUNK_SIZE; | ||
1052 | pageptr = rp->b_vec[chunk_idx].pg; | ||
1053 | get_page(pageptr); | ||
1054 | if (type) | ||
1055 | *type = VM_FAULT_MINOR; | ||
1056 | return pageptr; | ||
1057 | } | ||
1058 | |||
1059 | struct vm_operations_struct mon_bin_vm_ops = { | ||
1060 | .open = mon_bin_vma_open, | ||
1061 | .close = mon_bin_vma_close, | ||
1062 | .nopage = mon_bin_vma_nopage, | ||
1063 | }; | ||
1064 | |||
1065 | int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) | ||
1066 | { | ||
1067 | /* don't do anything here: "nopage" will set up page table entries */ | ||
1068 | vma->vm_ops = &mon_bin_vm_ops; | ||
1069 | vma->vm_flags |= VM_RESERVED; | ||
1070 | vma->vm_private_data = filp->private_data; | ||
1071 | mon_bin_vma_open(vma); | ||
1072 | return 0; | ||
1073 | } | ||
1074 | |||
1075 | struct file_operations mon_fops_binary = { | ||
1076 | .owner = THIS_MODULE, | ||
1077 | .open = mon_bin_open, | ||
1078 | .llseek = no_llseek, | ||
1079 | .read = mon_bin_read, | ||
1080 | /* .write = mon_text_write, */ | ||
1081 | .poll = mon_bin_poll, | ||
1082 | .ioctl = mon_bin_ioctl, | ||
1083 | .release = mon_bin_release, | ||
1084 | }; | ||
1085 | |||
1086 | static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp) | ||
1087 | { | ||
1088 | DECLARE_WAITQUEUE(waita, current); | ||
1089 | unsigned long flags; | ||
1090 | |||
1091 | add_wait_queue(&rp->b_wait, &waita); | ||
1092 | set_current_state(TASK_INTERRUPTIBLE); | ||
1093 | |||
1094 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1095 | while (MON_RING_EMPTY(rp)) { | ||
1096 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1097 | |||
1098 | if (file->f_flags & O_NONBLOCK) { | ||
1099 | set_current_state(TASK_RUNNING); | ||
1100 | remove_wait_queue(&rp->b_wait, &waita); | ||
1101 | return -EWOULDBLOCK; /* Same as EAGAIN in Linux */ | ||
1102 | } | ||
1103 | schedule(); | ||
1104 | if (signal_pending(current)) { | ||
1105 | remove_wait_queue(&rp->b_wait, &waita); | ||
1106 | return -EINTR; | ||
1107 | } | ||
1108 | set_current_state(TASK_INTERRUPTIBLE); | ||
1109 | |||
1110 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1111 | } | ||
1112 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1113 | |||
1114 | set_current_state(TASK_RUNNING); | ||
1115 | remove_wait_queue(&rp->b_wait, &waita); | ||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | static int mon_alloc_buff(struct mon_pgmap *map, int npages) | ||
1120 | { | ||
1121 | int n; | ||
1122 | unsigned long vaddr; | ||
1123 | |||
1124 | for (n = 0; n < npages; n++) { | ||
1125 | vaddr = get_zeroed_page(GFP_KERNEL); | ||
1126 | if (vaddr == 0) { | ||
1127 | while (n-- != 0) | ||
1128 | free_page((unsigned long) map[n].ptr); | ||
1129 | return -ENOMEM; | ||
1130 | } | ||
1131 | map[n].ptr = (unsigned char *) vaddr; | ||
1132 | map[n].pg = virt_to_page(vaddr); | ||
1133 | } | ||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | static void mon_free_buff(struct mon_pgmap *map, int npages) | ||
1138 | { | ||
1139 | int n; | ||
1140 | |||
1141 | for (n = 0; n < npages; n++) | ||
1142 | free_page((unsigned long) map[n].ptr); | ||
1143 | } | ||
1144 | |||
1145 | int __init mon_bin_init(void) | ||
1146 | { | ||
1147 | int rc; | ||
1148 | |||
1149 | rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon"); | ||
1150 | if (rc < 0) | ||
1151 | goto err_dev; | ||
1152 | |||
1153 | cdev_init(&mon_bin_cdev, &mon_fops_binary); | ||
1154 | mon_bin_cdev.owner = THIS_MODULE; | ||
1155 | |||
1156 | rc = cdev_add(&mon_bin_cdev, mon_bin_dev0, MON_BIN_MAX_MINOR); | ||
1157 | if (rc < 0) | ||
1158 | goto err_add; | ||
1159 | |||
1160 | return 0; | ||
1161 | |||
1162 | err_add: | ||
1163 | unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); | ||
1164 | err_dev: | ||
1165 | return rc; | ||
1166 | } | ||
1167 | |||
1168 | void __exit mon_bin_exit(void) | ||
1169 | { | ||
1170 | cdev_del(&mon_bin_cdev); | ||
1171 | unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); | ||
1172 | } | ||
diff --git a/drivers/usb/mon/mon_dma.c b/drivers/usb/mon/mon_dma.c index ddcfc01e77a0..140cc80bd2b1 100644 --- a/drivers/usb/mon/mon_dma.c +++ b/drivers/usb/mon/mon_dma.c | |||
@@ -48,6 +48,36 @@ char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len) | |||
48 | local_irq_restore(flags); | 48 | local_irq_restore(flags); |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | |||
52 | void mon_dmapeek_vec(const struct mon_reader_bin *rp, | ||
53 | unsigned int offset, dma_addr_t dma_addr, unsigned int length) | ||
54 | { | ||
55 | unsigned long flags; | ||
56 | unsigned int step_len; | ||
57 | struct page *pg; | ||
58 | unsigned char *map; | ||
59 | unsigned long page_off, page_len; | ||
60 | |||
61 | local_irq_save(flags); | ||
62 | while (length) { | ||
63 | /* compute number of bytes we are going to copy in this page */ | ||
64 | step_len = length; | ||
65 | page_off = dma_addr & (PAGE_SIZE-1); | ||
66 | page_len = PAGE_SIZE - page_off; | ||
67 | if (page_len < step_len) | ||
68 | step_len = page_len; | ||
69 | |||
70 | /* copy data and advance pointers */ | ||
71 | pg = phys_to_page(dma_addr); | ||
72 | map = kmap_atomic(pg, KM_IRQ0); | ||
73 | offset = mon_copy_to_buff(rp, offset, map + page_off, step_len); | ||
74 | kunmap_atomic(map, KM_IRQ0); | ||
75 | dma_addr += step_len; | ||
76 | length -= step_len; | ||
77 | } | ||
78 | local_irq_restore(flags); | ||
79 | } | ||
80 | |||
51 | #endif /* __i386__ */ | 81 | #endif /* __i386__ */ |
52 | 82 | ||
53 | #ifndef MON_HAS_UNMAP | 83 | #ifndef MON_HAS_UNMAP |
@@ -55,4 +85,11 @@ char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len) | |||
55 | { | 85 | { |
56 | return 'D'; | 86 | return 'D'; |
57 | } | 87 | } |
58 | #endif | 88 | |
89 | void mon_dmapeek_vec(const struct mon_reader_bin *rp, | ||
90 | unsigned int offset, dma_addr_t dma_addr, unsigned int length) | ||
91 | { | ||
92 | ; | ||
93 | } | ||
94 | |||
95 | #endif /* MON_HAS_UNMAP */ | ||
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 394bbf2f68d4..c9739e7b35e5 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
12 | #include <linux/debugfs.h> | ||
13 | #include <linux/smp_lock.h> | 12 | #include <linux/smp_lock.h> |
14 | #include <linux/notifier.h> | 13 | #include <linux/notifier.h> |
15 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
@@ -22,11 +21,10 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb); | |||
22 | static void mon_stop(struct mon_bus *mbus); | 21 | static void mon_stop(struct mon_bus *mbus); |
23 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); | 22 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); |
24 | static void mon_bus_drop(struct kref *r); | 23 | static void mon_bus_drop(struct kref *r); |
25 | static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus); | 24 | static void mon_bus_init(struct usb_bus *ubus); |
26 | 25 | ||
27 | DEFINE_MUTEX(mon_lock); | 26 | DEFINE_MUTEX(mon_lock); |
28 | 27 | ||
29 | static struct dentry *mon_dir; /* /dbg/usbmon */ | ||
30 | static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ | 28 | static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ |
31 | 29 | ||
32 | /* | 30 | /* |
@@ -200,7 +198,7 @@ static void mon_stop(struct mon_bus *mbus) | |||
200 | */ | 198 | */ |
201 | static void mon_bus_add(struct usb_bus *ubus) | 199 | static void mon_bus_add(struct usb_bus *ubus) |
202 | { | 200 | { |
203 | mon_bus_init(mon_dir, ubus); | 201 | mon_bus_init(ubus); |
204 | } | 202 | } |
205 | 203 | ||
206 | /* | 204 | /* |
@@ -212,8 +210,8 @@ static void mon_bus_remove(struct usb_bus *ubus) | |||
212 | 210 | ||
213 | mutex_lock(&mon_lock); | 211 | mutex_lock(&mon_lock); |
214 | list_del(&mbus->bus_link); | 212 | list_del(&mbus->bus_link); |
215 | debugfs_remove(mbus->dent_t); | 213 | if (mbus->text_inited) |
216 | debugfs_remove(mbus->dent_s); | 214 | mon_text_del(mbus); |
217 | 215 | ||
218 | mon_dissolve(mbus, ubus); | 216 | mon_dissolve(mbus, ubus); |
219 | kref_put(&mbus->ref, mon_bus_drop); | 217 | kref_put(&mbus->ref, mon_bus_drop); |
@@ -281,13 +279,9 @@ static void mon_bus_drop(struct kref *r) | |||
281 | * - refcount USB bus struct | 279 | * - refcount USB bus struct |
282 | * - link | 280 | * - link |
283 | */ | 281 | */ |
284 | static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) | 282 | static void mon_bus_init(struct usb_bus *ubus) |
285 | { | 283 | { |
286 | struct dentry *d; | ||
287 | struct mon_bus *mbus; | 284 | struct mon_bus *mbus; |
288 | enum { NAMESZ = 10 }; | ||
289 | char name[NAMESZ]; | ||
290 | int rc; | ||
291 | 285 | ||
292 | if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) | 286 | if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) |
293 | goto err_alloc; | 287 | goto err_alloc; |
@@ -303,57 +297,54 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) | |||
303 | ubus->mon_bus = mbus; | 297 | ubus->mon_bus = mbus; |
304 | mbus->uses_dma = ubus->uses_dma; | 298 | mbus->uses_dma = ubus->uses_dma; |
305 | 299 | ||
306 | rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); | 300 | mbus->text_inited = mon_text_add(mbus, ubus); |
307 | if (rc <= 0 || rc >= NAMESZ) | 301 | // mon_bin_add(...) |
308 | goto err_print_t; | ||
309 | d = debugfs_create_file(name, 0600, mondir, mbus, &mon_fops_text); | ||
310 | if (d == NULL) | ||
311 | goto err_create_t; | ||
312 | mbus->dent_t = d; | ||
313 | |||
314 | rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); | ||
315 | if (rc <= 0 || rc >= NAMESZ) | ||
316 | goto err_print_s; | ||
317 | d = debugfs_create_file(name, 0600, mondir, mbus, &mon_fops_stat); | ||
318 | if (d == NULL) | ||
319 | goto err_create_s; | ||
320 | mbus->dent_s = d; | ||
321 | 302 | ||
322 | mutex_lock(&mon_lock); | 303 | mutex_lock(&mon_lock); |
323 | list_add_tail(&mbus->bus_link, &mon_buses); | 304 | list_add_tail(&mbus->bus_link, &mon_buses); |
324 | mutex_unlock(&mon_lock); | 305 | mutex_unlock(&mon_lock); |
325 | return; | 306 | return; |
326 | 307 | ||
327 | err_create_s: | ||
328 | err_print_s: | ||
329 | debugfs_remove(mbus->dent_t); | ||
330 | err_create_t: | ||
331 | err_print_t: | ||
332 | kfree(mbus); | ||
333 | err_alloc: | 308 | err_alloc: |
334 | return; | 309 | return; |
335 | } | 310 | } |
336 | 311 | ||
312 | /* | ||
313 | * Search a USB bus by number. Notice that USB bus numbers start from one, | ||
314 | * which we may later use to identify "all" with zero. | ||
315 | * | ||
316 | * This function must be called with mon_lock held. | ||
317 | * | ||
318 | * This is obviously inefficient and may be revised in the future. | ||
319 | */ | ||
320 | struct mon_bus *mon_bus_lookup(unsigned int num) | ||
321 | { | ||
322 | struct list_head *p; | ||
323 | struct mon_bus *mbus; | ||
324 | |||
325 | list_for_each (p, &mon_buses) { | ||
326 | mbus = list_entry(p, struct mon_bus, bus_link); | ||
327 | if (mbus->u_bus->busnum == num) { | ||
328 | return mbus; | ||
329 | } | ||
330 | } | ||
331 | return NULL; | ||
332 | } | ||
333 | |||
337 | static int __init mon_init(void) | 334 | static int __init mon_init(void) |
338 | { | 335 | { |
339 | struct usb_bus *ubus; | 336 | struct usb_bus *ubus; |
340 | struct dentry *mondir; | 337 | int rc; |
341 | 338 | ||
342 | mondir = debugfs_create_dir("usbmon", NULL); | 339 | if ((rc = mon_text_init()) != 0) |
343 | if (IS_ERR(mondir)) { | 340 | goto err_text; |
344 | printk(KERN_NOTICE TAG ": debugfs is not available\n"); | 341 | if ((rc = mon_bin_init()) != 0) |
345 | return -ENODEV; | 342 | goto err_bin; |
346 | } | ||
347 | if (mondir == NULL) { | ||
348 | printk(KERN_NOTICE TAG ": unable to create usbmon directory\n"); | ||
349 | return -ENODEV; | ||
350 | } | ||
351 | mon_dir = mondir; | ||
352 | 343 | ||
353 | if (usb_mon_register(&mon_ops_0) != 0) { | 344 | if (usb_mon_register(&mon_ops_0) != 0) { |
354 | printk(KERN_NOTICE TAG ": unable to register with the core\n"); | 345 | printk(KERN_NOTICE TAG ": unable to register with the core\n"); |
355 | debugfs_remove(mondir); | 346 | rc = -ENODEV; |
356 | return -ENODEV; | 347 | goto err_reg; |
357 | } | 348 | } |
358 | // MOD_INC_USE_COUNT(which_module?); | 349 | // MOD_INC_USE_COUNT(which_module?); |
359 | 350 | ||
@@ -361,10 +352,17 @@ static int __init mon_init(void) | |||
361 | 352 | ||
362 | mutex_lock(&usb_bus_list_lock); | 353 | mutex_lock(&usb_bus_list_lock); |
363 | list_for_each_entry (ubus, &usb_bus_list, bus_list) { | 354 | list_for_each_entry (ubus, &usb_bus_list, bus_list) { |
364 | mon_bus_init(mondir, ubus); | 355 | mon_bus_init(ubus); |
365 | } | 356 | } |
366 | mutex_unlock(&usb_bus_list_lock); | 357 | mutex_unlock(&usb_bus_list_lock); |
367 | return 0; | 358 | return 0; |
359 | |||
360 | err_reg: | ||
361 | mon_bin_exit(); | ||
362 | err_bin: | ||
363 | mon_text_exit(); | ||
364 | err_text: | ||
365 | return rc; | ||
368 | } | 366 | } |
369 | 367 | ||
370 | static void __exit mon_exit(void) | 368 | static void __exit mon_exit(void) |
@@ -381,8 +379,8 @@ static void __exit mon_exit(void) | |||
381 | mbus = list_entry(p, struct mon_bus, bus_link); | 379 | mbus = list_entry(p, struct mon_bus, bus_link); |
382 | list_del(p); | 380 | list_del(p); |
383 | 381 | ||
384 | debugfs_remove(mbus->dent_t); | 382 | if (mbus->text_inited) |
385 | debugfs_remove(mbus->dent_s); | 383 | mon_text_del(mbus); |
386 | 384 | ||
387 | /* | 385 | /* |
388 | * This never happens, because the open/close paths in | 386 | * This never happens, because the open/close paths in |
@@ -401,7 +399,8 @@ static void __exit mon_exit(void) | |||
401 | } | 399 | } |
402 | mutex_unlock(&mon_lock); | 400 | mutex_unlock(&mon_lock); |
403 | 401 | ||
404 | debugfs_remove(mon_dir); | 402 | mon_text_exit(); |
403 | mon_bin_exit(); | ||
405 | } | 404 | } |
406 | 405 | ||
407 | module_init(mon_init); | 406 | module_init(mon_init); |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 05cf2c9a8f84..d38a1279d9d9 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/usb.h> | 9 | #include <linux/usb.h> |
10 | #include <linux/time.h> | 10 | #include <linux/time.h> |
11 | #include <linux/mutex.h> | 11 | #include <linux/mutex.h> |
12 | #include <linux/debugfs.h> | ||
12 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
13 | 14 | ||
14 | #include "usb_mon.h" | 15 | #include "usb_mon.h" |
@@ -63,6 +64,8 @@ struct mon_reader_text { | |||
63 | char slab_name[SLAB_NAME_SZ]; | 64 | char slab_name[SLAB_NAME_SZ]; |
64 | }; | 65 | }; |
65 | 66 | ||
67 | static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */ | ||
68 | |||
66 | static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); | 69 | static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); |
67 | 70 | ||
68 | /* | 71 | /* |
@@ -436,7 +439,7 @@ static int mon_text_release(struct inode *inode, struct file *file) | |||
436 | return 0; | 439 | return 0; |
437 | } | 440 | } |
438 | 441 | ||
439 | const struct file_operations mon_fops_text = { | 442 | static const struct file_operations mon_fops_text = { |
440 | .owner = THIS_MODULE, | 443 | .owner = THIS_MODULE, |
441 | .open = mon_text_open, | 444 | .open = mon_text_open, |
442 | .llseek = no_llseek, | 445 | .llseek = no_llseek, |
@@ -447,6 +450,47 @@ const struct file_operations mon_fops_text = { | |||
447 | .release = mon_text_release, | 450 | .release = mon_text_release, |
448 | }; | 451 | }; |
449 | 452 | ||
453 | int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) | ||
454 | { | ||
455 | struct dentry *d; | ||
456 | enum { NAMESZ = 10 }; | ||
457 | char name[NAMESZ]; | ||
458 | int rc; | ||
459 | |||
460 | rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); | ||
461 | if (rc <= 0 || rc >= NAMESZ) | ||
462 | goto err_print_t; | ||
463 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text); | ||
464 | if (d == NULL) | ||
465 | goto err_create_t; | ||
466 | mbus->dent_t = d; | ||
467 | |||
468 | /* XXX The stats do not belong to here (text API), but oh well... */ | ||
469 | rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); | ||
470 | if (rc <= 0 || rc >= NAMESZ) | ||
471 | goto err_print_s; | ||
472 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); | ||
473 | if (d == NULL) | ||
474 | goto err_create_s; | ||
475 | mbus->dent_s = d; | ||
476 | |||
477 | return 1; | ||
478 | |||
479 | err_create_s: | ||
480 | err_print_s: | ||
481 | debugfs_remove(mbus->dent_t); | ||
482 | mbus->dent_t = NULL; | ||
483 | err_create_t: | ||
484 | err_print_t: | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | void mon_text_del(struct mon_bus *mbus) | ||
489 | { | ||
490 | debugfs_remove(mbus->dent_t); | ||
491 | debugfs_remove(mbus->dent_s); | ||
492 | } | ||
493 | |||
450 | /* | 494 | /* |
451 | * Slab interface: constructor. | 495 | * Slab interface: constructor. |
452 | */ | 496 | */ |
@@ -459,3 +503,24 @@ static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sfla | |||
459 | memset(mem, 0xe5, sizeof(struct mon_event_text)); | 503 | memset(mem, 0xe5, sizeof(struct mon_event_text)); |
460 | } | 504 | } |
461 | 505 | ||
506 | int __init mon_text_init(void) | ||
507 | { | ||
508 | struct dentry *mondir; | ||
509 | |||
510 | mondir = debugfs_create_dir("usbmon", NULL); | ||
511 | if (IS_ERR(mondir)) { | ||
512 | printk(KERN_NOTICE TAG ": debugfs is not available\n"); | ||
513 | return -ENODEV; | ||
514 | } | ||
515 | if (mondir == NULL) { | ||
516 | printk(KERN_NOTICE TAG ": unable to create usbmon directory\n"); | ||
517 | return -ENODEV; | ||
518 | } | ||
519 | mon_dir = mondir; | ||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | void __exit mon_text_exit(void) | ||
524 | { | ||
525 | debugfs_remove(mon_dir); | ||
526 | } | ||
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index ab9d02d5df77..4f949ce8a7f3 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h | |||
@@ -17,9 +17,11 @@ | |||
17 | struct mon_bus { | 17 | struct mon_bus { |
18 | struct list_head bus_link; | 18 | struct list_head bus_link; |
19 | spinlock_t lock; | 19 | spinlock_t lock; |
20 | struct usb_bus *u_bus; | ||
21 | |||
22 | int text_inited; | ||
20 | struct dentry *dent_s; /* Debugging file */ | 23 | struct dentry *dent_s; /* Debugging file */ |
21 | struct dentry *dent_t; /* Text interface file */ | 24 | struct dentry *dent_t; /* Text interface file */ |
22 | struct usb_bus *u_bus; | ||
23 | int uses_dma; | 25 | int uses_dma; |
24 | 26 | ||
25 | /* Ref */ | 27 | /* Ref */ |
@@ -48,13 +50,35 @@ struct mon_reader { | |||
48 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); | 50 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); |
49 | void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); | 51 | void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); |
50 | 52 | ||
53 | struct mon_bus *mon_bus_lookup(unsigned int num); | ||
54 | |||
55 | int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus); | ||
56 | void mon_text_del(struct mon_bus *mbus); | ||
57 | // void mon_bin_add(struct mon_bus *); | ||
58 | |||
59 | int __init mon_text_init(void); | ||
60 | void __exit mon_text_exit(void); | ||
61 | int __init mon_bin_init(void); | ||
62 | void __exit mon_bin_exit(void); | ||
63 | |||
51 | /* | 64 | /* |
52 | */ | 65 | * DMA interface. |
66 | * | ||
67 | * XXX The vectored side needs a serious re-thinking. Abstracting vectors, | ||
68 | * like in Paolo's original patch, produces a double pkmap. We need an idea. | ||
69 | */ | ||
53 | extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); | 70 | extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); |
54 | 71 | ||
72 | struct mon_reader_bin; | ||
73 | extern void mon_dmapeek_vec(const struct mon_reader_bin *rp, | ||
74 | unsigned int offset, dma_addr_t dma_addr, unsigned int len); | ||
75 | extern unsigned int mon_copy_to_buff(const struct mon_reader_bin *rp, | ||
76 | unsigned int offset, const unsigned char *from, unsigned int len); | ||
77 | |||
78 | /* | ||
79 | */ | ||
55 | extern struct mutex mon_lock; | 80 | extern struct mutex mon_lock; |
56 | 81 | ||
57 | extern const struct file_operations mon_fops_text; | ||
58 | extern const struct file_operations mon_fops_stat; | 82 | extern const struct file_operations mon_fops_stat; |
59 | 83 | ||
60 | #endif /* __USB_MON_H */ | 84 | #endif /* __USB_MON_H */ |
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index e081836014ac..a2b94ef512bc 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig | |||
@@ -222,13 +222,15 @@ config USB_NET_MCS7830 | |||
222 | adapters marketed under the DeLOCK brand. | 222 | adapters marketed under the DeLOCK brand. |
223 | 223 | ||
224 | config USB_NET_RNDIS_HOST | 224 | config USB_NET_RNDIS_HOST |
225 | tristate "Host for RNDIS devices (EXPERIMENTAL)" | 225 | tristate "Host for RNDIS and ActiveSync devices (EXPERIMENTAL)" |
226 | depends on USB_USBNET && EXPERIMENTAL | 226 | depends on USB_USBNET && EXPERIMENTAL |
227 | select USB_NET_CDCETHER | 227 | select USB_NET_CDCETHER |
228 | help | 228 | help |
229 | This option enables hosting "Remote NDIS" USB networking links, | 229 | This option enables hosting "Remote NDIS" USB networking links, |
230 | as encouraged by Microsoft (instead of CDC Ethernet!) for use in | 230 | as encouraged by Microsoft (instead of CDC Ethernet!) for use in |
231 | various devices that may only support this protocol. | 231 | various devices that may only support this protocol. A variant |
232 | of this protocol (with even less public documentation) seems to | ||
233 | be at the root of Microsoft's "ActiveSync" too. | ||
232 | 234 | ||
233 | Avoid using this protocol unless you have no better options. | 235 | Avoid using this protocol unless you have no better options. |
234 | The protocol specification is incomplete, and is controlled by | 236 | The protocol specification is incomplete, and is controlled by |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index 44a91547146e..e5cdafa258dd 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CDC Ethernet based networking peripherals | 2 | * CDC Ethernet based networking peripherals |
3 | * Copyright (C) 2003-2005 by David Brownell | 3 | * Copyright (C) 2003-2005 by David Brownell |
4 | * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -35,6 +36,29 @@ | |||
35 | #include "usbnet.h" | 36 | #include "usbnet.h" |
36 | 37 | ||
37 | 38 | ||
39 | #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) | ||
40 | |||
41 | static int is_rndis(struct usb_interface_descriptor *desc) | ||
42 | { | ||
43 | return desc->bInterfaceClass == USB_CLASS_COMM | ||
44 | && desc->bInterfaceSubClass == 2 | ||
45 | && desc->bInterfaceProtocol == 0xff; | ||
46 | } | ||
47 | |||
48 | static int is_activesync(struct usb_interface_descriptor *desc) | ||
49 | { | ||
50 | return desc->bInterfaceClass == USB_CLASS_MISC | ||
51 | && desc->bInterfaceSubClass == 1 | ||
52 | && desc->bInterfaceProtocol == 1; | ||
53 | } | ||
54 | |||
55 | #else | ||
56 | |||
57 | #define is_rndis(desc) 0 | ||
58 | #define is_activesync(desc) 0 | ||
59 | |||
60 | #endif | ||
61 | |||
38 | /* | 62 | /* |
39 | * probes control interface, claims data interface, collects the bulk | 63 | * probes control interface, claims data interface, collects the bulk |
40 | * endpoints, activates data interface (if needed), maybe sets MTU. | 64 | * endpoints, activates data interface (if needed), maybe sets MTU. |
@@ -71,7 +95,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
71 | /* this assumes that if there's a non-RNDIS vendor variant | 95 | /* this assumes that if there's a non-RNDIS vendor variant |
72 | * of cdc-acm, it'll fail RNDIS requests cleanly. | 96 | * of cdc-acm, it'll fail RNDIS requests cleanly. |
73 | */ | 97 | */ |
74 | rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff); | 98 | rndis = is_rndis(&intf->cur_altsetting->desc) |
99 | || is_activesync(&intf->cur_altsetting->desc); | ||
75 | 100 | ||
76 | memset(info, 0, sizeof *info); | 101 | memset(info, 0, sizeof *info); |
77 | info->control = intf; | 102 | info->control = intf; |
@@ -99,6 +124,23 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
99 | goto bad_desc; | 124 | goto bad_desc; |
100 | } | 125 | } |
101 | break; | 126 | break; |
127 | case USB_CDC_ACM_TYPE: | ||
128 | /* paranoia: disambiguate a "real" vendor-specific | ||
129 | * modem interface from an RNDIS non-modem. | ||
130 | */ | ||
131 | if (rndis) { | ||
132 | struct usb_cdc_acm_descriptor *d; | ||
133 | |||
134 | d = (void *) buf; | ||
135 | if (d->bmCapabilities) { | ||
136 | dev_dbg(&intf->dev, | ||
137 | "ACM capabilities %02x, " | ||
138 | "not really RNDIS?\n", | ||
139 | d->bmCapabilities); | ||
140 | goto bad_desc; | ||
141 | } | ||
142 | } | ||
143 | break; | ||
102 | case USB_CDC_UNION_TYPE: | 144 | case USB_CDC_UNION_TYPE: |
103 | if (info->u) { | 145 | if (info->u) { |
104 | dev_dbg(&intf->dev, "extra CDC union\n"); | 146 | dev_dbg(&intf->dev, "extra CDC union\n"); |
@@ -171,7 +213,21 @@ next_desc: | |||
171 | buf += buf [0]; | 213 | buf += buf [0]; |
172 | } | 214 | } |
173 | 215 | ||
174 | if (!info->header || !info->u || (!rndis && !info->ether)) { | 216 | /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors, |
217 | * so we'll hard-wire the interfaces and not check for descriptors. | ||
218 | */ | ||
219 | if (is_activesync(&intf->cur_altsetting->desc) && !info->u) { | ||
220 | info->control = usb_ifnum_to_if(dev->udev, 0); | ||
221 | info->data = usb_ifnum_to_if(dev->udev, 1); | ||
222 | if (!info->control || !info->data) { | ||
223 | dev_dbg(&intf->dev, | ||
224 | "activesync: master #0/%p slave #1/%p\n", | ||
225 | info->control, | ||
226 | info->data); | ||
227 | goto bad_desc; | ||
228 | } | ||
229 | |||
230 | } else if (!info->header || !info->u || (!rndis && !info->ether)) { | ||
175 | dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", | 231 | dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", |
176 | info->header ? "" : "header ", | 232 | info->header ? "" : "header ", |
177 | info->u ? "" : "union ", | 233 | info->u ? "" : "union ", |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index fa78326d0bf0..36a989160a68 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -179,6 +179,7 @@ static struct usb_driver kaweth_driver = { | |||
179 | .suspend = kaweth_suspend, | 179 | .suspend = kaweth_suspend, |
180 | .resume = kaweth_resume, | 180 | .resume = kaweth_resume, |
181 | .id_table = usb_klsi_table, | 181 | .id_table = usb_klsi_table, |
182 | .supports_autosuspend = 1, | ||
182 | }; | 183 | }; |
183 | 184 | ||
184 | typedef __u8 eth_addr_t[6]; | 185 | typedef __u8 eth_addr_t[6]; |
@@ -225,6 +226,7 @@ struct kaweth_device | |||
225 | struct delayed_work lowmem_work; | 226 | struct delayed_work lowmem_work; |
226 | 227 | ||
227 | struct usb_device *dev; | 228 | struct usb_device *dev; |
229 | struct usb_interface *intf; | ||
228 | struct net_device *net; | 230 | struct net_device *net; |
229 | wait_queue_head_t term_wait; | 231 | wait_queue_head_t term_wait; |
230 | 232 | ||
@@ -662,9 +664,14 @@ static int kaweth_open(struct net_device *net) | |||
662 | 664 | ||
663 | dbg("Opening network device."); | 665 | dbg("Opening network device."); |
664 | 666 | ||
667 | res = usb_autopm_get_interface(kaweth->intf); | ||
668 | if (res) { | ||
669 | err("Interface cannot be resumed."); | ||
670 | return -EIO; | ||
671 | } | ||
665 | res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); | 672 | res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); |
666 | if (res) | 673 | if (res) |
667 | return -EIO; | 674 | goto err_out; |
668 | 675 | ||
669 | usb_fill_int_urb( | 676 | usb_fill_int_urb( |
670 | kaweth->irq_urb, | 677 | kaweth->irq_urb, |
@@ -681,7 +688,7 @@ static int kaweth_open(struct net_device *net) | |||
681 | res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); | 688 | res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); |
682 | if (res) { | 689 | if (res) { |
683 | usb_kill_urb(kaweth->rx_urb); | 690 | usb_kill_urb(kaweth->rx_urb); |
684 | return -EIO; | 691 | goto err_out; |
685 | } | 692 | } |
686 | kaweth->opened = 1; | 693 | kaweth->opened = 1; |
687 | 694 | ||
@@ -689,10 +696,14 @@ static int kaweth_open(struct net_device *net) | |||
689 | 696 | ||
690 | kaweth_async_set_rx_mode(kaweth); | 697 | kaweth_async_set_rx_mode(kaweth); |
691 | return 0; | 698 | return 0; |
699 | |||
700 | err_out: | ||
701 | usb_autopm_enable(kaweth->intf); | ||
702 | return -EIO; | ||
692 | } | 703 | } |
693 | 704 | ||
694 | /**************************************************************** | 705 | /**************************************************************** |
695 | * kaweth_close | 706 | * kaweth_kill_urbs |
696 | ****************************************************************/ | 707 | ****************************************************************/ |
697 | static void kaweth_kill_urbs(struct kaweth_device *kaweth) | 708 | static void kaweth_kill_urbs(struct kaweth_device *kaweth) |
698 | { | 709 | { |
@@ -724,17 +735,29 @@ static int kaweth_close(struct net_device *net) | |||
724 | 735 | ||
725 | kaweth->status &= ~KAWETH_STATUS_CLOSING; | 736 | kaweth->status &= ~KAWETH_STATUS_CLOSING; |
726 | 737 | ||
738 | usb_autopm_enable(kaweth->intf); | ||
739 | |||
727 | return 0; | 740 | return 0; |
728 | } | 741 | } |
729 | 742 | ||
730 | static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 743 | static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
731 | { | 744 | { |
745 | struct kaweth_device *kaweth = netdev_priv(dev); | ||
732 | 746 | ||
733 | strlcpy(info->driver, driver_name, sizeof(info->driver)); | 747 | strlcpy(info->driver, driver_name, sizeof(info->driver)); |
748 | usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info)); | ||
749 | } | ||
750 | |||
751 | static u32 kaweth_get_link(struct net_device *dev) | ||
752 | { | ||
753 | struct kaweth_device *kaweth = netdev_priv(dev); | ||
754 | |||
755 | return kaweth->linkstate; | ||
734 | } | 756 | } |
735 | 757 | ||
736 | static struct ethtool_ops ops = { | 758 | static struct ethtool_ops ops = { |
737 | .get_drvinfo = kaweth_get_drvinfo | 759 | .get_drvinfo = kaweth_get_drvinfo, |
760 | .get_link = kaweth_get_link | ||
738 | }; | 761 | }; |
739 | 762 | ||
740 | /**************************************************************** | 763 | /**************************************************************** |
@@ -908,6 +931,7 @@ static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) | |||
908 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | 931 | struct kaweth_device *kaweth = usb_get_intfdata(intf); |
909 | unsigned long flags; | 932 | unsigned long flags; |
910 | 933 | ||
934 | dbg("Suspending device"); | ||
911 | spin_lock_irqsave(&kaweth->device_lock, flags); | 935 | spin_lock_irqsave(&kaweth->device_lock, flags); |
912 | kaweth->status |= KAWETH_STATUS_SUSPENDING; | 936 | kaweth->status |= KAWETH_STATUS_SUSPENDING; |
913 | spin_unlock_irqrestore(&kaweth->device_lock, flags); | 937 | spin_unlock_irqrestore(&kaweth->device_lock, flags); |
@@ -924,6 +948,7 @@ static int kaweth_resume(struct usb_interface *intf) | |||
924 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | 948 | struct kaweth_device *kaweth = usb_get_intfdata(intf); |
925 | unsigned long flags; | 949 | unsigned long flags; |
926 | 950 | ||
951 | dbg("Resuming device"); | ||
927 | spin_lock_irqsave(&kaweth->device_lock, flags); | 952 | spin_lock_irqsave(&kaweth->device_lock, flags); |
928 | kaweth->status &= ~KAWETH_STATUS_SUSPENDING; | 953 | kaweth->status &= ~KAWETH_STATUS_SUSPENDING; |
929 | spin_unlock_irqrestore(&kaweth->device_lock, flags); | 954 | spin_unlock_irqrestore(&kaweth->device_lock, flags); |
@@ -1086,6 +1111,8 @@ err_fw: | |||
1086 | 1111 | ||
1087 | dbg("Initializing net device."); | 1112 | dbg("Initializing net device."); |
1088 | 1113 | ||
1114 | kaweth->intf = intf; | ||
1115 | |||
1089 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 1116 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
1090 | if (!kaweth->tx_urb) | 1117 | if (!kaweth->tx_urb) |
1091 | goto err_free_netdev; | 1118 | goto err_free_netdev; |
@@ -1265,7 +1292,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, | |||
1265 | { | 1292 | { |
1266 | struct urb *urb; | 1293 | struct urb *urb; |
1267 | int retv; | 1294 | int retv; |
1268 | int length; | 1295 | int length = 0; /* shut up GCC */ |
1269 | 1296 | ||
1270 | urb = usb_alloc_urb(0, GFP_NOIO); | 1297 | urb = usb_alloc_urb(0, GFP_NOIO); |
1271 | if (!urb) | 1298 | if (!urb) |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index a322a16d9cf8..be888d2d813c 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
@@ -49,6 +49,8 @@ | |||
49 | * - In some cases, MS-Windows will emit undocumented requests; this | 49 | * - In some cases, MS-Windows will emit undocumented requests; this |
50 | * matters more to peripheral implementations than host ones. | 50 | * matters more to peripheral implementations than host ones. |
51 | * | 51 | * |
52 | * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync". | ||
53 | * | ||
52 | * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in | 54 | * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in |
53 | * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and | 55 | * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and |
54 | * currently rare) "Ethernet Emulation Model" (EEM). | 56 | * currently rare) "Ethernet Emulation Model" (EEM). |
@@ -61,6 +63,9 @@ | |||
61 | * - control-in: GET_ENCAPSULATED | 63 | * - control-in: GET_ENCAPSULATED |
62 | * | 64 | * |
63 | * We'll try to ignore the RESPONSE_AVAILABLE notifications. | 65 | * We'll try to ignore the RESPONSE_AVAILABLE notifications. |
66 | * | ||
67 | * REVISIT some RNDIS implementations seem to have curious issues still | ||
68 | * to be resolved. | ||
64 | */ | 69 | */ |
65 | struct rndis_msg_hdr { | 70 | struct rndis_msg_hdr { |
66 | __le32 msg_type; /* RNDIS_MSG_* */ | 71 | __le32 msg_type; /* RNDIS_MSG_* */ |
@@ -71,8 +76,14 @@ struct rndis_msg_hdr { | |||
71 | // ... and more | 76 | // ... and more |
72 | } __attribute__ ((packed)); | 77 | } __attribute__ ((packed)); |
73 | 78 | ||
74 | /* RNDIS defines this (absurdly huge) control timeout */ | 79 | /* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */ |
75 | #define RNDIS_CONTROL_TIMEOUT_MS (10 * 1000) | 80 | #define CONTROL_BUFFER_SIZE 1025 |
81 | |||
82 | /* RNDIS defines an (absurdly huge) 10 second control timeout, | ||
83 | * but ActiveSync seems to use a more usual 5 second timeout | ||
84 | * (which matches the USB 2.0 spec). | ||
85 | */ | ||
86 | #define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) | ||
76 | 87 | ||
77 | 88 | ||
78 | #define ccpu2 __constant_cpu_to_le32 | 89 | #define ccpu2 __constant_cpu_to_le32 |
@@ -270,6 +281,7 @@ static void rndis_status(struct usbnet *dev, struct urb *urb) | |||
270 | static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | 281 | static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) |
271 | { | 282 | { |
272 | struct cdc_state *info = (void *) &dev->data; | 283 | struct cdc_state *info = (void *) &dev->data; |
284 | int master_ifnum; | ||
273 | int retval; | 285 | int retval; |
274 | unsigned count; | 286 | unsigned count; |
275 | __le32 rsp; | 287 | __le32 rsp; |
@@ -279,7 +291,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
279 | * disconnect(): either serialize, or dispatch responses on xid | 291 | * disconnect(): either serialize, or dispatch responses on xid |
280 | */ | 292 | */ |
281 | 293 | ||
282 | /* Issue the request; don't bother byteswapping our xid */ | 294 | /* Issue the request; xid is unique, don't bother byteswapping it */ |
283 | if (likely(buf->msg_type != RNDIS_MSG_HALT | 295 | if (likely(buf->msg_type != RNDIS_MSG_HALT |
284 | && buf->msg_type != RNDIS_MSG_RESET)) { | 296 | && buf->msg_type != RNDIS_MSG_RESET)) { |
285 | xid = dev->xid++; | 297 | xid = dev->xid++; |
@@ -287,11 +299,12 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
287 | xid = dev->xid++; | 299 | xid = dev->xid++; |
288 | buf->request_id = (__force __le32) xid; | 300 | buf->request_id = (__force __le32) xid; |
289 | } | 301 | } |
302 | master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber; | ||
290 | retval = usb_control_msg(dev->udev, | 303 | retval = usb_control_msg(dev->udev, |
291 | usb_sndctrlpipe(dev->udev, 0), | 304 | usb_sndctrlpipe(dev->udev, 0), |
292 | USB_CDC_SEND_ENCAPSULATED_COMMAND, | 305 | USB_CDC_SEND_ENCAPSULATED_COMMAND, |
293 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 306 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
294 | 0, info->u->bMasterInterface0, | 307 | 0, master_ifnum, |
295 | buf, le32_to_cpu(buf->msg_len), | 308 | buf, le32_to_cpu(buf->msg_len), |
296 | RNDIS_CONTROL_TIMEOUT_MS); | 309 | RNDIS_CONTROL_TIMEOUT_MS); |
297 | if (unlikely(retval < 0 || xid == 0)) | 310 | if (unlikely(retval < 0 || xid == 0)) |
@@ -306,13 +319,13 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
306 | */ | 319 | */ |
307 | rsp = buf->msg_type | RNDIS_MSG_COMPLETION; | 320 | rsp = buf->msg_type | RNDIS_MSG_COMPLETION; |
308 | for (count = 0; count < 10; count++) { | 321 | for (count = 0; count < 10; count++) { |
309 | memset(buf, 0, 1024); | 322 | memset(buf, 0, CONTROL_BUFFER_SIZE); |
310 | retval = usb_control_msg(dev->udev, | 323 | retval = usb_control_msg(dev->udev, |
311 | usb_rcvctrlpipe(dev->udev, 0), | 324 | usb_rcvctrlpipe(dev->udev, 0), |
312 | USB_CDC_GET_ENCAPSULATED_RESPONSE, | 325 | USB_CDC_GET_ENCAPSULATED_RESPONSE, |
313 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 326 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
314 | 0, info->u->bMasterInterface0, | 327 | 0, master_ifnum, |
315 | buf, 1024, | 328 | buf, CONTROL_BUFFER_SIZE, |
316 | RNDIS_CONTROL_TIMEOUT_MS); | 329 | RNDIS_CONTROL_TIMEOUT_MS); |
317 | if (likely(retval >= 8)) { | 330 | if (likely(retval >= 8)) { |
318 | msg_len = le32_to_cpu(buf->msg_len); | 331 | msg_len = le32_to_cpu(buf->msg_len); |
@@ -350,7 +363,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
350 | usb_sndctrlpipe(dev->udev, 0), | 363 | usb_sndctrlpipe(dev->udev, 0), |
351 | USB_CDC_SEND_ENCAPSULATED_COMMAND, | 364 | USB_CDC_SEND_ENCAPSULATED_COMMAND, |
352 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 365 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
353 | 0, info->u->bMasterInterface0, | 366 | 0, master_ifnum, |
354 | msg, sizeof *msg, | 367 | msg, sizeof *msg, |
355 | RNDIS_CONTROL_TIMEOUT_MS); | 368 | RNDIS_CONTROL_TIMEOUT_MS); |
356 | if (unlikely(retval < 0)) | 369 | if (unlikely(retval < 0)) |
@@ -393,38 +406,64 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) | |||
393 | u32 tmp; | 406 | u32 tmp; |
394 | 407 | ||
395 | /* we can't rely on i/o from stack working, or stack allocation */ | 408 | /* we can't rely on i/o from stack working, or stack allocation */ |
396 | u.buf = kmalloc(1024, GFP_KERNEL); | 409 | u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); |
397 | if (!u.buf) | 410 | if (!u.buf) |
398 | return -ENOMEM; | 411 | return -ENOMEM; |
399 | retval = usbnet_generic_cdc_bind(dev, intf); | 412 | retval = usbnet_generic_cdc_bind(dev, intf); |
400 | if (retval < 0) | 413 | if (retval < 0) |
401 | goto fail; | 414 | goto fail; |
402 | 415 | ||
403 | net->hard_header_len += sizeof (struct rndis_data_hdr); | ||
404 | |||
405 | /* initialize; max transfer is 16KB at full speed */ | ||
406 | u.init->msg_type = RNDIS_MSG_INIT; | 416 | u.init->msg_type = RNDIS_MSG_INIT; |
407 | u.init->msg_len = ccpu2(sizeof *u.init); | 417 | u.init->msg_len = ccpu2(sizeof *u.init); |
408 | u.init->major_version = ccpu2(1); | 418 | u.init->major_version = ccpu2(1); |
409 | u.init->minor_version = ccpu2(0); | 419 | u.init->minor_version = ccpu2(0); |
410 | u.init->max_transfer_size = ccpu2(net->mtu + net->hard_header_len); | ||
411 | 420 | ||
421 | /* max transfer (in spec) is 0x4000 at full speed, but for | ||
422 | * TX we'll stick to one Ethernet packet plus RNDIS framing. | ||
423 | * For RX we handle drivers that zero-pad to end-of-packet. | ||
424 | * Don't let userspace change these settings. | ||
425 | */ | ||
426 | net->hard_header_len += sizeof (struct rndis_data_hdr); | ||
427 | dev->hard_mtu = net->mtu + net->hard_header_len; | ||
428 | |||
429 | dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); | ||
430 | dev->rx_urb_size &= ~(dev->maxpacket - 1); | ||
431 | u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); | ||
432 | |||
433 | net->change_mtu = NULL; | ||
412 | retval = rndis_command(dev, u.header); | 434 | retval = rndis_command(dev, u.header); |
413 | if (unlikely(retval < 0)) { | 435 | if (unlikely(retval < 0)) { |
414 | /* it might not even be an RNDIS device!! */ | 436 | /* it might not even be an RNDIS device!! */ |
415 | dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); | 437 | dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); |
438 | goto fail_and_release; | ||
439 | } | ||
440 | tmp = le32_to_cpu(u.init_c->max_transfer_size); | ||
441 | if (tmp < dev->hard_mtu) { | ||
442 | dev_err(&intf->dev, | ||
443 | "dev can't take %u byte packets (max %u)\n", | ||
444 | dev->hard_mtu, tmp); | ||
416 | goto fail_and_release; | 445 | goto fail_and_release; |
417 | } | 446 | } |
418 | dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size); | 447 | |
419 | /* REVISIT: peripheral "alignment" request is ignored ... */ | 448 | /* REVISIT: peripheral "alignment" request is ignored ... */ |
420 | dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu, | 449 | dev_dbg(&intf->dev, |
450 | "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n", | ||
451 | dev->hard_mtu, tmp, dev->rx_urb_size, | ||
421 | 1 << le32_to_cpu(u.init_c->packet_alignment)); | 452 | 1 << le32_to_cpu(u.init_c->packet_alignment)); |
422 | 453 | ||
423 | /* get designated host ethernet address */ | 454 | /* Get designated host ethernet address. |
424 | memset(u.get, 0, sizeof *u.get); | 455 | * |
456 | * Adding a payload exactly the same size as the expected response | ||
457 | * payload is an evident requirement MSFT added for ActiveSync. | ||
458 | * This undocumented (and nonsensical) issue was found by sniffing | ||
459 | * protocol requests from the ActiveSync 4.1 Windows driver. | ||
460 | */ | ||
461 | memset(u.get, 0, sizeof *u.get + 48); | ||
425 | u.get->msg_type = RNDIS_MSG_QUERY; | 462 | u.get->msg_type = RNDIS_MSG_QUERY; |
426 | u.get->msg_len = ccpu2(sizeof *u.get); | 463 | u.get->msg_len = ccpu2(sizeof *u.get + 48); |
427 | u.get->oid = OID_802_3_PERMANENT_ADDRESS; | 464 | u.get->oid = OID_802_3_PERMANENT_ADDRESS; |
465 | u.get->len = ccpu2(48); | ||
466 | u.get->offset = ccpu2(20); | ||
428 | 467 | ||
429 | retval = rndis_command(dev, u.header); | 468 | retval = rndis_command(dev, u.header); |
430 | if (unlikely(retval < 0)) { | 469 | if (unlikely(retval < 0)) { |
@@ -432,7 +471,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) | |||
432 | goto fail_and_release; | 471 | goto fail_and_release; |
433 | } | 472 | } |
434 | tmp = le32_to_cpu(u.get_c->offset); | 473 | tmp = le32_to_cpu(u.get_c->offset); |
435 | if (unlikely((tmp + 8) > (1024 - ETH_ALEN) | 474 | if (unlikely((tmp + 8) > (CONTROL_BUFFER_SIZE - ETH_ALEN) |
436 | || u.get_c->len != ccpu2(ETH_ALEN))) { | 475 | || u.get_c->len != ccpu2(ETH_ALEN))) { |
437 | dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", | 476 | dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", |
438 | tmp, le32_to_cpu(u.get_c->len)); | 477 | tmp, le32_to_cpu(u.get_c->len)); |
@@ -598,6 +637,10 @@ static const struct usb_device_id products [] = { | |||
598 | /* RNDIS is MSFT's un-official variant of CDC ACM */ | 637 | /* RNDIS is MSFT's un-official variant of CDC ACM */ |
599 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), | 638 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), |
600 | .driver_info = (unsigned long) &rndis_info, | 639 | .driver_info = (unsigned long) &rndis_info, |
640 | }, { | ||
641 | /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ | ||
642 | USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), | ||
643 | .driver_info = (unsigned long) &rndis_info, | ||
601 | }, | 644 | }, |
602 | { }, // END | 645 | { }, // END |
603 | }; | 646 | }; |
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 86bcf63b6ba5..11dad42c3c60 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -572,8 +572,20 @@ static void aircable_unthrottle(struct usb_serial_port *port) | |||
572 | schedule_work(&priv->rx_work); | 572 | schedule_work(&priv->rx_work); |
573 | } | 573 | } |
574 | 574 | ||
575 | static struct usb_driver aircable_driver = { | ||
576 | .name = "aircable", | ||
577 | .probe = usb_serial_probe, | ||
578 | .disconnect = usb_serial_disconnect, | ||
579 | .id_table = id_table, | ||
580 | .no_dynamic_id = 1, | ||
581 | }; | ||
582 | |||
575 | static struct usb_serial_driver aircable_device = { | 583 | static struct usb_serial_driver aircable_device = { |
576 | .description = "aircable", | 584 | .driver = { |
585 | .owner = THIS_MODULE, | ||
586 | .name = "aircable", | ||
587 | }, | ||
588 | .usb_driver = &aircable_driver, | ||
577 | .id_table = id_table, | 589 | .id_table = id_table, |
578 | .num_ports = 1, | 590 | .num_ports = 1, |
579 | .attach = aircable_attach, | 591 | .attach = aircable_attach, |
@@ -587,13 +599,6 @@ static struct usb_serial_driver aircable_device = { | |||
587 | .unthrottle = aircable_unthrottle, | 599 | .unthrottle = aircable_unthrottle, |
588 | }; | 600 | }; |
589 | 601 | ||
590 | static struct usb_driver aircable_driver = { | ||
591 | .name = "aircable", | ||
592 | .probe = usb_serial_probe, | ||
593 | .disconnect = usb_serial_disconnect, | ||
594 | .id_table = id_table, | ||
595 | }; | ||
596 | |||
597 | static int __init aircable_init (void) | 602 | static int __init aircable_init (void) |
598 | { | 603 | { |
599 | int retval; | 604 | int retval; |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index f2ca76a9cbac..0af42e32fa0a 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -277,6 +277,7 @@ static struct usb_serial_driver airprime_device = { | |||
277 | .owner = THIS_MODULE, | 277 | .owner = THIS_MODULE, |
278 | .name = "airprime", | 278 | .name = "airprime", |
279 | }, | 279 | }, |
280 | .usb_driver = &airprime_driver, | ||
280 | .id_table = id_table, | 281 | .id_table = id_table, |
281 | .num_interrupt_in = NUM_DONT_CARE, | 282 | .num_interrupt_in = NUM_DONT_CARE, |
282 | .num_bulk_in = NUM_DONT_CARE, | 283 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 5261cd22ee6b..edd685791a6b 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -444,6 +444,7 @@ static struct usb_driver ark3116_driver = { | |||
444 | .probe = usb_serial_probe, | 444 | .probe = usb_serial_probe, |
445 | .disconnect = usb_serial_disconnect, | 445 | .disconnect = usb_serial_disconnect, |
446 | .id_table = id_table, | 446 | .id_table = id_table, |
447 | .no_dynamic_id = 1, | ||
447 | }; | 448 | }; |
448 | 449 | ||
449 | static struct usb_serial_driver ark3116_device = { | 450 | static struct usb_serial_driver ark3116_device = { |
@@ -452,6 +453,7 @@ static struct usb_serial_driver ark3116_device = { | |||
452 | .name = "ark3116", | 453 | .name = "ark3116", |
453 | }, | 454 | }, |
454 | .id_table = id_table, | 455 | .id_table = id_table, |
456 | .usb_driver = &ark3116_driver, | ||
455 | .num_interrupt_in = 1, | 457 | .num_interrupt_in = 1, |
456 | .num_bulk_in = 1, | 458 | .num_bulk_in = 1, |
457 | .num_bulk_out = 1, | 459 | .num_bulk_out = 1, |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 38b4dae319ee..3b800d277c4b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -126,6 +126,7 @@ static struct usb_serial_driver belkin_device = { | |||
126 | .name = "belkin", | 126 | .name = "belkin", |
127 | }, | 127 | }, |
128 | .description = "Belkin / Peracom / GoHubs USB Serial Adapter", | 128 | .description = "Belkin / Peracom / GoHubs USB Serial Adapter", |
129 | .usb_driver = &belkin_driver, | ||
129 | .id_table = id_table_combined, | 130 | .id_table = id_table_combined, |
130 | .num_interrupt_in = 1, | 131 | .num_interrupt_in = 1, |
131 | .num_bulk_in = 1, | 132 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 6542f220468f..c08a38402b93 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -103,11 +103,52 @@ exit: | |||
103 | return retval; | 103 | return retval; |
104 | } | 104 | } |
105 | 105 | ||
106 | #ifdef CONFIG_HOTPLUG | ||
107 | static ssize_t store_new_id(struct device_driver *driver, | ||
108 | const char *buf, size_t count) | ||
109 | { | ||
110 | struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); | ||
111 | ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count); | ||
112 | |||
113 | if (retval >= 0 && usb_drv->usb_driver != NULL) | ||
114 | retval = usb_store_new_id(&usb_drv->usb_driver->dynids, | ||
115 | &usb_drv->usb_driver->drvwrap.driver, | ||
116 | buf, count); | ||
117 | return retval; | ||
118 | } | ||
119 | |||
120 | static struct driver_attribute drv_attrs[] = { | ||
121 | __ATTR(new_id, S_IWUSR, NULL, store_new_id), | ||
122 | __ATTR_NULL, | ||
123 | }; | ||
124 | |||
125 | static void free_dynids(struct usb_serial_driver *drv) | ||
126 | { | ||
127 | struct usb_dynid *dynid, *n; | ||
128 | |||
129 | spin_lock(&drv->dynids.lock); | ||
130 | list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { | ||
131 | list_del(&dynid->node); | ||
132 | kfree(dynid); | ||
133 | } | ||
134 | spin_unlock(&drv->dynids.lock); | ||
135 | } | ||
136 | |||
137 | #else | ||
138 | static struct driver_attribute drv_attrs[] = { | ||
139 | __ATTR_NULL, | ||
140 | }; | ||
141 | static inline void free_dynids(struct usb_driver *drv) | ||
142 | { | ||
143 | } | ||
144 | #endif | ||
145 | |||
106 | struct bus_type usb_serial_bus_type = { | 146 | struct bus_type usb_serial_bus_type = { |
107 | .name = "usb-serial", | 147 | .name = "usb-serial", |
108 | .match = usb_serial_device_match, | 148 | .match = usb_serial_device_match, |
109 | .probe = usb_serial_device_probe, | 149 | .probe = usb_serial_device_probe, |
110 | .remove = usb_serial_device_remove, | 150 | .remove = usb_serial_device_remove, |
151 | .drv_attrs = drv_attrs, | ||
111 | }; | 152 | }; |
112 | 153 | ||
113 | int usb_serial_bus_register(struct usb_serial_driver *driver) | 154 | int usb_serial_bus_register(struct usb_serial_driver *driver) |
@@ -115,6 +156,9 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) | |||
115 | int retval; | 156 | int retval; |
116 | 157 | ||
117 | driver->driver.bus = &usb_serial_bus_type; | 158 | driver->driver.bus = &usb_serial_bus_type; |
159 | spin_lock_init(&driver->dynids.lock); | ||
160 | INIT_LIST_HEAD(&driver->dynids.list); | ||
161 | |||
118 | retval = driver_register(&driver->driver); | 162 | retval = driver_register(&driver->driver); |
119 | 163 | ||
120 | return retval; | 164 | return retval; |
@@ -122,6 +166,7 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) | |||
122 | 166 | ||
123 | void usb_serial_bus_deregister(struct usb_serial_driver *driver) | 167 | void usb_serial_bus_deregister(struct usb_serial_driver *driver) |
124 | { | 168 | { |
169 | free_dynids(driver); | ||
125 | driver_unregister(&driver->driver); | 170 | driver_unregister(&driver->driver); |
126 | } | 171 | } |
127 | 172 | ||
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 7ebaffd6ed86..06b4fffc189c 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -89,6 +89,7 @@ static struct usb_serial_driver cp2101_device = { | |||
89 | .owner = THIS_MODULE, | 89 | .owner = THIS_MODULE, |
90 | .name = "cp2101", | 90 | .name = "cp2101", |
91 | }, | 91 | }, |
92 | .usb_driver = &cp2101_driver, | ||
92 | .id_table = id_table, | 93 | .id_table = id_table, |
93 | .num_interrupt_in = 0, | 94 | .num_interrupt_in = 0, |
94 | .num_bulk_in = 0, | 95 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index a63c3286caa0..4167753ed31f 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -88,6 +88,7 @@ static struct usb_serial_driver cyberjack_device = { | |||
88 | .name = "cyberjack", | 88 | .name = "cyberjack", |
89 | }, | 89 | }, |
90 | .description = "Reiner SCT Cyberjack USB card reader", | 90 | .description = "Reiner SCT Cyberjack USB card reader", |
91 | .usb_driver = &cyberjack_driver, | ||
91 | .id_table = id_table, | 92 | .id_table = id_table, |
92 | .num_interrupt_in = 1, | 93 | .num_interrupt_in = 1, |
93 | .num_bulk_in = 1, | 94 | .num_bulk_in = 1, |
@@ -98,7 +99,7 @@ static struct usb_serial_driver cyberjack_device = { | |||
98 | .open = cyberjack_open, | 99 | .open = cyberjack_open, |
99 | .close = cyberjack_close, | 100 | .close = cyberjack_close, |
100 | .write = cyberjack_write, | 101 | .write = cyberjack_write, |
101 | .write_room = cyberjack_write_room, | 102 | .write_room = cyberjack_write_room, |
102 | .read_int_callback = cyberjack_read_int_callback, | 103 | .read_int_callback = cyberjack_read_int_callback, |
103 | .read_bulk_callback = cyberjack_read_bulk_callback, | 104 | .read_bulk_callback = cyberjack_read_bulk_callback, |
104 | .write_bulk_callback = cyberjack_write_bulk_callback, | 105 | .write_bulk_callback = cyberjack_write_bulk_callback, |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 6bc1f404e186..57b8e27285fc 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -193,6 +193,7 @@ static struct usb_serial_driver cypress_earthmate_device = { | |||
193 | .name = "earthmate", | 193 | .name = "earthmate", |
194 | }, | 194 | }, |
195 | .description = "DeLorme Earthmate USB", | 195 | .description = "DeLorme Earthmate USB", |
196 | .usb_driver = &cypress_driver, | ||
196 | .id_table = id_table_earthmate, | 197 | .id_table = id_table_earthmate, |
197 | .num_interrupt_in = 1, | 198 | .num_interrupt_in = 1, |
198 | .num_interrupt_out = 1, | 199 | .num_interrupt_out = 1, |
@@ -222,6 +223,7 @@ static struct usb_serial_driver cypress_hidcom_device = { | |||
222 | .name = "cyphidcom", | 223 | .name = "cyphidcom", |
223 | }, | 224 | }, |
224 | .description = "HID->COM RS232 Adapter", | 225 | .description = "HID->COM RS232 Adapter", |
226 | .usb_driver = &cypress_driver, | ||
225 | .id_table = id_table_cyphidcomrs232, | 227 | .id_table = id_table_cyphidcomrs232, |
226 | .num_interrupt_in = 1, | 228 | .num_interrupt_in = 1, |
227 | .num_interrupt_out = 1, | 229 | .num_interrupt_out = 1, |
@@ -251,6 +253,7 @@ static struct usb_serial_driver cypress_ca42v2_device = { | |||
251 | .name = "nokiaca42v2", | 253 | .name = "nokiaca42v2", |
252 | }, | 254 | }, |
253 | .description = "Nokia CA-42 V2 Adapter", | 255 | .description = "Nokia CA-42 V2 Adapter", |
256 | .usb_driver = &cypress_driver, | ||
254 | .id_table = id_table_nokiaca42v2, | 257 | .id_table = id_table_nokiaca42v2, |
255 | .num_interrupt_in = 1, | 258 | .num_interrupt_in = 1, |
256 | .num_interrupt_out = 1, | 259 | .num_interrupt_out = 1, |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index efd9ce3f931f..0b0fb51bad3e 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -509,6 +509,7 @@ static struct usb_serial_driver digi_acceleport_2_device = { | |||
509 | .name = "digi_2", | 509 | .name = "digi_2", |
510 | }, | 510 | }, |
511 | .description = "Digi 2 port USB adapter", | 511 | .description = "Digi 2 port USB adapter", |
512 | .usb_driver = &digi_driver, | ||
512 | .id_table = id_table_2, | 513 | .id_table = id_table_2, |
513 | .num_interrupt_in = 0, | 514 | .num_interrupt_in = 0, |
514 | .num_bulk_in = 4, | 515 | .num_bulk_in = 4, |
@@ -538,6 +539,7 @@ static struct usb_serial_driver digi_acceleport_4_device = { | |||
538 | .name = "digi_4", | 539 | .name = "digi_4", |
539 | }, | 540 | }, |
540 | .description = "Digi 4 port USB adapter", | 541 | .description = "Digi 4 port USB adapter", |
542 | .usb_driver = &digi_driver, | ||
541 | .id_table = id_table_4, | 543 | .id_table = id_table_4, |
542 | .num_interrupt_in = 0, | 544 | .num_interrupt_in = 0, |
543 | .num_bulk_in = 5, | 545 | .num_bulk_in = 5, |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 92beeb19795f..4703c8f85383 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -117,6 +117,7 @@ static struct usb_serial_driver empeg_device = { | |||
117 | .name = "empeg", | 117 | .name = "empeg", |
118 | }, | 118 | }, |
119 | .id_table = id_table, | 119 | .id_table = id_table, |
120 | .usb_driver = &empeg_driver, | ||
120 | .num_interrupt_in = 0, | 121 | .num_interrupt_in = 0, |
121 | .num_bulk_in = 1, | 122 | .num_bulk_in = 1, |
122 | .num_bulk_out = 1, | 123 | .num_bulk_out = 1, |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6986e756f7c0..4695952b6470 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -464,7 +464,6 @@ static struct usb_device_id id_table_combined [] = { | |||
464 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 464 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
465 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | 465 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
466 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, | 466 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, |
467 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) }, | ||
468 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, | 467 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, |
469 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, | 468 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, |
470 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, | 469 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, |
@@ -615,6 +614,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
615 | .name = "ftdi_sio", | 614 | .name = "ftdi_sio", |
616 | }, | 615 | }, |
617 | .description = "FTDI USB Serial Device", | 616 | .description = "FTDI USB Serial Device", |
617 | .usb_driver = &ftdi_driver , | ||
618 | .id_table = id_table_combined, | 618 | .id_table = id_table_combined, |
619 | .num_interrupt_in = 0, | 619 | .num_interrupt_in = 0, |
620 | .num_bulk_in = 1, | 620 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 40dd394de58d..7eff1c03ba80 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -364,7 +364,6 @@ | |||
364 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices | 364 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices |
365 | * and I'm not entirely sure which are used by which. | 365 | * and I'm not entirely sure which are used by which. |
366 | */ | 366 | */ |
367 | #define FTDI_4N_GALAXY_DE_0_PID 0x8372 | ||
368 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 | 367 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 |
369 | #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 | 368 | #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 |
370 | 369 | ||
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 2bebd63d5ed1..4092f6dc9efd 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c | |||
@@ -58,6 +58,7 @@ static struct usb_serial_driver funsoft_device = { | |||
58 | .name = "funsoft", | 58 | .name = "funsoft", |
59 | }, | 59 | }, |
60 | .id_table = id_table, | 60 | .id_table = id_table, |
61 | .usb_driver = &funsoft_driver, | ||
61 | .num_interrupt_in = NUM_DONT_CARE, | 62 | .num_interrupt_in = NUM_DONT_CARE, |
62 | .num_bulk_in = NUM_DONT_CARE, | 63 | .num_bulk_in = NUM_DONT_CARE, |
63 | .num_bulk_out = NUM_DONT_CARE, | 64 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 6530d391ebed..74660a3aa670 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1566,6 +1566,7 @@ static struct usb_serial_driver garmin_device = { | |||
1566 | .name = "garmin_gps", | 1566 | .name = "garmin_gps", |
1567 | }, | 1567 | }, |
1568 | .description = "Garmin GPS usb/tty", | 1568 | .description = "Garmin GPS usb/tty", |
1569 | .usb_driver = &garmin_driver, | ||
1569 | .id_table = id_table, | 1570 | .id_table = id_table, |
1570 | .num_interrupt_in = 1, | 1571 | .num_interrupt_in = 1, |
1571 | .num_bulk_in = 1, | 1572 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 36042937e77f..601e0648dec6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -20,6 +20,10 @@ | |||
20 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | static int generic_probe(struct usb_interface *interface, | ||
24 | const struct usb_device_id *id); | ||
25 | |||
26 | |||
23 | static int debug; | 27 | static int debug; |
24 | 28 | ||
25 | #ifdef CONFIG_USB_SERIAL_GENERIC | 29 | #ifdef CONFIG_USB_SERIAL_GENERIC |
@@ -34,6 +38,21 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); | |||
34 | 38 | ||
35 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ | 39 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ |
36 | 40 | ||
41 | /* we want to look at all devices, as the vendor/product id can change | ||
42 | * depending on the command line argument */ | ||
43 | static struct usb_device_id generic_serial_ids[] = { | ||
44 | {.driver_info = 42}, | ||
45 | {} | ||
46 | }; | ||
47 | |||
48 | static struct usb_driver generic_driver = { | ||
49 | .name = "usbserial_generic", | ||
50 | .probe = generic_probe, | ||
51 | .disconnect = usb_serial_disconnect, | ||
52 | .id_table = generic_serial_ids, | ||
53 | .no_dynamic_id = 1, | ||
54 | }; | ||
55 | |||
37 | /* All of the device info needed for the Generic Serial Converter */ | 56 | /* All of the device info needed for the Generic Serial Converter */ |
38 | struct usb_serial_driver usb_serial_generic_device = { | 57 | struct usb_serial_driver usb_serial_generic_device = { |
39 | .driver = { | 58 | .driver = { |
@@ -41,6 +60,7 @@ struct usb_serial_driver usb_serial_generic_device = { | |||
41 | .name = "generic", | 60 | .name = "generic", |
42 | }, | 61 | }, |
43 | .id_table = generic_device_ids, | 62 | .id_table = generic_device_ids, |
63 | .usb_driver = &generic_driver, | ||
44 | .num_interrupt_in = NUM_DONT_CARE, | 64 | .num_interrupt_in = NUM_DONT_CARE, |
45 | .num_bulk_in = NUM_DONT_CARE, | 65 | .num_bulk_in = NUM_DONT_CARE, |
46 | .num_bulk_out = NUM_DONT_CARE, | 66 | .num_bulk_out = NUM_DONT_CARE, |
@@ -48,13 +68,6 @@ struct usb_serial_driver usb_serial_generic_device = { | |||
48 | .shutdown = usb_serial_generic_shutdown, | 68 | .shutdown = usb_serial_generic_shutdown, |
49 | }; | 69 | }; |
50 | 70 | ||
51 | /* we want to look at all devices, as the vendor/product id can change | ||
52 | * depending on the command line argument */ | ||
53 | static struct usb_device_id generic_serial_ids[] = { | ||
54 | {.driver_info = 42}, | ||
55 | {} | ||
56 | }; | ||
57 | |||
58 | static int generic_probe(struct usb_interface *interface, | 71 | static int generic_probe(struct usb_interface *interface, |
59 | const struct usb_device_id *id) | 72 | const struct usb_device_id *id) |
60 | { | 73 | { |
@@ -65,14 +78,6 @@ static int generic_probe(struct usb_interface *interface, | |||
65 | return usb_serial_probe(interface, id); | 78 | return usb_serial_probe(interface, id); |
66 | return -ENODEV; | 79 | return -ENODEV; |
67 | } | 80 | } |
68 | |||
69 | static struct usb_driver generic_driver = { | ||
70 | .name = "usbserial_generic", | ||
71 | .probe = generic_probe, | ||
72 | .disconnect = usb_serial_disconnect, | ||
73 | .id_table = generic_serial_ids, | ||
74 | .no_dynamic_id = 1, | ||
75 | }; | ||
76 | #endif | 81 | #endif |
77 | 82 | ||
78 | int usb_serial_generic_register (int _debug) | 83 | int usb_serial_generic_register (int _debug) |
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index ebcac701b069..6c6ebae741c9 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
@@ -49,6 +49,7 @@ static struct usb_serial_driver hp49gp_device = { | |||
49 | .name = "hp4X", | 49 | .name = "hp4X", |
50 | }, | 50 | }, |
51 | .id_table = id_table, | 51 | .id_table = id_table, |
52 | .usb_driver = &hp49gp_driver, | ||
52 | .num_interrupt_in = NUM_DONT_CARE, | 53 | .num_interrupt_in = NUM_DONT_CARE, |
53 | .num_bulk_in = NUM_DONT_CARE, | 54 | .num_bulk_in = NUM_DONT_CARE, |
54 | .num_bulk_out = NUM_DONT_CARE, | 55 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index f623d58370a4..6a26a2e683a6 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -146,6 +146,8 @@ struct edgeport_serial { | |||
146 | struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ | 146 | struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ |
147 | struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ | 147 | struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ |
148 | struct edgeport_product_info product_info; /* Product Info */ | 148 | struct edgeport_product_info product_info; /* Product Info */ |
149 | struct edge_compatibility_descriptor epic_descriptor; /* Edgeport compatible descriptor */ | ||
150 | int is_epic; /* flag if EPiC device or not */ | ||
149 | 151 | ||
150 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ | 152 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ |
151 | unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ | 153 | unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ |
@@ -240,14 +242,6 @@ static void edge_shutdown (struct usb_serial *serial); | |||
240 | 242 | ||
241 | #include "io_tables.h" /* all of the devices that this driver supports */ | 243 | #include "io_tables.h" /* all of the devices that this driver supports */ |
242 | 244 | ||
243 | static struct usb_driver io_driver = { | ||
244 | .name = "io_edgeport", | ||
245 | .probe = usb_serial_probe, | ||
246 | .disconnect = usb_serial_disconnect, | ||
247 | .id_table = id_table_combined, | ||
248 | .no_dynamic_id = 1, | ||
249 | }; | ||
250 | |||
251 | /* function prototypes for all of our local functions */ | 245 | /* function prototypes for all of our local functions */ |
252 | static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); | 246 | static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); |
253 | static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); | 247 | static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); |
@@ -397,6 +391,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) | |||
397 | unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); | 391 | unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); |
398 | 392 | ||
399 | kfree(pStringDesc); | 393 | kfree(pStringDesc); |
394 | dbg("%s - USB String %s", __FUNCTION__, string); | ||
400 | return strlen(string); | 395 | return strlen(string); |
401 | } | 396 | } |
402 | 397 | ||
@@ -434,6 +429,34 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de | |||
434 | } | 429 | } |
435 | #endif | 430 | #endif |
436 | 431 | ||
432 | static void dump_product_info(struct edgeport_product_info *product_info) | ||
433 | { | ||
434 | // Dump Product Info structure | ||
435 | dbg("**Product Information:"); | ||
436 | dbg(" ProductId %x", product_info->ProductId ); | ||
437 | dbg(" NumPorts %d", product_info->NumPorts ); | ||
438 | dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); | ||
439 | dbg(" IsServer %d", product_info->IsServer); | ||
440 | dbg(" IsRS232 %d", product_info->IsRS232 ); | ||
441 | dbg(" IsRS422 %d", product_info->IsRS422 ); | ||
442 | dbg(" IsRS485 %d", product_info->IsRS485 ); | ||
443 | dbg(" RomSize %d", product_info->RomSize ); | ||
444 | dbg(" RamSize %d", product_info->RamSize ); | ||
445 | dbg(" CpuRev %x", product_info->CpuRev ); | ||
446 | dbg(" BoardRev %x", product_info->BoardRev); | ||
447 | dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, | ||
448 | product_info->BootMinorVersion, | ||
449 | le16_to_cpu(product_info->BootBuildNumber)); | ||
450 | dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, | ||
451 | product_info->FirmwareMinorVersion, | ||
452 | le16_to_cpu(product_info->FirmwareBuildNumber)); | ||
453 | dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], | ||
454 | product_info->ManufactureDescDate[1], | ||
455 | product_info->ManufactureDescDate[2]+1900); | ||
456 | dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); | ||
457 | dbg(" EpicVer %d", product_info->EpicVer); | ||
458 | } | ||
459 | |||
437 | static void get_product_info(struct edgeport_serial *edge_serial) | 460 | static void get_product_info(struct edgeport_serial *edge_serial) |
438 | { | 461 | { |
439 | struct edgeport_product_info *product_info = &edge_serial->product_info; | 462 | struct edgeport_product_info *product_info = &edge_serial->product_info; |
@@ -495,30 +518,60 @@ static void get_product_info(struct edgeport_serial *edge_serial) | |||
495 | break; | 518 | break; |
496 | } | 519 | } |
497 | 520 | ||
498 | // Dump Product Info structure | 521 | dump_product_info(product_info); |
499 | dbg("**Product Information:"); | 522 | } |
500 | dbg(" ProductId %x", product_info->ProductId ); | ||
501 | dbg(" NumPorts %d", product_info->NumPorts ); | ||
502 | dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); | ||
503 | dbg(" IsServer %d", product_info->IsServer); | ||
504 | dbg(" IsRS232 %d", product_info->IsRS232 ); | ||
505 | dbg(" IsRS422 %d", product_info->IsRS422 ); | ||
506 | dbg(" IsRS485 %d", product_info->IsRS485 ); | ||
507 | dbg(" RomSize %d", product_info->RomSize ); | ||
508 | dbg(" RamSize %d", product_info->RamSize ); | ||
509 | dbg(" CpuRev %x", product_info->CpuRev ); | ||
510 | dbg(" BoardRev %x", product_info->BoardRev); | ||
511 | dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, | ||
512 | product_info->BootMinorVersion, | ||
513 | le16_to_cpu(product_info->BootBuildNumber)); | ||
514 | dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, | ||
515 | product_info->FirmwareMinorVersion, | ||
516 | le16_to_cpu(product_info->FirmwareBuildNumber)); | ||
517 | dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], | ||
518 | product_info->ManufactureDescDate[1], | ||
519 | product_info->ManufactureDescDate[2]+1900); | ||
520 | dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); | ||
521 | 523 | ||
524 | static int get_epic_descriptor(struct edgeport_serial *ep) | ||
525 | { | ||
526 | int result; | ||
527 | struct usb_serial *serial = ep->serial; | ||
528 | struct edgeport_product_info *product_info = &ep->product_info; | ||
529 | struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; | ||
530 | struct edge_compatibility_bits *bits; | ||
531 | |||
532 | ep->is_epic = 0; | ||
533 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
534 | USB_REQUEST_ION_GET_EPIC_DESC, | ||
535 | 0xC0, 0x00, 0x00, | ||
536 | &ep->epic_descriptor, | ||
537 | sizeof(struct edge_compatibility_descriptor), | ||
538 | 300); | ||
539 | |||
540 | dbg("%s result = %d", __FUNCTION__, result); | ||
541 | |||
542 | if (result > 0) { | ||
543 | ep->is_epic = 1; | ||
544 | memset(product_info, 0, sizeof(struct edgeport_product_info)); | ||
545 | |||
546 | product_info->NumPorts = epic->NumPorts; | ||
547 | product_info->ProdInfoVer = 0; | ||
548 | product_info->FirmwareMajorVersion = epic->MajorVersion; | ||
549 | product_info->FirmwareMinorVersion = epic->MinorVersion; | ||
550 | product_info->FirmwareBuildNumber = epic->BuildNumber; | ||
551 | product_info->iDownloadFile = epic->iDownloadFile; | ||
552 | product_info->EpicVer = epic->EpicVer; | ||
553 | product_info->Epic = epic->Supports; | ||
554 | product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE; | ||
555 | dump_product_info(product_info); | ||
556 | |||
557 | bits = &ep->epic_descriptor.Supports; | ||
558 | dbg("**EPIC descriptor:"); | ||
559 | dbg(" VendEnableSuspend: %s", bits->VendEnableSuspend ? "TRUE": "FALSE"); | ||
560 | dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE" ); | ||
561 | dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE" ); | ||
562 | dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE" ); | ||
563 | dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE" ); | ||
564 | dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE" ); | ||
565 | dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE" ); | ||
566 | dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE" ); | ||
567 | dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE" ); | ||
568 | dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE" ); | ||
569 | dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE" ); | ||
570 | dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE" ); | ||
571 | dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE" ); | ||
572 | } | ||
573 | |||
574 | return result; | ||
522 | } | 575 | } |
523 | 576 | ||
524 | 577 | ||
@@ -1017,21 +1070,29 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) | |||
1017 | 1070 | ||
1018 | edge_port->closePending = TRUE; | 1071 | edge_port->closePending = TRUE; |
1019 | 1072 | ||
1020 | /* flush and chase */ | 1073 | if ((!edge_serial->is_epic) || |
1021 | edge_port->chaseResponsePending = TRUE; | 1074 | ((edge_serial->is_epic) && |
1022 | 1075 | (edge_serial->epic_descriptor.Supports.IOSPChase))) { | |
1023 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); | 1076 | /* flush and chase */ |
1024 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); | 1077 | edge_port->chaseResponsePending = TRUE; |
1025 | if (status == 0) { | 1078 | |
1026 | // block until chase finished | 1079 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); |
1027 | block_until_chase_response(edge_port); | 1080 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); |
1028 | } else { | 1081 | if (status == 0) { |
1029 | edge_port->chaseResponsePending = FALSE; | 1082 | // block until chase finished |
1083 | block_until_chase_response(edge_port); | ||
1084 | } else { | ||
1085 | edge_port->chaseResponsePending = FALSE; | ||
1086 | } | ||
1030 | } | 1087 | } |
1031 | 1088 | ||
1032 | /* close the port */ | 1089 | if ((!edge_serial->is_epic) || |
1033 | dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); | 1090 | ((edge_serial->is_epic) && |
1034 | send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); | 1091 | (edge_serial->epic_descriptor.Supports.IOSPClose))) { |
1092 | /* close the port */ | ||
1093 | dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); | ||
1094 | send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); | ||
1095 | } | ||
1035 | 1096 | ||
1036 | //port->close = TRUE; | 1097 | //port->close = TRUE; |
1037 | edge_port->closePending = FALSE; | 1098 | edge_port->closePending = FALSE; |
@@ -1694,29 +1755,38 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned | |||
1694 | static void edge_break (struct usb_serial_port *port, int break_state) | 1755 | static void edge_break (struct usb_serial_port *port, int break_state) |
1695 | { | 1756 | { |
1696 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1757 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
1758 | struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); | ||
1697 | int status; | 1759 | int status; |
1698 | 1760 | ||
1699 | /* flush and chase */ | 1761 | if ((!edge_serial->is_epic) || |
1700 | edge_port->chaseResponsePending = TRUE; | 1762 | ((edge_serial->is_epic) && |
1701 | 1763 | (edge_serial->epic_descriptor.Supports.IOSPChase))) { | |
1702 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); | 1764 | /* flush and chase */ |
1703 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); | 1765 | edge_port->chaseResponsePending = TRUE; |
1704 | if (status == 0) { | 1766 | |
1705 | // block until chase finished | 1767 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); |
1706 | block_until_chase_response(edge_port); | 1768 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); |
1707 | } else { | 1769 | if (status == 0) { |
1708 | edge_port->chaseResponsePending = FALSE; | 1770 | // block until chase finished |
1771 | block_until_chase_response(edge_port); | ||
1772 | } else { | ||
1773 | edge_port->chaseResponsePending = FALSE; | ||
1774 | } | ||
1709 | } | 1775 | } |
1710 | 1776 | ||
1711 | if (break_state == -1) { | 1777 | if ((!edge_serial->is_epic) || |
1712 | dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); | 1778 | ((edge_serial->is_epic) && |
1713 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); | 1779 | (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { |
1714 | } else { | 1780 | if (break_state == -1) { |
1715 | dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); | 1781 | dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); |
1716 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); | 1782 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); |
1717 | } | 1783 | } else { |
1718 | if (status) { | 1784 | dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); |
1719 | dbg("%s - error sending break set/clear command.", __FUNCTION__); | 1785 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); |
1786 | } | ||
1787 | if (status) { | ||
1788 | dbg("%s - error sending break set/clear command.", __FUNCTION__); | ||
1789 | } | ||
1720 | } | 1790 | } |
1721 | 1791 | ||
1722 | return; | 1792 | return; |
@@ -2288,6 +2358,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer | |||
2288 | *****************************************************************************/ | 2358 | *****************************************************************************/ |
2289 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) | 2359 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) |
2290 | { | 2360 | { |
2361 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2291 | unsigned char *cmdBuffer; | 2362 | unsigned char *cmdBuffer; |
2292 | unsigned char *currCmd; | 2363 | unsigned char *currCmd; |
2293 | int cmdLen = 0; | 2364 | int cmdLen = 0; |
@@ -2295,6 +2366,14 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa | |||
2295 | int status; | 2366 | int status; |
2296 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; | 2367 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; |
2297 | 2368 | ||
2369 | if ((!edge_serial->is_epic) || | ||
2370 | ((edge_serial->is_epic) && | ||
2371 | (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { | ||
2372 | dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", | ||
2373 | edge_port->port->number, baudRate); | ||
2374 | return 0; | ||
2375 | } | ||
2376 | |||
2298 | dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); | 2377 | dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); |
2299 | 2378 | ||
2300 | status = calc_baud_rate_divisor (baudRate, &divisor); | 2379 | status = calc_baud_rate_divisor (baudRate, &divisor); |
@@ -2374,6 +2453,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) | |||
2374 | *****************************************************************************/ | 2453 | *****************************************************************************/ |
2375 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) | 2454 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) |
2376 | { | 2455 | { |
2456 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2377 | unsigned char *cmdBuffer; | 2457 | unsigned char *cmdBuffer; |
2378 | unsigned char *currCmd; | 2458 | unsigned char *currCmd; |
2379 | unsigned long cmdLen = 0; | 2459 | unsigned long cmdLen = 0; |
@@ -2381,6 +2461,22 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2381 | 2461 | ||
2382 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); | 2462 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); |
2383 | 2463 | ||
2464 | if ((!edge_serial->is_epic) || | ||
2465 | ((edge_serial->is_epic) && | ||
2466 | (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && | ||
2467 | (regNum == MCR))) { | ||
2468 | dbg("SendCmdWriteUartReg - Not writting to MCR Register"); | ||
2469 | return 0; | ||
2470 | } | ||
2471 | |||
2472 | if ((!edge_serial->is_epic) || | ||
2473 | ((edge_serial->is_epic) && | ||
2474 | (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && | ||
2475 | (regNum == LCR))) { | ||
2476 | dbg ("SendCmdWriteUartReg - Not writting to LCR Register"); | ||
2477 | return 0; | ||
2478 | } | ||
2479 | |||
2384 | // Alloc memory for the string of commands. | 2480 | // Alloc memory for the string of commands. |
2385 | cmdBuffer = kmalloc (0x10, GFP_ATOMIC); | 2481 | cmdBuffer = kmalloc (0x10, GFP_ATOMIC); |
2386 | if (cmdBuffer == NULL ) { | 2482 | if (cmdBuffer == NULL ) { |
@@ -2414,6 +2510,7 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2414 | #endif | 2510 | #endif |
2415 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) | 2511 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) |
2416 | { | 2512 | { |
2513 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2417 | struct tty_struct *tty; | 2514 | struct tty_struct *tty; |
2418 | int baud; | 2515 | int baud; |
2419 | unsigned cflag; | 2516 | unsigned cflag; |
@@ -2494,8 +2591,12 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi | |||
2494 | unsigned char stop_char = STOP_CHAR(tty); | 2591 | unsigned char stop_char = STOP_CHAR(tty); |
2495 | unsigned char start_char = START_CHAR(tty); | 2592 | unsigned char start_char = START_CHAR(tty); |
2496 | 2593 | ||
2497 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XON_CHAR, start_char); | 2594 | if ((!edge_serial->is_epic) || |
2498 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); | 2595 | ((edge_serial->is_epic) && |
2596 | (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { | ||
2597 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char); | ||
2598 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); | ||
2599 | } | ||
2499 | 2600 | ||
2500 | /* if we are implementing INBOUND XON/XOFF */ | 2601 | /* if we are implementing INBOUND XON/XOFF */ |
2501 | if (I_IXOFF(tty)) { | 2602 | if (I_IXOFF(tty)) { |
@@ -2515,8 +2616,14 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi | |||
2515 | } | 2616 | } |
2516 | 2617 | ||
2517 | /* Set flow control to the configured value */ | 2618 | /* Set flow control to the configured value */ |
2518 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); | 2619 | if ((!edge_serial->is_epic) || |
2519 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); | 2620 | ((edge_serial->is_epic) && |
2621 | (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) | ||
2622 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); | ||
2623 | if ((!edge_serial->is_epic) || | ||
2624 | ((edge_serial->is_epic) && | ||
2625 | (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) | ||
2626 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); | ||
2520 | 2627 | ||
2521 | 2628 | ||
2522 | edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | 2629 | edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); |
@@ -2728,6 +2835,13 @@ static int edge_startup (struct usb_serial *serial) | |||
2728 | struct edgeport_port *edge_port; | 2835 | struct edgeport_port *edge_port; |
2729 | struct usb_device *dev; | 2836 | struct usb_device *dev; |
2730 | int i, j; | 2837 | int i, j; |
2838 | int response; | ||
2839 | int interrupt_in_found; | ||
2840 | int bulk_in_found; | ||
2841 | int bulk_out_found; | ||
2842 | static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, | ||
2843 | EDGE_COMPATIBILITY_MASK1, | ||
2844 | EDGE_COMPATIBILITY_MASK2 }; | ||
2731 | 2845 | ||
2732 | dev = serial->dev; | 2846 | dev = serial->dev; |
2733 | 2847 | ||
@@ -2750,38 +2864,50 @@ static int edge_startup (struct usb_serial *serial) | |||
2750 | 2864 | ||
2751 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); | 2865 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); |
2752 | 2866 | ||
2753 | /* get the manufacturing descriptor for this device */ | 2867 | /* Read the epic descriptor */ |
2754 | get_manufacturing_desc (edge_serial); | 2868 | if (get_epic_descriptor(edge_serial) <= 0) { |
2869 | /* memcpy descriptor to Supports structures */ | ||
2870 | memcpy(&edge_serial->epic_descriptor.Supports, descriptor, | ||
2871 | sizeof(struct edge_compatibility_bits)); | ||
2872 | |||
2873 | /* get the manufacturing descriptor for this device */ | ||
2874 | get_manufacturing_desc (edge_serial); | ||
2755 | 2875 | ||
2756 | /* get the boot descriptor */ | 2876 | /* get the boot descriptor */ |
2757 | get_boot_desc (edge_serial); | 2877 | get_boot_desc (edge_serial); |
2758 | 2878 | ||
2759 | get_product_info(edge_serial); | 2879 | get_product_info(edge_serial); |
2880 | } | ||
2760 | 2881 | ||
2761 | /* set the number of ports from the manufacturing description */ | 2882 | /* set the number of ports from the manufacturing description */ |
2762 | /* serial->num_ports = serial->product_info.NumPorts; */ | 2883 | /* serial->num_ports = serial->product_info.NumPorts; */ |
2763 | if (edge_serial->product_info.NumPorts != serial->num_ports) { | 2884 | if ((!edge_serial->is_epic) && |
2764 | warn("%s - Device Reported %d serial ports vs core " | 2885 | (edge_serial->product_info.NumPorts != serial->num_ports)) { |
2765 | "thinking we have %d ports, email greg@kroah.com this info.", | 2886 | dev_warn(&serial->dev->dev, "Device Reported %d serial ports " |
2766 | __FUNCTION__, edge_serial->product_info.NumPorts, | 2887 | "vs. core thinking we have %d ports, email " |
2767 | serial->num_ports); | 2888 | "greg@kroah.com this information.", |
2889 | edge_serial->product_info.NumPorts, | ||
2890 | serial->num_ports); | ||
2768 | } | 2891 | } |
2769 | 2892 | ||
2770 | dbg("%s - time 1 %ld", __FUNCTION__, jiffies); | 2893 | dbg("%s - time 1 %ld", __FUNCTION__, jiffies); |
2771 | 2894 | ||
2772 | /* now load the application firmware into this device */ | 2895 | /* If not an EPiC device */ |
2773 | load_application_firmware (edge_serial); | 2896 | if (!edge_serial->is_epic) { |
2897 | /* now load the application firmware into this device */ | ||
2898 | load_application_firmware (edge_serial); | ||
2774 | 2899 | ||
2775 | dbg("%s - time 2 %ld", __FUNCTION__, jiffies); | 2900 | dbg("%s - time 2 %ld", __FUNCTION__, jiffies); |
2776 | 2901 | ||
2777 | /* Check current Edgeport EEPROM and update if necessary */ | 2902 | /* Check current Edgeport EEPROM and update if necessary */ |
2778 | update_edgeport_E2PROM (edge_serial); | 2903 | update_edgeport_E2PROM (edge_serial); |
2779 | |||
2780 | dbg("%s - time 3 %ld", __FUNCTION__, jiffies); | ||
2781 | 2904 | ||
2782 | /* set the configuration to use #1 */ | 2905 | dbg("%s - time 3 %ld", __FUNCTION__, jiffies); |
2783 | // dbg("set_configuration 1"); | 2906 | |
2784 | // usb_set_configuration (dev, 1); | 2907 | /* set the configuration to use #1 */ |
2908 | // dbg("set_configuration 1"); | ||
2909 | // usb_set_configuration (dev, 1); | ||
2910 | } | ||
2785 | 2911 | ||
2786 | /* we set up the pointers to the endpoints in the edge_open function, | 2912 | /* we set up the pointers to the endpoints in the edge_open function, |
2787 | * as the structures aren't created yet. */ | 2913 | * as the structures aren't created yet. */ |
@@ -2804,8 +2930,101 @@ static int edge_startup (struct usb_serial *serial) | |||
2804 | edge_port->port = serial->port[i]; | 2930 | edge_port->port = serial->port[i]; |
2805 | usb_set_serial_port_data(serial->port[i], edge_port); | 2931 | usb_set_serial_port_data(serial->port[i], edge_port); |
2806 | } | 2932 | } |
2807 | 2933 | ||
2808 | return 0; | 2934 | response = 0; |
2935 | |||
2936 | if (edge_serial->is_epic) { | ||
2937 | /* EPIC thing, set up our interrupt polling now and our read urb, so | ||
2938 | * that the device knows it really is connected. */ | ||
2939 | interrupt_in_found = bulk_in_found = bulk_out_found = FALSE; | ||
2940 | for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) { | ||
2941 | struct usb_endpoint_descriptor *endpoint; | ||
2942 | int buffer_size; | ||
2943 | |||
2944 | endpoint = &serial->interface->altsetting[0].endpoint[i].desc; | ||
2945 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
2946 | if ((!interrupt_in_found) && | ||
2947 | (usb_endpoint_is_int_in(endpoint))) { | ||
2948 | /* we found a interrupt in endpoint */ | ||
2949 | dbg("found interrupt in"); | ||
2950 | |||
2951 | /* not set up yet, so do it now */ | ||
2952 | edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2953 | if (!edge_serial->interrupt_read_urb) { | ||
2954 | err("out of memory"); | ||
2955 | return -ENOMEM; | ||
2956 | } | ||
2957 | edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
2958 | if (!edge_serial->interrupt_in_buffer) { | ||
2959 | err("out of memory"); | ||
2960 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
2961 | return -ENOMEM; | ||
2962 | } | ||
2963 | edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress; | ||
2964 | |||
2965 | /* set up our interrupt urb */ | ||
2966 | usb_fill_int_urb(edge_serial->interrupt_read_urb, | ||
2967 | dev, | ||
2968 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
2969 | edge_serial->interrupt_in_buffer, | ||
2970 | buffer_size, | ||
2971 | edge_interrupt_callback, | ||
2972 | edge_serial, | ||
2973 | endpoint->bInterval); | ||
2974 | |||
2975 | interrupt_in_found = TRUE; | ||
2976 | } | ||
2977 | |||
2978 | if ((!bulk_in_found) && | ||
2979 | (usb_endpoint_is_bulk_in(endpoint))) { | ||
2980 | /* we found a bulk in endpoint */ | ||
2981 | dbg("found bulk in"); | ||
2982 | |||
2983 | /* not set up yet, so do it now */ | ||
2984 | edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2985 | if (!edge_serial->read_urb) { | ||
2986 | err("out of memory"); | ||
2987 | return -ENOMEM; | ||
2988 | } | ||
2989 | edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
2990 | if (!edge_serial->bulk_in_buffer) { | ||
2991 | err ("out of memory"); | ||
2992 | usb_free_urb(edge_serial->read_urb); | ||
2993 | return -ENOMEM; | ||
2994 | } | ||
2995 | edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress; | ||
2996 | |||
2997 | /* set up our bulk in urb */ | ||
2998 | usb_fill_bulk_urb(edge_serial->read_urb, dev, | ||
2999 | usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), | ||
3000 | edge_serial->bulk_in_buffer, | ||
3001 | endpoint->wMaxPacketSize, | ||
3002 | edge_bulk_in_callback, | ||
3003 | edge_serial); | ||
3004 | bulk_in_found = TRUE; | ||
3005 | } | ||
3006 | |||
3007 | if ((!bulk_out_found) && | ||
3008 | (usb_endpoint_is_bulk_out(endpoint))) { | ||
3009 | /* we found a bulk out endpoint */ | ||
3010 | dbg("found bulk out"); | ||
3011 | edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress; | ||
3012 | bulk_out_found = TRUE; | ||
3013 | } | ||
3014 | } | ||
3015 | |||
3016 | if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) { | ||
3017 | err ("Error - the proper endpoints were not found!"); | ||
3018 | return -ENODEV; | ||
3019 | } | ||
3020 | |||
3021 | /* start interrupt read for this edgeport this interrupt will | ||
3022 | * continue as long as the edgeport is connected */ | ||
3023 | response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL); | ||
3024 | if (response) | ||
3025 | err("%s - Error %d submitting control urb", __FUNCTION__, response); | ||
3026 | } | ||
3027 | return response; | ||
2809 | } | 3028 | } |
2810 | 3029 | ||
2811 | 3030 | ||
@@ -2815,6 +3034,7 @@ static int edge_startup (struct usb_serial *serial) | |||
2815 | ****************************************************************************/ | 3034 | ****************************************************************************/ |
2816 | static void edge_shutdown (struct usb_serial *serial) | 3035 | static void edge_shutdown (struct usb_serial *serial) |
2817 | { | 3036 | { |
3037 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); | ||
2818 | int i; | 3038 | int i; |
2819 | 3039 | ||
2820 | dbg("%s", __FUNCTION__); | 3040 | dbg("%s", __FUNCTION__); |
@@ -2824,7 +3044,18 @@ static void edge_shutdown (struct usb_serial *serial) | |||
2824 | kfree (usb_get_serial_port_data(serial->port[i])); | 3044 | kfree (usb_get_serial_port_data(serial->port[i])); |
2825 | usb_set_serial_port_data(serial->port[i], NULL); | 3045 | usb_set_serial_port_data(serial->port[i], NULL); |
2826 | } | 3046 | } |
2827 | kfree (usb_get_serial_data(serial)); | 3047 | /* free up our endpoint stuff */ |
3048 | if (edge_serial->is_epic) { | ||
3049 | usb_unlink_urb(edge_serial->interrupt_read_urb); | ||
3050 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
3051 | kfree(edge_serial->interrupt_in_buffer); | ||
3052 | |||
3053 | usb_unlink_urb(edge_serial->read_urb); | ||
3054 | usb_free_urb(edge_serial->read_urb); | ||
3055 | kfree(edge_serial->bulk_in_buffer); | ||
3056 | } | ||
3057 | |||
3058 | kfree(edge_serial); | ||
2828 | usb_set_serial_data(serial, NULL); | 3059 | usb_set_serial_data(serial, NULL); |
2829 | } | 3060 | } |
2830 | 3061 | ||
@@ -2846,6 +3077,9 @@ static int __init edgeport_init(void) | |||
2846 | retval = usb_serial_register(&edgeport_8port_device); | 3077 | retval = usb_serial_register(&edgeport_8port_device); |
2847 | if (retval) | 3078 | if (retval) |
2848 | goto failed_8port_device_register; | 3079 | goto failed_8port_device_register; |
3080 | retval = usb_serial_register(&epic_device); | ||
3081 | if (retval) | ||
3082 | goto failed_epic_device_register; | ||
2849 | retval = usb_register(&io_driver); | 3083 | retval = usb_register(&io_driver); |
2850 | if (retval) | 3084 | if (retval) |
2851 | goto failed_usb_register; | 3085 | goto failed_usb_register; |
@@ -2853,6 +3087,8 @@ static int __init edgeport_init(void) | |||
2853 | return 0; | 3087 | return 0; |
2854 | 3088 | ||
2855 | failed_usb_register: | 3089 | failed_usb_register: |
3090 | usb_serial_deregister(&epic_device); | ||
3091 | failed_epic_device_register: | ||
2856 | usb_serial_deregister(&edgeport_8port_device); | 3092 | usb_serial_deregister(&edgeport_8port_device); |
2857 | failed_8port_device_register: | 3093 | failed_8port_device_register: |
2858 | usb_serial_deregister(&edgeport_4port_device); | 3094 | usb_serial_deregister(&edgeport_4port_device); |
@@ -2873,6 +3109,7 @@ static void __exit edgeport_exit (void) | |||
2873 | usb_serial_deregister (&edgeport_2port_device); | 3109 | usb_serial_deregister (&edgeport_2port_device); |
2874 | usb_serial_deregister (&edgeport_4port_device); | 3110 | usb_serial_deregister (&edgeport_4port_device); |
2875 | usb_serial_deregister (&edgeport_8port_device); | 3111 | usb_serial_deregister (&edgeport_8port_device); |
3112 | usb_serial_deregister (&epic_device); | ||
2876 | } | 3113 | } |
2877 | 3114 | ||
2878 | module_init(edgeport_init); | 3115 | module_init(edgeport_init); |
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 123fa8a904e6..29a913a6daca 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h | |||
@@ -111,10 +111,12 @@ struct edgeport_product_info { | |||
111 | __le16 FirmwareBuildNumber; /* zzzz (LE format) */ | 111 | __le16 FirmwareBuildNumber; /* zzzz (LE format) */ |
112 | 112 | ||
113 | __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */ | 113 | __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */ |
114 | __u8 Unused1[1]; /* Available */ | 114 | __u8 HardwareType; |
115 | 115 | ||
116 | __u8 iDownloadFile; /* What to download to EPiC device */ | 116 | __u8 iDownloadFile; /* What to download to EPiC device */ |
117 | __u8 Unused2[2]; /* Available */ | 117 | __u8 EpicVer; /* What version of EPiC spec this device supports */ |
118 | |||
119 | struct edge_compatibility_bits Epic; | ||
118 | }; | 120 | }; |
119 | 121 | ||
120 | /* | 122 | /* |
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index fad561c04c76..6d3008772540 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h | |||
@@ -47,6 +47,18 @@ static struct usb_device_id edgeport_8port_id_table [] = { | |||
47 | { } | 47 | { } |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct usb_device_id Epic_port_id_table [] = { | ||
51 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, | ||
52 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, | ||
53 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, | ||
54 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, | ||
55 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, | ||
56 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, | ||
57 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, | ||
58 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, | ||
59 | { } | ||
60 | }; | ||
61 | |||
50 | /* Devices that this driver supports */ | 62 | /* Devices that this driver supports */ |
51 | static struct usb_device_id id_table_combined [] = { | 63 | static struct usb_device_id id_table_combined [] = { |
52 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, | 64 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, |
@@ -70,17 +82,34 @@ static struct usb_device_id id_table_combined [] = { | |||
70 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, | 82 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, |
71 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, | 83 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, |
72 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, | 84 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, |
85 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, | ||
86 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, | ||
87 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, | ||
88 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, | ||
89 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, | ||
90 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, | ||
91 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, | ||
92 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, | ||
73 | { } /* Terminating entry */ | 93 | { } /* Terminating entry */ |
74 | }; | 94 | }; |
75 | 95 | ||
76 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 96 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
77 | 97 | ||
98 | static struct usb_driver io_driver = { | ||
99 | .name = "io_edgeport", | ||
100 | .probe = usb_serial_probe, | ||
101 | .disconnect = usb_serial_disconnect, | ||
102 | .id_table = id_table_combined, | ||
103 | .no_dynamic_id = 1, | ||
104 | }; | ||
105 | |||
78 | static struct usb_serial_driver edgeport_2port_device = { | 106 | static struct usb_serial_driver edgeport_2port_device = { |
79 | .driver = { | 107 | .driver = { |
80 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
81 | .name = "edgeport_2", | 109 | .name = "edgeport_2", |
82 | }, | 110 | }, |
83 | .description = "Edgeport 2 port adapter", | 111 | .description = "Edgeport 2 port adapter", |
112 | .usb_driver = &io_driver, | ||
84 | .id_table = edgeport_2port_id_table, | 113 | .id_table = edgeport_2port_id_table, |
85 | .num_interrupt_in = 1, | 114 | .num_interrupt_in = 1, |
86 | .num_bulk_in = 1, | 115 | .num_bulk_in = 1, |
@@ -111,6 +140,7 @@ static struct usb_serial_driver edgeport_4port_device = { | |||
111 | .name = "edgeport_4", | 140 | .name = "edgeport_4", |
112 | }, | 141 | }, |
113 | .description = "Edgeport 4 port adapter", | 142 | .description = "Edgeport 4 port adapter", |
143 | .usb_driver = &io_driver, | ||
114 | .id_table = edgeport_4port_id_table, | 144 | .id_table = edgeport_4port_id_table, |
115 | .num_interrupt_in = 1, | 145 | .num_interrupt_in = 1, |
116 | .num_bulk_in = 1, | 146 | .num_bulk_in = 1, |
@@ -141,6 +171,7 @@ static struct usb_serial_driver edgeport_8port_device = { | |||
141 | .name = "edgeport_8", | 171 | .name = "edgeport_8", |
142 | }, | 172 | }, |
143 | .description = "Edgeport 8 port adapter", | 173 | .description = "Edgeport 8 port adapter", |
174 | .usb_driver = &io_driver, | ||
144 | .id_table = edgeport_8port_id_table, | 175 | .id_table = edgeport_8port_id_table, |
145 | .num_interrupt_in = 1, | 176 | .num_interrupt_in = 1, |
146 | .num_bulk_in = 1, | 177 | .num_bulk_in = 1, |
@@ -165,5 +196,35 @@ static struct usb_serial_driver edgeport_8port_device = { | |||
165 | .write_bulk_callback = edge_bulk_out_data_callback, | 196 | .write_bulk_callback = edge_bulk_out_data_callback, |
166 | }; | 197 | }; |
167 | 198 | ||
199 | static struct usb_serial_driver epic_device = { | ||
200 | .driver = { | ||
201 | .owner = THIS_MODULE, | ||
202 | .name = "epic", | ||
203 | }, | ||
204 | .description = "EPiC device", | ||
205 | .id_table = Epic_port_id_table, | ||
206 | .num_interrupt_in = 1, | ||
207 | .num_bulk_in = 1, | ||
208 | .num_bulk_out = 1, | ||
209 | .num_ports = 1, | ||
210 | .open = edge_open, | ||
211 | .close = edge_close, | ||
212 | .throttle = edge_throttle, | ||
213 | .unthrottle = edge_unthrottle, | ||
214 | .attach = edge_startup, | ||
215 | .shutdown = edge_shutdown, | ||
216 | .ioctl = edge_ioctl, | ||
217 | .set_termios = edge_set_termios, | ||
218 | .tiocmget = edge_tiocmget, | ||
219 | .tiocmset = edge_tiocmset, | ||
220 | .write = edge_write, | ||
221 | .write_room = edge_write_room, | ||
222 | .chars_in_buffer = edge_chars_in_buffer, | ||
223 | .break_ctl = edge_break, | ||
224 | .read_int_callback = edge_interrupt_callback, | ||
225 | .read_bulk_callback = edge_bulk_in_callback, | ||
226 | .write_bulk_callback = edge_bulk_out_data_callback, | ||
227 | }; | ||
228 | |||
168 | #endif | 229 | #endif |
169 | 230 | ||
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 980285c0233a..544098d2b775 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -2979,6 +2979,7 @@ static struct usb_serial_driver edgeport_1port_device = { | |||
2979 | .name = "edgeport_ti_1", | 2979 | .name = "edgeport_ti_1", |
2980 | }, | 2980 | }, |
2981 | .description = "Edgeport TI 1 port adapter", | 2981 | .description = "Edgeport TI 1 port adapter", |
2982 | .usb_driver = &io_driver, | ||
2982 | .id_table = edgeport_1port_id_table, | 2983 | .id_table = edgeport_1port_id_table, |
2983 | .num_interrupt_in = 1, | 2984 | .num_interrupt_in = 1, |
2984 | .num_bulk_in = 1, | 2985 | .num_bulk_in = 1, |
@@ -3009,6 +3010,7 @@ static struct usb_serial_driver edgeport_2port_device = { | |||
3009 | .name = "edgeport_ti_2", | 3010 | .name = "edgeport_ti_2", |
3010 | }, | 3011 | }, |
3011 | .description = "Edgeport TI 2 port adapter", | 3012 | .description = "Edgeport TI 2 port adapter", |
3013 | .usb_driver = &io_driver, | ||
3012 | .id_table = edgeport_2port_id_table, | 3014 | .id_table = edgeport_2port_id_table, |
3013 | .num_interrupt_in = 1, | 3015 | .num_interrupt_in = 1, |
3014 | .num_bulk_in = 2, | 3016 | .num_bulk_in = 2, |
diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h index f1804fd5a3dd..e57fa117e486 100644 --- a/drivers/usb/serial/io_usbvend.h +++ b/drivers/usb/serial/io_usbvend.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #define USB_VENDOR_ID_ION 0x1608 // Our VID | 31 | #define USB_VENDOR_ID_ION 0x1608 // Our VID |
32 | #define USB_VENDOR_ID_TI 0x0451 // TI VID | 32 | #define USB_VENDOR_ID_TI 0x0451 // TI VID |
33 | #define USB_VENDOR_ID_AXIOHM 0x05D9 /* Axiohm VID */ | ||
33 | 34 | ||
34 | // | 35 | // |
35 | // Definitions of USB product IDs (PID) | 36 | // Definitions of USB product IDs (PID) |
@@ -334,6 +335,10 @@ struct edge_compatibility_bits | |||
334 | 335 | ||
335 | }; | 336 | }; |
336 | 337 | ||
338 | #define EDGE_COMPATIBILITY_MASK0 0x0001 | ||
339 | #define EDGE_COMPATIBILITY_MASK1 0x3FFF | ||
340 | #define EDGE_COMPATIBILITY_MASK2 0x0001 | ||
341 | |||
337 | struct edge_compatibility_descriptor | 342 | struct edge_compatibility_descriptor |
338 | { | 343 | { |
339 | __u8 Length; // Descriptor Length (per USB spec) | 344 | __u8 Length; // Descriptor Length (per USB spec) |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 42f757a5b876..a408184334ea 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -563,6 +563,7 @@ static struct usb_serial_driver ipaq_device = { | |||
563 | .name = "ipaq", | 563 | .name = "ipaq", |
564 | }, | 564 | }, |
565 | .description = "PocketPC PDA", | 565 | .description = "PocketPC PDA", |
566 | .usb_driver = &ipaq_driver, | ||
566 | .id_table = ipaq_id_table, | 567 | .id_table = ipaq_id_table, |
567 | .num_interrupt_in = NUM_DONT_CARE, | 568 | .num_interrupt_in = NUM_DONT_CARE, |
568 | .num_bulk_in = 1, | 569 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index d3b9a351cef8..1bc586064c77 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -442,6 +442,7 @@ static struct usb_serial_driver ipw_device = { | |||
442 | .name = "ipw", | 442 | .name = "ipw", |
443 | }, | 443 | }, |
444 | .description = "IPWireless converter", | 444 | .description = "IPWireless converter", |
445 | .usb_driver = &usb_ipw_driver, | ||
445 | .id_table = usb_ipw_ids, | 446 | .id_table = usb_ipw_ids, |
446 | .num_interrupt_in = NUM_DONT_CARE, | 447 | .num_interrupt_in = NUM_DONT_CARE, |
447 | .num_bulk_in = 1, | 448 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 8fdf486e3465..9d847f69291c 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -138,6 +138,7 @@ static struct usb_serial_driver ir_device = { | |||
138 | .name = "ir-usb", | 138 | .name = "ir-usb", |
139 | }, | 139 | }, |
140 | .description = "IR Dongle", | 140 | .description = "IR Dongle", |
141 | .usb_driver = &ir_driver, | ||
141 | .id_table = id_table, | 142 | .id_table = id_table, |
142 | .num_interrupt_in = 1, | 143 | .num_interrupt_in = 1, |
143 | .num_bulk_in = 1, | 144 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 9d2fdfd6865f..e6966f12ed5a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -1275,11 +1275,31 @@ static int keyspan_fake_startup (struct usb_serial *serial) | |||
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | /* Helper functions used by keyspan_setup_urbs */ | 1277 | /* Helper functions used by keyspan_setup_urbs */ |
1278 | static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial, | ||
1279 | int endpoint) | ||
1280 | { | ||
1281 | struct usb_host_interface *iface_desc; | ||
1282 | struct usb_endpoint_descriptor *ep; | ||
1283 | int i; | ||
1284 | |||
1285 | iface_desc = serial->interface->cur_altsetting; | ||
1286 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
1287 | ep = &iface_desc->endpoint[i].desc; | ||
1288 | if (ep->bEndpointAddress == endpoint) | ||
1289 | return ep; | ||
1290 | } | ||
1291 | dev_warn(&serial->interface->dev, "found no endpoint descriptor for " | ||
1292 | "endpoint %x\n", endpoint); | ||
1293 | return NULL; | ||
1294 | } | ||
1295 | |||
1278 | static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, | 1296 | static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, |
1279 | int dir, void *ctx, char *buf, int len, | 1297 | int dir, void *ctx, char *buf, int len, |
1280 | void (*callback)(struct urb *)) | 1298 | void (*callback)(struct urb *)) |
1281 | { | 1299 | { |
1282 | struct urb *urb; | 1300 | struct urb *urb; |
1301 | struct usb_endpoint_descriptor const *ep_desc; | ||
1302 | char const *ep_type_name; | ||
1283 | 1303 | ||
1284 | if (endpoint == -1) | 1304 | if (endpoint == -1) |
1285 | return NULL; /* endpoint not needed */ | 1305 | return NULL; /* endpoint not needed */ |
@@ -1291,11 +1311,32 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, | |||
1291 | return NULL; | 1311 | return NULL; |
1292 | } | 1312 | } |
1293 | 1313 | ||
1294 | /* Fill URB using supplied data. */ | 1314 | ep_desc = find_ep(serial, endpoint); |
1295 | usb_fill_bulk_urb(urb, serial->dev, | 1315 | if (!ep_desc) { |
1296 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | 1316 | /* leak the urb, something's wrong and the callers don't care */ |
1297 | buf, len, callback, ctx); | 1317 | return urb; |
1318 | } | ||
1319 | if (usb_endpoint_xfer_int(ep_desc)) { | ||
1320 | ep_type_name = "INT"; | ||
1321 | usb_fill_int_urb(urb, serial->dev, | ||
1322 | usb_sndintpipe(serial->dev, endpoint) | dir, | ||
1323 | buf, len, callback, ctx, | ||
1324 | ep_desc->bInterval); | ||
1325 | } else if (usb_endpoint_xfer_bulk(ep_desc)) { | ||
1326 | ep_type_name = "BULK"; | ||
1327 | usb_fill_bulk_urb(urb, serial->dev, | ||
1328 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
1329 | buf, len, callback, ctx); | ||
1330 | } else { | ||
1331 | dev_warn(&serial->interface->dev, | ||
1332 | "unsupported endpoint type %x\n", | ||
1333 | ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
1334 | usb_free_urb(urb); | ||
1335 | return NULL; | ||
1336 | } | ||
1298 | 1337 | ||
1338 | dbg("%s - using urb %p for %s endpoint %x", | ||
1339 | __func__, urb, ep_type_name, endpoint); | ||
1299 | return urb; | 1340 | return urb; |
1300 | } | 1341 | } |
1301 | 1342 | ||
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 6413d73c139c..c6830cbdc6df 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -229,7 +229,6 @@ struct ezusb_hex_record { | |||
229 | #define keyspan_usa28_product_id 0x010f | 229 | #define keyspan_usa28_product_id 0x010f |
230 | #define keyspan_usa28x_product_id 0x0110 | 230 | #define keyspan_usa28x_product_id 0x0110 |
231 | #define keyspan_usa28xa_product_id 0x0115 | 231 | #define keyspan_usa28xa_product_id 0x0115 |
232 | #define keyspan_usa28xb_product_id 0x0110 | ||
233 | #define keyspan_usa49w_product_id 0x010a | 232 | #define keyspan_usa49w_product_id 0x010a |
234 | #define keyspan_usa49wlc_product_id 0x012a | 233 | #define keyspan_usa49wlc_product_id 0x012a |
235 | 234 | ||
@@ -511,7 +510,6 @@ static struct usb_device_id keyspan_ids_combined[] = { | |||
511 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, | 510 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, |
512 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, | 511 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, |
513 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, | 512 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, |
514 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) }, | ||
515 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, | 513 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, |
516 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, | 514 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, |
517 | { } /* Terminating entry */ | 515 | { } /* Terminating entry */ |
@@ -559,7 +557,6 @@ static struct usb_device_id keyspan_2port_ids[] = { | |||
559 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, | 557 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, |
560 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, | 558 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, |
561 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, | 559 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, |
562 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) }, | ||
563 | { } /* Terminating entry */ | 560 | { } /* Terminating entry */ |
564 | }; | 561 | }; |
565 | 562 | ||
@@ -576,6 +573,7 @@ static struct usb_serial_driver keyspan_pre_device = { | |||
576 | .name = "keyspan_no_firm", | 573 | .name = "keyspan_no_firm", |
577 | }, | 574 | }, |
578 | .description = "Keyspan - (without firmware)", | 575 | .description = "Keyspan - (without firmware)", |
576 | .usb_driver = &keyspan_driver, | ||
579 | .id_table = keyspan_pre_ids, | 577 | .id_table = keyspan_pre_ids, |
580 | .num_interrupt_in = NUM_DONT_CARE, | 578 | .num_interrupt_in = NUM_DONT_CARE, |
581 | .num_bulk_in = NUM_DONT_CARE, | 579 | .num_bulk_in = NUM_DONT_CARE, |
@@ -590,6 +588,7 @@ static struct usb_serial_driver keyspan_1port_device = { | |||
590 | .name = "keyspan_1", | 588 | .name = "keyspan_1", |
591 | }, | 589 | }, |
592 | .description = "Keyspan 1 port adapter", | 590 | .description = "Keyspan 1 port adapter", |
591 | .usb_driver = &keyspan_driver, | ||
593 | .id_table = keyspan_1port_ids, | 592 | .id_table = keyspan_1port_ids, |
594 | .num_interrupt_in = NUM_DONT_CARE, | 593 | .num_interrupt_in = NUM_DONT_CARE, |
595 | .num_bulk_in = NUM_DONT_CARE, | 594 | .num_bulk_in = NUM_DONT_CARE, |
@@ -617,6 +616,7 @@ static struct usb_serial_driver keyspan_2port_device = { | |||
617 | .name = "keyspan_2", | 616 | .name = "keyspan_2", |
618 | }, | 617 | }, |
619 | .description = "Keyspan 2 port adapter", | 618 | .description = "Keyspan 2 port adapter", |
619 | .usb_driver = &keyspan_driver, | ||
620 | .id_table = keyspan_2port_ids, | 620 | .id_table = keyspan_2port_ids, |
621 | .num_interrupt_in = NUM_DONT_CARE, | 621 | .num_interrupt_in = NUM_DONT_CARE, |
622 | .num_bulk_in = NUM_DONT_CARE, | 622 | .num_bulk_in = NUM_DONT_CARE, |
@@ -644,6 +644,7 @@ static struct usb_serial_driver keyspan_4port_device = { | |||
644 | .name = "keyspan_4", | 644 | .name = "keyspan_4", |
645 | }, | 645 | }, |
646 | .description = "Keyspan 4 port adapter", | 646 | .description = "Keyspan 4 port adapter", |
647 | .usb_driver = &keyspan_driver, | ||
647 | .id_table = keyspan_4port_ids, | 648 | .id_table = keyspan_4port_ids, |
648 | .num_interrupt_in = NUM_DONT_CARE, | 649 | .num_interrupt_in = NUM_DONT_CARE, |
649 | .num_bulk_in = 5, | 650 | .num_bulk_in = 5, |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 126b9703bbaf..da514cb785b3 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -793,6 +793,7 @@ static struct usb_serial_driver keyspan_pda_fake_device = { | |||
793 | .name = "keyspan_pda_pre", | 793 | .name = "keyspan_pda_pre", |
794 | }, | 794 | }, |
795 | .description = "Keyspan PDA - (prerenumeration)", | 795 | .description = "Keyspan PDA - (prerenumeration)", |
796 | .usb_driver = &keyspan_pda_driver, | ||
796 | .id_table = id_table_fake, | 797 | .id_table = id_table_fake, |
797 | .num_interrupt_in = NUM_DONT_CARE, | 798 | .num_interrupt_in = NUM_DONT_CARE, |
798 | .num_bulk_in = NUM_DONT_CARE, | 799 | .num_bulk_in = NUM_DONT_CARE, |
@@ -809,6 +810,7 @@ static struct usb_serial_driver xircom_pgs_fake_device = { | |||
809 | .name = "xircom_no_firm", | 810 | .name = "xircom_no_firm", |
810 | }, | 811 | }, |
811 | .description = "Xircom / Entregra PGS - (prerenumeration)", | 812 | .description = "Xircom / Entregra PGS - (prerenumeration)", |
813 | .usb_driver = &keyspan_pda_driver, | ||
812 | .id_table = id_table_fake_xircom, | 814 | .id_table = id_table_fake_xircom, |
813 | .num_interrupt_in = NUM_DONT_CARE, | 815 | .num_interrupt_in = NUM_DONT_CARE, |
814 | .num_bulk_in = NUM_DONT_CARE, | 816 | .num_bulk_in = NUM_DONT_CARE, |
@@ -824,6 +826,7 @@ static struct usb_serial_driver keyspan_pda_device = { | |||
824 | .name = "keyspan_pda", | 826 | .name = "keyspan_pda", |
825 | }, | 827 | }, |
826 | .description = "Keyspan PDA", | 828 | .description = "Keyspan PDA", |
829 | .usb_driver = &keyspan_pda_driver, | ||
827 | .id_table = id_table_std, | 830 | .id_table = id_table_std, |
828 | .num_interrupt_in = 1, | 831 | .num_interrupt_in = 1, |
829 | .num_bulk_in = 0, | 832 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 5c4b06a99ac0..b2097c45a235 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -124,6 +124,7 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
124 | .name = "kl5kusb105d", | 124 | .name = "kl5kusb105d", |
125 | }, | 125 | }, |
126 | .description = "KL5KUSB105D / PalmConnect", | 126 | .description = "KL5KUSB105D / PalmConnect", |
127 | .usb_driver = &kl5kusb105d_driver, | ||
127 | .id_table = id_table, | 128 | .id_table = id_table, |
128 | .num_interrupt_in = 1, | 129 | .num_interrupt_in = 1, |
129 | .num_bulk_in = 1, | 130 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 62bea0c923bd..0683b51f0932 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -110,6 +110,7 @@ static struct usb_serial_driver kobil_device = { | |||
110 | .name = "kobil", | 110 | .name = "kobil", |
111 | }, | 111 | }, |
112 | .description = "KOBIL USB smart card terminal", | 112 | .description = "KOBIL USB smart card terminal", |
113 | .usb_driver = &kobil_driver, | ||
113 | .id_table = id_table, | 114 | .id_table = id_table, |
114 | .num_interrupt_in = NUM_DONT_CARE, | 115 | .num_interrupt_in = NUM_DONT_CARE, |
115 | .num_bulk_in = 0, | 116 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 38b1d17e06ef..4cd839b1407f 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -137,6 +137,7 @@ static struct usb_serial_driver mct_u232_device = { | |||
137 | .name = "mct_u232", | 137 | .name = "mct_u232", |
138 | }, | 138 | }, |
139 | .description = "MCT U232", | 139 | .description = "MCT U232", |
140 | .usb_driver = &mct_u232_driver, | ||
140 | .id_table = id_table_combined, | 141 | .id_table = id_table_combined, |
141 | .num_interrupt_in = 2, | 142 | .num_interrupt_in = 2, |
142 | .num_bulk_in = 0, | 143 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e55f4ed81d7b..6109c6704a73 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -1605,12 +1605,21 @@ static void mos7720_shutdown(struct usb_serial *serial) | |||
1605 | usb_set_serial_data(serial, NULL); | 1605 | usb_set_serial_data(serial, NULL); |
1606 | } | 1606 | } |
1607 | 1607 | ||
1608 | static struct usb_driver usb_driver = { | ||
1609 | .name = "moschip7720", | ||
1610 | .probe = usb_serial_probe, | ||
1611 | .disconnect = usb_serial_disconnect, | ||
1612 | .id_table = moschip_port_id_table, | ||
1613 | .no_dynamic_id = 1, | ||
1614 | }; | ||
1615 | |||
1608 | static struct usb_serial_driver moschip7720_2port_driver = { | 1616 | static struct usb_serial_driver moschip7720_2port_driver = { |
1609 | .driver = { | 1617 | .driver = { |
1610 | .owner = THIS_MODULE, | 1618 | .owner = THIS_MODULE, |
1611 | .name = "moschip7720", | 1619 | .name = "moschip7720", |
1612 | }, | 1620 | }, |
1613 | .description = "Moschip 2 port adapter", | 1621 | .description = "Moschip 2 port adapter", |
1622 | .usb_driver = &usb_driver, | ||
1614 | .id_table = moschip_port_id_table, | 1623 | .id_table = moschip_port_id_table, |
1615 | .num_interrupt_in = 1, | 1624 | .num_interrupt_in = 1, |
1616 | .num_bulk_in = 2, | 1625 | .num_bulk_in = 2, |
@@ -1631,13 +1640,6 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
1631 | .read_bulk_callback = mos7720_bulk_in_callback, | 1640 | .read_bulk_callback = mos7720_bulk_in_callback, |
1632 | }; | 1641 | }; |
1633 | 1642 | ||
1634 | static struct usb_driver usb_driver = { | ||
1635 | .name = "moschip7720", | ||
1636 | .probe = usb_serial_probe, | ||
1637 | .disconnect = usb_serial_disconnect, | ||
1638 | .id_table = moschip_port_id_table, | ||
1639 | }; | ||
1640 | |||
1641 | static int __init moschip7720_init(void) | 1643 | static int __init moschip7720_init(void) |
1642 | { | 1644 | { |
1643 | int retval; | 1645 | int retval; |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 83f661403ba1..b2264a87617b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -2834,12 +2834,21 @@ static void mos7840_shutdown(struct usb_serial *serial) | |||
2834 | 2834 | ||
2835 | } | 2835 | } |
2836 | 2836 | ||
2837 | static struct usb_driver io_driver = { | ||
2838 | .name = "mos7840", | ||
2839 | .probe = usb_serial_probe, | ||
2840 | .disconnect = usb_serial_disconnect, | ||
2841 | .id_table = moschip_id_table_combined, | ||
2842 | .no_dynamic_id = 1, | ||
2843 | }; | ||
2844 | |||
2837 | static struct usb_serial_driver moschip7840_4port_device = { | 2845 | static struct usb_serial_driver moschip7840_4port_device = { |
2838 | .driver = { | 2846 | .driver = { |
2839 | .owner = THIS_MODULE, | 2847 | .owner = THIS_MODULE, |
2840 | .name = "mos7840", | 2848 | .name = "mos7840", |
2841 | }, | 2849 | }, |
2842 | .description = DRIVER_DESC, | 2850 | .description = DRIVER_DESC, |
2851 | .usb_driver = &io_driver, | ||
2843 | .id_table = moschip_port_id_table, | 2852 | .id_table = moschip_port_id_table, |
2844 | .num_interrupt_in = 1, //NUM_DONT_CARE,//1, | 2853 | .num_interrupt_in = 1, //NUM_DONT_CARE,//1, |
2845 | #ifdef check | 2854 | #ifdef check |
@@ -2869,13 +2878,6 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2869 | .read_int_callback = mos7840_interrupt_callback, | 2878 | .read_int_callback = mos7840_interrupt_callback, |
2870 | }; | 2879 | }; |
2871 | 2880 | ||
2872 | static struct usb_driver io_driver = { | ||
2873 | .name = "mos7840", | ||
2874 | .probe = usb_serial_probe, | ||
2875 | .disconnect = usb_serial_disconnect, | ||
2876 | .id_table = moschip_id_table_combined, | ||
2877 | }; | ||
2878 | |||
2879 | /**************************************************************************** | 2881 | /**************************************************************************** |
2880 | * moschip7840_init | 2882 | * moschip7840_init |
2881 | * This is called by the module subsystem, or on startup to initialize us | 2883 | * This is called by the module subsystem, or on startup to initialize us |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 054abee81652..90701111d746 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -119,6 +119,7 @@ static struct usb_serial_driver navman_device = { | |||
119 | .name = "navman", | 119 | .name = "navman", |
120 | }, | 120 | }, |
121 | .id_table = id_table, | 121 | .id_table = id_table, |
122 | .usb_driver = &navman_driver, | ||
122 | .num_interrupt_in = NUM_DONT_CARE, | 123 | .num_interrupt_in = NUM_DONT_CARE, |
123 | .num_bulk_in = NUM_DONT_CARE, | 124 | .num_bulk_in = NUM_DONT_CARE, |
124 | .num_bulk_out = NUM_DONT_CARE, | 125 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index bc91d3b726fc..0216ac12a27d 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -93,6 +93,7 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
93 | .name = "omninet", | 93 | .name = "omninet", |
94 | }, | 94 | }, |
95 | .description = "ZyXEL - omni.net lcd plus usb", | 95 | .description = "ZyXEL - omni.net lcd plus usb", |
96 | .usb_driver = &omninet_driver, | ||
96 | .id_table = id_table, | 97 | .id_table = id_table, |
97 | .num_interrupt_in = 1, | 98 | .num_interrupt_in = 1, |
98 | .num_bulk_in = 1, | 99 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0fed43a96871..ced9f32b29d9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -135,6 +135,7 @@ static struct usb_serial_driver option_1port_device = { | |||
135 | .name = "option1", | 135 | .name = "option1", |
136 | }, | 136 | }, |
137 | .description = "GSM modem (1-port)", | 137 | .description = "GSM modem (1-port)", |
138 | .usb_driver = &option_driver, | ||
138 | .id_table = option_ids1, | 139 | .id_table = option_ids1, |
139 | .num_interrupt_in = NUM_DONT_CARE, | 140 | .num_interrupt_in = NUM_DONT_CARE, |
140 | .num_bulk_in = NUM_DONT_CARE, | 141 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 5dc2ac9afa90..6c083d4e2c9b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -1118,6 +1118,7 @@ static struct usb_serial_driver pl2303_device = { | |||
1118 | .name = "pl2303", | 1118 | .name = "pl2303", |
1119 | }, | 1119 | }, |
1120 | .id_table = id_table, | 1120 | .id_table = id_table, |
1121 | .usb_driver = &pl2303_driver, | ||
1121 | .num_interrupt_in = NUM_DONT_CARE, | 1122 | .num_interrupt_in = NUM_DONT_CARE, |
1122 | .num_bulk_in = 1, | 1123 | .num_bulk_in = 1, |
1123 | .num_bulk_out = 1, | 1124 | .num_bulk_out = 1, |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 30b7ebc8d45d..5a03a3fc9386 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -402,6 +402,7 @@ static struct usb_serial_driver safe_device = { | |||
402 | .name = "safe_serial", | 402 | .name = "safe_serial", |
403 | }, | 403 | }, |
404 | .id_table = id_table, | 404 | .id_table = id_table, |
405 | .usb_driver = &safe_driver, | ||
405 | .num_interrupt_in = NUM_DONT_CARE, | 406 | .num_interrupt_in = NUM_DONT_CARE, |
406 | .num_bulk_in = NUM_DONT_CARE, | 407 | .num_bulk_in = NUM_DONT_CARE, |
407 | .num_bulk_out = NUM_DONT_CARE, | 408 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 6d8e91e00ecf..ecedd833818d 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -13,10 +13,9 @@ | |||
13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> | 13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> |
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | 15 | ||
16 | History: | ||
17 | */ | 16 | */ |
18 | 17 | ||
19 | #define DRIVER_VERSION "v.1.0.5" | 18 | #define DRIVER_VERSION "v.1.0.6" |
20 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" | 19 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" |
21 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 20 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
22 | 21 | ||
@@ -31,14 +30,15 @@ | |||
31 | 30 | ||
32 | 31 | ||
33 | static struct usb_device_id id_table [] = { | 32 | static struct usb_device_id id_table [] = { |
33 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
35 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
35 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 36 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
36 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
38 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 38 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
39 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 39 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
40 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
40 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 41 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
41 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ | ||
42 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 42 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ |
43 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 43 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
44 | 44 | ||
@@ -55,14 +55,15 @@ static struct usb_device_id id_table_1port [] = { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | static struct usb_device_id id_table_3port [] = { | 57 | static struct usb_device_id id_table_3port [] = { |
58 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
58 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 59 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
60 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
59 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 61 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
60 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
61 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 62 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
62 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 63 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
63 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 64 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
65 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
64 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 66 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
65 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ | ||
66 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 67 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ |
67 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 68 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
68 | { } | 69 | { } |
@@ -81,7 +82,7 @@ static int debug; | |||
81 | 82 | ||
82 | /* per port private data */ | 83 | /* per port private data */ |
83 | #define N_IN_URB 4 | 84 | #define N_IN_URB 4 |
84 | #define N_OUT_URB 1 | 85 | #define N_OUT_URB 4 |
85 | #define IN_BUFLEN 4096 | 86 | #define IN_BUFLEN 4096 |
86 | #define OUT_BUFLEN 128 | 87 | #define OUT_BUFLEN 128 |
87 | 88 | ||
@@ -396,6 +397,8 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
396 | struct usb_serial *serial = port->serial; | 397 | struct usb_serial *serial = port->serial; |
397 | int i, err; | 398 | int i, err; |
398 | struct urb *urb; | 399 | struct urb *urb; |
400 | int result; | ||
401 | __u16 set_mode_dzero = 0x0000; | ||
399 | 402 | ||
400 | portdata = usb_get_serial_port_data(port); | 403 | portdata = usb_get_serial_port_data(port); |
401 | 404 | ||
@@ -442,6 +445,12 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
442 | 445 | ||
443 | port->tty->low_latency = 1; | 446 | port->tty->low_latency = 1; |
444 | 447 | ||
448 | /* set mode to D0 */ | ||
449 | result = usb_control_msg(serial->dev, | ||
450 | usb_rcvctrlpipe(serial->dev, 0), | ||
451 | 0x00, 0x40, set_mode_dzero, 0, NULL, | ||
452 | 0, USB_CTRL_SET_TIMEOUT); | ||
453 | |||
445 | sierra_send_setup(port); | 454 | sierra_send_setup(port); |
446 | 455 | ||
447 | return (0); | 456 | return (0); |
@@ -614,6 +623,7 @@ static struct usb_serial_driver sierra_1port_device = { | |||
614 | }, | 623 | }, |
615 | .description = "Sierra USB modem (1 port)", | 624 | .description = "Sierra USB modem (1 port)", |
616 | .id_table = id_table_1port, | 625 | .id_table = id_table_1port, |
626 | .usb_driver = &sierra_driver, | ||
617 | .num_interrupt_in = NUM_DONT_CARE, | 627 | .num_interrupt_in = NUM_DONT_CARE, |
618 | .num_bulk_in = 1, | 628 | .num_bulk_in = 1, |
619 | .num_bulk_out = 1, | 629 | .num_bulk_out = 1, |
@@ -642,6 +652,7 @@ static struct usb_serial_driver sierra_3port_device = { | |||
642 | }, | 652 | }, |
643 | .description = "Sierra USB modem (3 port)", | 653 | .description = "Sierra USB modem (3 port)", |
644 | .id_table = id_table_3port, | 654 | .id_table = id_table_3port, |
655 | .usb_driver = &sierra_driver, | ||
645 | .num_interrupt_in = NUM_DONT_CARE, | 656 | .num_interrupt_in = NUM_DONT_CARE, |
646 | .num_bulk_in = 3, | 657 | .num_bulk_in = 3, |
647 | .num_bulk_out = 3, | 658 | .num_bulk_out = 3, |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 83189005c6fb..4203e2b1a761 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -262,6 +262,7 @@ static struct usb_serial_driver ti_1port_device = { | |||
262 | .name = "ti_usb_3410_5052_1", | 262 | .name = "ti_usb_3410_5052_1", |
263 | }, | 263 | }, |
264 | .description = "TI USB 3410 1 port adapter", | 264 | .description = "TI USB 3410 1 port adapter", |
265 | .usb_driver = &ti_usb_driver, | ||
265 | .id_table = ti_id_table_3410, | 266 | .id_table = ti_id_table_3410, |
266 | .num_interrupt_in = 1, | 267 | .num_interrupt_in = 1, |
267 | .num_bulk_in = 1, | 268 | .num_bulk_in = 1, |
@@ -292,6 +293,7 @@ static struct usb_serial_driver ti_2port_device = { | |||
292 | .name = "ti_usb_3410_5052_2", | 293 | .name = "ti_usb_3410_5052_2", |
293 | }, | 294 | }, |
294 | .description = "TI USB 5052 2 port adapter", | 295 | .description = "TI USB 5052 2 port adapter", |
296 | .usb_driver = &ti_usb_driver, | ||
295 | .id_table = ti_id_table_5052, | 297 | .id_table = ti_id_table_5052, |
296 | .num_interrupt_in = 1, | 298 | .num_interrupt_in = 1, |
297 | .num_bulk_in = 2, | 299 | .num_bulk_in = 2, |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 716f6806cc89..6bf22a28adb8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -59,14 +59,19 @@ static struct usb_driver usb_serial_driver = { | |||
59 | 59 | ||
60 | static int debug; | 60 | static int debug; |
61 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ | 61 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ |
62 | static spinlock_t table_lock; | ||
62 | static LIST_HEAD(usb_serial_driver_list); | 63 | static LIST_HEAD(usb_serial_driver_list); |
63 | 64 | ||
64 | struct usb_serial *usb_serial_get_by_index(unsigned index) | 65 | struct usb_serial *usb_serial_get_by_index(unsigned index) |
65 | { | 66 | { |
66 | struct usb_serial *serial = serial_table[index]; | 67 | struct usb_serial *serial; |
68 | |||
69 | spin_lock(&table_lock); | ||
70 | serial = serial_table[index]; | ||
67 | 71 | ||
68 | if (serial) | 72 | if (serial) |
69 | kref_get(&serial->kref); | 73 | kref_get(&serial->kref); |
74 | spin_unlock(&table_lock); | ||
70 | return serial; | 75 | return serial; |
71 | } | 76 | } |
72 | 77 | ||
@@ -78,6 +83,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po | |||
78 | dbg("%s %d", __FUNCTION__, num_ports); | 83 | dbg("%s %d", __FUNCTION__, num_ports); |
79 | 84 | ||
80 | *minor = 0; | 85 | *minor = 0; |
86 | spin_lock(&table_lock); | ||
81 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { | 87 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
82 | if (serial_table[i]) | 88 | if (serial_table[i]) |
83 | continue; | 89 | continue; |
@@ -96,8 +102,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po | |||
96 | dbg("%s - minor base = %d", __FUNCTION__, *minor); | 102 | dbg("%s - minor base = %d", __FUNCTION__, *minor); |
97 | for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) | 103 | for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) |
98 | serial_table[i] = serial; | 104 | serial_table[i] = serial; |
105 | spin_unlock(&table_lock); | ||
99 | return serial; | 106 | return serial; |
100 | } | 107 | } |
108 | spin_unlock(&table_lock); | ||
101 | return NULL; | 109 | return NULL; |
102 | } | 110 | } |
103 | 111 | ||
@@ -110,9 +118,11 @@ static void return_serial(struct usb_serial *serial) | |||
110 | if (serial == NULL) | 118 | if (serial == NULL) |
111 | return; | 119 | return; |
112 | 120 | ||
121 | spin_lock(&table_lock); | ||
113 | for (i = 0; i < serial->num_ports; ++i) { | 122 | for (i = 0; i < serial->num_ports; ++i) { |
114 | serial_table[serial->minor + i] = NULL; | 123 | serial_table[serial->minor + i] = NULL; |
115 | } | 124 | } |
125 | spin_unlock(&table_lock); | ||
116 | } | 126 | } |
117 | 127 | ||
118 | static void destroy_serial(struct kref *kref) | 128 | static void destroy_serial(struct kref *kref) |
@@ -271,7 +281,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
271 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) | 281 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) |
272 | { | 282 | { |
273 | struct usb_serial_port *port = tty->driver_data; | 283 | struct usb_serial_port *port = tty->driver_data; |
274 | int retval = -EINVAL; | 284 | int retval = -ENODEV; |
275 | 285 | ||
276 | if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) | 286 | if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) |
277 | goto exit; | 287 | goto exit; |
@@ -279,6 +289,7 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int | |||
279 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); | 289 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
280 | 290 | ||
281 | if (!port->open_count) { | 291 | if (!port->open_count) { |
292 | retval = -EINVAL; | ||
282 | dbg("%s - port not opened", __FUNCTION__); | 293 | dbg("%s - port not opened", __FUNCTION__); |
283 | goto exit; | 294 | goto exit; |
284 | } | 295 | } |
@@ -559,15 +570,20 @@ static void port_release(struct device *dev) | |||
559 | port_free(port); | 570 | port_free(port); |
560 | } | 571 | } |
561 | 572 | ||
562 | static void port_free(struct usb_serial_port *port) | 573 | static void kill_traffic(struct usb_serial_port *port) |
563 | { | 574 | { |
564 | usb_kill_urb(port->read_urb); | 575 | usb_kill_urb(port->read_urb); |
565 | usb_free_urb(port->read_urb); | ||
566 | usb_kill_urb(port->write_urb); | 576 | usb_kill_urb(port->write_urb); |
567 | usb_free_urb(port->write_urb); | ||
568 | usb_kill_urb(port->interrupt_in_urb); | 577 | usb_kill_urb(port->interrupt_in_urb); |
569 | usb_free_urb(port->interrupt_in_urb); | ||
570 | usb_kill_urb(port->interrupt_out_urb); | 578 | usb_kill_urb(port->interrupt_out_urb); |
579 | } | ||
580 | |||
581 | static void port_free(struct usb_serial_port *port) | ||
582 | { | ||
583 | kill_traffic(port); | ||
584 | usb_free_urb(port->read_urb); | ||
585 | usb_free_urb(port->write_urb); | ||
586 | usb_free_urb(port->interrupt_in_urb); | ||
571 | usb_free_urb(port->interrupt_out_urb); | 587 | usb_free_urb(port->interrupt_out_urb); |
572 | kfree(port->bulk_in_buffer); | 588 | kfree(port->bulk_in_buffer); |
573 | kfree(port->bulk_out_buffer); | 589 | kfree(port->bulk_out_buffer); |
@@ -596,6 +612,39 @@ static struct usb_serial * create_serial (struct usb_device *dev, | |||
596 | return serial; | 612 | return serial; |
597 | } | 613 | } |
598 | 614 | ||
615 | static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf, | ||
616 | struct usb_serial_driver *drv) | ||
617 | { | ||
618 | struct usb_dynid *dynid; | ||
619 | |||
620 | spin_lock(&drv->dynids.lock); | ||
621 | list_for_each_entry(dynid, &drv->dynids.list, node) { | ||
622 | if (usb_match_one_id(intf, &dynid->id)) { | ||
623 | spin_unlock(&drv->dynids.lock); | ||
624 | return &dynid->id; | ||
625 | } | ||
626 | } | ||
627 | spin_unlock(&drv->dynids.lock); | ||
628 | return NULL; | ||
629 | } | ||
630 | |||
631 | static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, | ||
632 | struct usb_interface *intf) | ||
633 | { | ||
634 | const struct usb_device_id *id; | ||
635 | |||
636 | id = usb_match_id(intf, drv->id_table); | ||
637 | if (id) { | ||
638 | dbg("static descriptor matches"); | ||
639 | goto exit; | ||
640 | } | ||
641 | id = match_dynamic_id(intf, drv); | ||
642 | if (id) | ||
643 | dbg("dynamic descriptor matches"); | ||
644 | exit: | ||
645 | return id; | ||
646 | } | ||
647 | |||
599 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) | 648 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) |
600 | { | 649 | { |
601 | struct list_head *p; | 650 | struct list_head *p; |
@@ -605,11 +654,9 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac | |||
605 | /* Check if the usb id matches a known device */ | 654 | /* Check if the usb id matches a known device */ |
606 | list_for_each(p, &usb_serial_driver_list) { | 655 | list_for_each(p, &usb_serial_driver_list) { |
607 | t = list_entry(p, struct usb_serial_driver, driver_list); | 656 | t = list_entry(p, struct usb_serial_driver, driver_list); |
608 | id = usb_match_id(iface, t->id_table); | 657 | id = get_iface_id(t, iface); |
609 | if (id != NULL) { | 658 | if (id) |
610 | dbg("descriptor matches"); | ||
611 | return t; | 659 | return t; |
612 | } | ||
613 | } | 660 | } |
614 | 661 | ||
615 | return NULL; | 662 | return NULL; |
@@ -639,14 +686,17 @@ int usb_serial_probe(struct usb_interface *interface, | |||
639 | int num_ports = 0; | 686 | int num_ports = 0; |
640 | int max_endpoints; | 687 | int max_endpoints; |
641 | 688 | ||
689 | lock_kernel(); /* guard against unloading a serial driver module */ | ||
642 | type = search_serial_device(interface); | 690 | type = search_serial_device(interface); |
643 | if (!type) { | 691 | if (!type) { |
692 | unlock_kernel(); | ||
644 | dbg("none matched"); | 693 | dbg("none matched"); |
645 | return -ENODEV; | 694 | return -ENODEV; |
646 | } | 695 | } |
647 | 696 | ||
648 | serial = create_serial (dev, interface, type); | 697 | serial = create_serial (dev, interface, type); |
649 | if (!serial) { | 698 | if (!serial) { |
699 | unlock_kernel(); | ||
650 | dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); | 700 | dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); |
651 | return -ENOMEM; | 701 | return -ENOMEM; |
652 | } | 702 | } |
@@ -656,16 +706,18 @@ int usb_serial_probe(struct usb_interface *interface, | |||
656 | const struct usb_device_id *id; | 706 | const struct usb_device_id *id; |
657 | 707 | ||
658 | if (!try_module_get(type->driver.owner)) { | 708 | if (!try_module_get(type->driver.owner)) { |
709 | unlock_kernel(); | ||
659 | dev_err(&interface->dev, "module get failed, exiting\n"); | 710 | dev_err(&interface->dev, "module get failed, exiting\n"); |
660 | kfree (serial); | 711 | kfree (serial); |
661 | return -EIO; | 712 | return -EIO; |
662 | } | 713 | } |
663 | 714 | ||
664 | id = usb_match_id(interface, type->id_table); | 715 | id = get_iface_id(type, interface); |
665 | retval = type->probe(serial, id); | 716 | retval = type->probe(serial, id); |
666 | module_put(type->driver.owner); | 717 | module_put(type->driver.owner); |
667 | 718 | ||
668 | if (retval) { | 719 | if (retval) { |
720 | unlock_kernel(); | ||
669 | dbg ("sub driver rejected device"); | 721 | dbg ("sub driver rejected device"); |
670 | kfree (serial); | 722 | kfree (serial); |
671 | return retval; | 723 | return retval; |
@@ -735,6 +787,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
735 | * properly during a later invocation of usb_serial_probe | 787 | * properly during a later invocation of usb_serial_probe |
736 | */ | 788 | */ |
737 | if (num_bulk_in == 0 || num_bulk_out == 0) { | 789 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
790 | unlock_kernel(); | ||
738 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); | 791 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
739 | kfree (serial); | 792 | kfree (serial); |
740 | return -ENODEV; | 793 | return -ENODEV; |
@@ -750,6 +803,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
750 | if (type == &usb_serial_generic_device) { | 803 | if (type == &usb_serial_generic_device) { |
751 | num_ports = num_bulk_out; | 804 | num_ports = num_bulk_out; |
752 | if (num_ports == 0) { | 805 | if (num_ports == 0) { |
806 | unlock_kernel(); | ||
753 | dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); | 807 | dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); |
754 | kfree (serial); | 808 | kfree (serial); |
755 | return -EIO; | 809 | return -EIO; |
@@ -760,6 +814,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
760 | /* if this device type has a calc_num_ports function, call it */ | 814 | /* if this device type has a calc_num_ports function, call it */ |
761 | if (type->calc_num_ports) { | 815 | if (type->calc_num_ports) { |
762 | if (!try_module_get(type->driver.owner)) { | 816 | if (!try_module_get(type->driver.owner)) { |
817 | unlock_kernel(); | ||
763 | dev_err(&interface->dev, "module get failed, exiting\n"); | 818 | dev_err(&interface->dev, "module get failed, exiting\n"); |
764 | kfree (serial); | 819 | kfree (serial); |
765 | return -EIO; | 820 | return -EIO; |
@@ -771,12 +826,6 @@ int usb_serial_probe(struct usb_interface *interface, | |||
771 | num_ports = type->num_ports; | 826 | num_ports = type->num_ports; |
772 | } | 827 | } |
773 | 828 | ||
774 | if (get_free_serial (serial, num_ports, &minor) == NULL) { | ||
775 | dev_err(&interface->dev, "No more free serial devices\n"); | ||
776 | kfree (serial); | ||
777 | return -ENOMEM; | ||
778 | } | ||
779 | |||
780 | serial->minor = minor; | 829 | serial->minor = minor; |
781 | serial->num_ports = num_ports; | 830 | serial->num_ports = num_ports; |
782 | serial->num_bulk_in = num_bulk_in; | 831 | serial->num_bulk_in = num_bulk_in; |
@@ -791,6 +840,8 @@ int usb_serial_probe(struct usb_interface *interface, | |||
791 | max_endpoints = max(max_endpoints, num_interrupt_out); | 840 | max_endpoints = max(max_endpoints, num_interrupt_out); |
792 | max_endpoints = max(max_endpoints, (int)serial->num_ports); | 841 | max_endpoints = max(max_endpoints, (int)serial->num_ports); |
793 | serial->num_port_pointers = max_endpoints; | 842 | serial->num_port_pointers = max_endpoints; |
843 | unlock_kernel(); | ||
844 | |||
794 | dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); | 845 | dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); |
795 | for (i = 0; i < max_endpoints; ++i) { | 846 | for (i = 0; i < max_endpoints; ++i) { |
796 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); | 847 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
@@ -925,6 +976,11 @@ int usb_serial_probe(struct usb_interface *interface, | |||
925 | } | 976 | } |
926 | } | 977 | } |
927 | 978 | ||
979 | if (get_free_serial (serial, num_ports, &minor) == NULL) { | ||
980 | dev_err(&interface->dev, "No more free serial devices\n"); | ||
981 | goto probe_error; | ||
982 | } | ||
983 | |||
928 | /* register all of the individual ports with the driver core */ | 984 | /* register all of the individual ports with the driver core */ |
929 | for (i = 0; i < num_ports; ++i) { | 985 | for (i = 0; i < num_ports; ++i) { |
930 | port = serial->port[i]; | 986 | port = serial->port[i]; |
@@ -1002,8 +1058,11 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1002 | if (serial) { | 1058 | if (serial) { |
1003 | for (i = 0; i < serial->num_ports; ++i) { | 1059 | for (i = 0; i < serial->num_ports; ++i) { |
1004 | port = serial->port[i]; | 1060 | port = serial->port[i]; |
1005 | if (port && port->tty) | 1061 | if (port) { |
1006 | tty_hangup(port->tty); | 1062 | if (port->tty) |
1063 | tty_hangup(port->tty); | ||
1064 | kill_traffic(port); | ||
1065 | } | ||
1007 | } | 1066 | } |
1008 | /* let the last holder of this object | 1067 | /* let the last holder of this object |
1009 | * cause it to be cleaned up */ | 1068 | * cause it to be cleaned up */ |
@@ -1040,6 +1099,7 @@ static int __init usb_serial_init(void) | |||
1040 | return -ENOMEM; | 1099 | return -ENOMEM; |
1041 | 1100 | ||
1042 | /* Initialize our global data */ | 1101 | /* Initialize our global data */ |
1102 | spin_lock_init(&table_lock); | ||
1043 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { | 1103 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
1044 | serial_table[i] = NULL; | 1104 | serial_table[i] = NULL; |
1045 | } | 1105 | } |
@@ -1138,7 +1198,7 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1138 | set_to_generic_if_null(device, shutdown); | 1198 | set_to_generic_if_null(device, shutdown); |
1139 | } | 1199 | } |
1140 | 1200 | ||
1141 | int usb_serial_register(struct usb_serial_driver *driver) | 1201 | int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */ |
1142 | { | 1202 | { |
1143 | int retval; | 1203 | int retval; |
1144 | 1204 | ||
@@ -1162,7 +1222,7 @@ int usb_serial_register(struct usb_serial_driver *driver) | |||
1162 | } | 1222 | } |
1163 | 1223 | ||
1164 | 1224 | ||
1165 | void usb_serial_deregister(struct usb_serial_driver *device) | 1225 | void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */ |
1166 | { | 1226 | { |
1167 | info("USB Serial deregistering driver %s", device->description); | 1227 | info("USB Serial deregistering driver %s", device->description); |
1168 | list_del(&device->driver_list); | 1228 | list_del(&device->driver_list); |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index b09f06096056..2f59ff226e2c 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -90,8 +90,6 @@ static struct usb_device_id id_table [] = { | |||
90 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 90 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
91 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), | 91 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), |
92 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 92 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
93 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID), | ||
94 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | ||
95 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), | 93 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), |
96 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 94 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
97 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), | 95 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), |
@@ -151,7 +149,6 @@ static struct usb_device_id id_table_combined [] = { | |||
151 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, | 149 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, |
152 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, | 150 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, |
153 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, | 151 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, |
154 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID) }, | ||
155 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, | 152 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, |
156 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, | 153 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, |
157 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, | 154 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, |
@@ -189,6 +186,7 @@ static struct usb_serial_driver handspring_device = { | |||
189 | .name = "visor", | 186 | .name = "visor", |
190 | }, | 187 | }, |
191 | .description = "Handspring Visor / Palm OS", | 188 | .description = "Handspring Visor / Palm OS", |
189 | .usb_driver = &visor_driver, | ||
192 | .id_table = id_table, | 190 | .id_table = id_table, |
193 | .num_interrupt_in = NUM_DONT_CARE, | 191 | .num_interrupt_in = NUM_DONT_CARE, |
194 | .num_bulk_in = 2, | 192 | .num_bulk_in = 2, |
@@ -219,6 +217,7 @@ static struct usb_serial_driver clie_5_device = { | |||
219 | .name = "clie_5", | 217 | .name = "clie_5", |
220 | }, | 218 | }, |
221 | .description = "Sony Clie 5.0", | 219 | .description = "Sony Clie 5.0", |
220 | .usb_driver = &visor_driver, | ||
222 | .id_table = clie_id_5_table, | 221 | .id_table = clie_id_5_table, |
223 | .num_interrupt_in = NUM_DONT_CARE, | 222 | .num_interrupt_in = NUM_DONT_CARE, |
224 | .num_bulk_in = 2, | 223 | .num_bulk_in = 2, |
@@ -249,6 +248,7 @@ static struct usb_serial_driver clie_3_5_device = { | |||
249 | .name = "clie_3.5", | 248 | .name = "clie_3.5", |
250 | }, | 249 | }, |
251 | .description = "Sony Clie 3.5", | 250 | .description = "Sony Clie 3.5", |
251 | .usb_driver = &visor_driver, | ||
252 | .id_table = clie_id_3_5_table, | 252 | .id_table = clie_id_3_5_table, |
253 | .num_interrupt_in = 0, | 253 | .num_interrupt_in = 0, |
254 | .num_bulk_in = 1, | 254 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 765118d83fb6..4ce6f62a6f39 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h | |||
@@ -32,7 +32,6 @@ | |||
32 | #define PALM_TUNGSTEN_T_ID 0x0060 | 32 | #define PALM_TUNGSTEN_T_ID 0x0060 |
33 | #define PALM_TREO_650 0x0061 | 33 | #define PALM_TREO_650 0x0061 |
34 | #define PALM_TUNGSTEN_Z_ID 0x0031 | 34 | #define PALM_TUNGSTEN_Z_ID 0x0031 |
35 | #define PALM_ZIRE31_ID 0x0061 | ||
36 | #define PALM_ZIRE_ID 0x0070 | 35 | #define PALM_ZIRE_ID 0x0070 |
37 | #define PALM_M100_ID 0x0080 | 36 | #define PALM_M100_ID 0x0080 |
38 | 37 | ||
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 5483d8564c1b..bf16e9e1d84e 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -161,6 +161,7 @@ static struct usb_serial_driver whiteheat_fake_device = { | |||
161 | .name = "whiteheatnofirm", | 161 | .name = "whiteheatnofirm", |
162 | }, | 162 | }, |
163 | .description = "Connect Tech - WhiteHEAT - (prerenumeration)", | 163 | .description = "Connect Tech - WhiteHEAT - (prerenumeration)", |
164 | .usb_driver = &whiteheat_driver, | ||
164 | .id_table = id_table_prerenumeration, | 165 | .id_table = id_table_prerenumeration, |
165 | .num_interrupt_in = NUM_DONT_CARE, | 166 | .num_interrupt_in = NUM_DONT_CARE, |
166 | .num_bulk_in = NUM_DONT_CARE, | 167 | .num_bulk_in = NUM_DONT_CARE, |
@@ -176,6 +177,7 @@ static struct usb_serial_driver whiteheat_device = { | |||
176 | .name = "whiteheat", | 177 | .name = "whiteheat", |
177 | }, | 178 | }, |
178 | .description = "Connect Tech - WhiteHEAT", | 179 | .description = "Connect Tech - WhiteHEAT", |
180 | .usb_driver = &whiteheat_driver, | ||
179 | .id_table = id_table_std, | 181 | .id_table = id_table_std, |
180 | .num_interrupt_in = NUM_DONT_CARE, | 182 | .num_interrupt_in = NUM_DONT_CARE, |
181 | .num_bulk_in = NUM_DONT_CARE, | 183 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index e565d3d2ab29..6d3dad3d1dae 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/usb_ch9.h> | ||
37 | #include <linux/usb/input.h> | 36 | #include <linux/usb/input.h> |
38 | #include "usb.h" | 37 | #include "usb.h" |
39 | #include "onetouch.h" | 38 | #include "onetouch.h" |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index e1072d52d641..70234f5dbeeb 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -110,23 +110,6 @@ static int slave_configure(struct scsi_device *sdev) | |||
110 | * the end, scatter-gather buffers follow page boundaries. */ | 110 | * the end, scatter-gather buffers follow page boundaries. */ |
111 | blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); | 111 | blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); |
112 | 112 | ||
113 | /* Set the SCSI level to at least 2. We'll leave it at 3 if that's | ||
114 | * what is originally reported. We need this to avoid confusing | ||
115 | * the SCSI layer with devices that report 0 or 1, but need 10-byte | ||
116 | * commands (ala ATAPI devices behind certain bridges, or devices | ||
117 | * which simply have broken INQUIRY data). | ||
118 | * | ||
119 | * NOTE: This means /dev/sg programs (ala cdrecord) will get the | ||
120 | * actual information. This seems to be the preference for | ||
121 | * programs like that. | ||
122 | * | ||
123 | * NOTE: This also means that /proc/scsi/scsi and sysfs may report | ||
124 | * the actual value or the modified one, depending on where the | ||
125 | * data comes from. | ||
126 | */ | ||
127 | if (sdev->scsi_level < SCSI_2) | ||
128 | sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; | ||
129 | |||
130 | /* Many devices have trouble transfering more than 32KB at a time, | 113 | /* Many devices have trouble transfering more than 32KB at a time, |
131 | * while others have trouble with more than 64K. At this time we | 114 | * while others have trouble with more than 64K. At this time we |
132 | * are limiting both to 32K (64 sectores). | 115 | * are limiting both to 32K (64 sectores). |
@@ -176,7 +159,9 @@ static int slave_configure(struct scsi_device *sdev) | |||
176 | * a Get-Max-LUN request, we won't lose much by setting the | 159 | * a Get-Max-LUN request, we won't lose much by setting the |
177 | * revision level down to 2. The only devices that would be | 160 | * revision level down to 2. The only devices that would be |
178 | * affected are those with sparse LUNs. */ | 161 | * affected are those with sparse LUNs. */ |
179 | sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; | 162 | if (sdev->scsi_level > SCSI_2) |
163 | sdev->sdev_target->scsi_level = | ||
164 | sdev->scsi_level = SCSI_2; | ||
180 | 165 | ||
181 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable | 166 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable |
182 | * Hardware Error) when any low-level error occurs, | 167 | * Hardware Error) when any low-level error occurs, |
@@ -194,6 +179,16 @@ static int slave_configure(struct scsi_device *sdev) | |||
194 | sdev->use_10_for_ms = 1; | 179 | sdev->use_10_for_ms = 1; |
195 | } | 180 | } |
196 | 181 | ||
182 | /* The CB and CBI transports have no way to pass LUN values | ||
183 | * other than the bits in the second byte of a CDB. But those | ||
184 | * bits don't get set to the LUN value if the device reports | ||
185 | * scsi_level == 0 (UNKNOWN). Hence such devices must necessarily | ||
186 | * be single-LUN. | ||
187 | */ | ||
188 | if ((us->protocol == US_PR_CB || us->protocol == US_PR_CBI) && | ||
189 | sdev->scsi_level == SCSI_UNKNOWN) | ||
190 | us->max_lun = 0; | ||
191 | |||
197 | /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM | 192 | /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM |
198 | * REMOVAL command, so suppress those commands. */ | 193 | * REMOVAL command, so suppress those commands. */ |
199 | if (us->flags & US_FL_NOT_LOCKABLE) | 194 | if (us->flags & US_FL_NOT_LOCKABLE) |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b49f2a78189e..f49a62fc32d2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -573,7 +573,7 @@ UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, | |||
573 | #endif | 573 | #endif |
574 | 574 | ||
575 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ | 575 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ |
576 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x0501, | 576 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, |
577 | "Sony", | 577 | "Sony", |
578 | "USB Floppy Drive", | 578 | "USB Floppy Drive", |
579 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 579 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -1325,13 +1325,6 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, | |||
1325 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1325 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1326 | US_FL_FIX_CAPACITY ), | 1326 | US_FL_FIX_CAPACITY ), |
1327 | 1327 | ||
1328 | /* Reported by Jan Mate <mate@fiit.stuba.sk> */ | ||
1329 | UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, | ||
1330 | "Sony Ericsson", | ||
1331 | "P990i", | ||
1332 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1333 | US_FL_FIX_CAPACITY ), | ||
1334 | |||
1335 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> | 1328 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> |
1336 | * Tested on hardware version 1.10. | 1329 | * Tested on hardware version 1.10. |
1337 | * Entry is needed only for the initializer function override. | 1330 | * Entry is needed only for the initializer function override. |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 70644506651f..7e7ec29782f1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -731,26 +731,27 @@ static int get_pipes(struct us_data *us) | |||
731 | struct usb_endpoint_descriptor *ep_int = NULL; | 731 | struct usb_endpoint_descriptor *ep_int = NULL; |
732 | 732 | ||
733 | /* | 733 | /* |
734 | * Find the endpoints we need. | 734 | * Find the first endpoint of each type we need. |
735 | * We are expecting a minimum of 2 endpoints - in and out (bulk). | 735 | * We are expecting a minimum of 2 endpoints - in and out (bulk). |
736 | * An optional interrupt is OK (necessary for CBI protocol). | 736 | * An optional interrupt-in is OK (necessary for CBI protocol). |
737 | * We will ignore any others. | 737 | * We will ignore any others. |
738 | */ | 738 | */ |
739 | for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { | 739 | for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { |
740 | ep = &altsetting->endpoint[i].desc; | 740 | ep = &altsetting->endpoint[i].desc; |
741 | 741 | ||
742 | /* Is it a BULK endpoint? */ | ||
743 | if (usb_endpoint_xfer_bulk(ep)) { | 742 | if (usb_endpoint_xfer_bulk(ep)) { |
744 | /* BULK in or out? */ | 743 | if (usb_endpoint_dir_in(ep)) { |
745 | if (usb_endpoint_dir_in(ep)) | 744 | if (!ep_in) |
746 | ep_in = ep; | 745 | ep_in = ep; |
747 | else | 746 | } else { |
748 | ep_out = ep; | 747 | if (!ep_out) |
748 | ep_out = ep; | ||
749 | } | ||
749 | } | 750 | } |
750 | 751 | ||
751 | /* Is it an interrupt endpoint? */ | 752 | else if (usb_endpoint_is_int_in(ep)) { |
752 | else if (usb_endpoint_xfer_int(ep)) { | 753 | if (!ep_int) |
753 | ep_int = ep; | 754 | ep_int = ep; |
754 | } | 755 | } |
755 | } | 756 | } |
756 | 757 | ||
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 157db77a7170..683513e310de 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -11,6 +11,7 @@ header-y += netfilter_arp/ | |||
11 | header-y += netfilter_bridge/ | 11 | header-y += netfilter_bridge/ |
12 | header-y += netfilter_ipv4/ | 12 | header-y += netfilter_ipv4/ |
13 | header-y += netfilter_ipv6/ | 13 | header-y += netfilter_ipv6/ |
14 | header-y += usb/ | ||
14 | 15 | ||
15 | header-y += affs_hardblocks.h | 16 | header-y += affs_hardblocks.h |
16 | header-y += aio_abi.h | 17 | header-y += aio_abi.h |
@@ -326,7 +327,6 @@ unifdef-y += udp.h | |||
326 | unifdef-y += uinput.h | 327 | unifdef-y += uinput.h |
327 | unifdef-y += uio.h | 328 | unifdef-y += uio.h |
328 | unifdef-y += unistd.h | 329 | unifdef-y += unistd.h |
329 | unifdef-y += usb_ch9.h | ||
330 | unifdef-y += usbdevice_fs.h | 330 | unifdef-y += usbdevice_fs.h |
331 | unifdef-y += user.h | 331 | unifdef-y += user.h |
332 | unifdef-y += utsname.h | 332 | unifdef-y += utsname.h |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 93173fe45634..d26b08f461f2 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -266,6 +266,7 @@ struct hid_item { | |||
266 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 | 266 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 |
267 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 | 267 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 |
268 | #define HID_QUIRK_IGNORE_MOUSE 0x00040000 | 268 | #define HID_QUIRK_IGNORE_MOUSE 0x00040000 |
269 | #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 | ||
269 | 270 | ||
270 | /* | 271 | /* |
271 | * This is the global environment of the parser. This information is | 272 | * This is the global environment of the parser. This information is |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 733f38de4978..b5c226a87ed8 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define __LINUX_USB_H | 2 | #define __LINUX_USB_H |
3 | 3 | ||
4 | #include <linux/mod_devicetable.h> | 4 | #include <linux/mod_devicetable.h> |
5 | #include <linux/usb_ch9.h> | 5 | #include <linux/usb/ch9.h> |
6 | 6 | ||
7 | #define USB_MAJOR 180 | 7 | #define USB_MAJOR 180 |
8 | #define USB_DEVICE_MAJOR 189 | 8 | #define USB_DEVICE_MAJOR 189 |
@@ -107,7 +107,8 @@ enum usb_interface_condition { | |||
107 | * @needs_remote_wakeup: flag set when the driver requires remote-wakeup | 107 | * @needs_remote_wakeup: flag set when the driver requires remote-wakeup |
108 | * capability during autosuspend. | 108 | * capability during autosuspend. |
109 | * @dev: driver model's view of this device | 109 | * @dev: driver model's view of this device |
110 | * @class_dev: driver model's class view of this device. | 110 | * @usb_dev: if an interface is bound to the USB major, this will point |
111 | * to the sysfs representation for that device. | ||
111 | * @pm_usage_cnt: PM usage counter for this interface; autosuspend is not | 112 | * @pm_usage_cnt: PM usage counter for this interface; autosuspend is not |
112 | * allowed unless the counter is 0. | 113 | * allowed unless the counter is 0. |
113 | * | 114 | * |
@@ -152,7 +153,7 @@ struct usb_interface { | |||
152 | unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ | 153 | unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ |
153 | 154 | ||
154 | struct device dev; /* interface specific device info */ | 155 | struct device dev; /* interface specific device info */ |
155 | struct class_device *class_dev; | 156 | struct device *usb_dev; /* pointer to the usb class's device, if any */ |
156 | int pm_usage_cnt; /* usage counter for autosuspend */ | 157 | int pm_usage_cnt; /* usage counter for autosuspend */ |
157 | }; | 158 | }; |
158 | #define to_usb_interface(d) container_of(d, struct usb_interface, dev) | 159 | #define to_usb_interface(d) container_of(d, struct usb_interface, dev) |
@@ -372,7 +373,7 @@ struct usb_device { | |||
372 | char *serial; /* iSerialNumber string, if present */ | 373 | char *serial; /* iSerialNumber string, if present */ |
373 | 374 | ||
374 | struct list_head filelist; | 375 | struct list_head filelist; |
375 | struct class_device *class_dev; | 376 | struct device *usbfs_dev; |
376 | struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ | 377 | struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ |
377 | 378 | ||
378 | /* | 379 | /* |
@@ -475,6 +476,8 @@ extern void usb_driver_release_interface(struct usb_driver *driver, | |||
475 | struct usb_interface *iface); | 476 | struct usb_interface *iface); |
476 | const struct usb_device_id *usb_match_id(struct usb_interface *interface, | 477 | const struct usb_device_id *usb_match_id(struct usb_interface *interface, |
477 | const struct usb_device_id *id); | 478 | const struct usb_device_id *id); |
479 | extern int usb_match_one_id(struct usb_interface *interface, | ||
480 | const struct usb_device_id *id); | ||
478 | 481 | ||
479 | extern struct usb_interface *usb_find_interface(struct usb_driver *drv, | 482 | extern struct usb_interface *usb_find_interface(struct usb_driver *drv, |
480 | int minor); | 483 | int minor); |
@@ -554,6 +557,18 @@ static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *e | |||
554 | } | 557 | } |
555 | 558 | ||
556 | /** | 559 | /** |
560 | * usb_endpoint_xfer_control - check if the endpoint has control transfer type | ||
561 | * @epd: endpoint to be checked | ||
562 | * | ||
563 | * Returns true if the endpoint is of type control, otherwise it returns false. | ||
564 | */ | ||
565 | static inline int usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd) | ||
566 | { | ||
567 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
568 | USB_ENDPOINT_XFER_CONTROL); | ||
569 | } | ||
570 | |||
571 | /** | ||
557 | * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type | 572 | * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type |
558 | * @epd: endpoint to be checked | 573 | * @epd: endpoint to be checked |
559 | * | 574 | * |
@@ -723,11 +738,21 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
723 | 738 | ||
724 | /* ----------------------------------------------------------------------- */ | 739 | /* ----------------------------------------------------------------------- */ |
725 | 740 | ||
741 | /* Stuff for dynamic usb ids */ | ||
726 | struct usb_dynids { | 742 | struct usb_dynids { |
727 | spinlock_t lock; | 743 | spinlock_t lock; |
728 | struct list_head list; | 744 | struct list_head list; |
729 | }; | 745 | }; |
730 | 746 | ||
747 | struct usb_dynid { | ||
748 | struct list_head node; | ||
749 | struct usb_device_id id; | ||
750 | }; | ||
751 | |||
752 | extern ssize_t usb_store_new_id(struct usb_dynids *dynids, | ||
753 | struct device_driver *driver, | ||
754 | const char *buf, size_t count); | ||
755 | |||
731 | /** | 756 | /** |
732 | * struct usbdrv_wrap - wrapper for driver-model structure | 757 | * struct usbdrv_wrap - wrapper for driver-model structure |
733 | * @driver: The driver-model core driver structure. | 758 | * @driver: The driver-model core driver structure. |
@@ -1086,7 +1111,6 @@ struct urb | |||
1086 | struct kref kref; /* reference count of the URB */ | 1111 | struct kref kref; /* reference count of the URB */ |
1087 | spinlock_t lock; /* lock for the URB */ | 1112 | spinlock_t lock; /* lock for the URB */ |
1088 | void *hcpriv; /* private data for host controller */ | 1113 | void *hcpriv; /* private data for host controller */ |
1089 | int bandwidth; /* bandwidth for INT/ISO request */ | ||
1090 | atomic_t use_count; /* concurrent submissions counter */ | 1114 | atomic_t use_count; /* concurrent submissions counter */ |
1091 | u8 reject; /* submissions will fail */ | 1115 | u8 reject; /* submissions will fail */ |
1092 | 1116 | ||
diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild new file mode 100644 index 000000000000..43f160cfe003 --- /dev/null +++ b/include/linux/usb/Kbuild | |||
@@ -0,0 +1,5 @@ | |||
1 | unifdef-y += audio.h | ||
2 | unifdef-y += cdc.h | ||
3 | unifdef-y += ch9.h | ||
4 | unifdef-y += midi.h | ||
5 | |||
diff --git a/include/linux/usb_ch9.h b/include/linux/usb/ch9.h index c720d107ff29..ae7833749fa2 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb/ch9.h | |||
@@ -224,6 +224,7 @@ struct usb_device_descriptor { | |||
224 | #define USB_CLASS_CONTENT_SEC 0x0d /* content security */ | 224 | #define USB_CLASS_CONTENT_SEC 0x0d /* content security */ |
225 | #define USB_CLASS_VIDEO 0x0e | 225 | #define USB_CLASS_VIDEO 0x0e |
226 | #define USB_CLASS_WIRELESS_CONTROLLER 0xe0 | 226 | #define USB_CLASS_WIRELESS_CONTROLLER 0xe0 |
227 | #define USB_CLASS_MISC 0xef | ||
227 | #define USB_CLASS_APP_SPEC 0xfe | 228 | #define USB_CLASS_APP_SPEC 0xfe |
228 | #define USB_CLASS_VENDOR_SPEC 0xff | 229 | #define USB_CLASS_VENDOR_SPEC 0xff |
229 | 230 | ||
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 10f99e5f1a97..33dcd8576696 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -179,6 +179,9 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) | |||
179 | * memory structure allocation at this point in time. | 179 | * memory structure allocation at this point in time. |
180 | * @shutdown: pointer to the driver's shutdown function. This will be | 180 | * @shutdown: pointer to the driver's shutdown function. This will be |
181 | * called when the device is removed from the system. | 181 | * called when the device is removed from the system. |
182 | * @usb_driver: pointer to the struct usb_driver that controls this | ||
183 | * device. This is necessary to allow dynamic ids to be added to | ||
184 | * the driver from sysfs. | ||
182 | * | 185 | * |
183 | * This structure is defines a USB Serial driver. It provides all of | 186 | * This structure is defines a USB Serial driver. It provides all of |
184 | * the information that the USB serial core code needs. If the function | 187 | * the information that the USB serial core code needs. If the function |
@@ -202,6 +205,8 @@ struct usb_serial_driver { | |||
202 | 205 | ||
203 | struct list_head driver_list; | 206 | struct list_head driver_list; |
204 | struct device_driver driver; | 207 | struct device_driver driver; |
208 | struct usb_driver *usb_driver; | ||
209 | struct usb_dynids dynids; | ||
205 | 210 | ||
206 | int (*probe) (struct usb_serial *serial, const struct usb_device_id *id); | 211 | int (*probe) (struct usb_serial *serial, const struct usb_device_id *id); |
207 | int (*attach) (struct usb_serial *serial); | 212 | int (*attach) (struct usb_serial *serial); |
diff --git a/include/linux/usb_gadgetfs.h b/include/linux/usb_gadgetfs.h index b53d6ae8e55e..8086d5a9b94e 100644 --- a/include/linux/usb_gadgetfs.h +++ b/include/linux/usb_gadgetfs.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #include <asm/types.h> | 2 | #include <asm/types.h> |
3 | #include <asm/ioctl.h> | 3 | #include <asm/ioctl.h> |
4 | 4 | ||
5 | #include <linux/usb_ch9.h> | 5 | #include <linux/usb/ch9.h> |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Filesystem based user-mode API to USB Gadget controller hardware | 8 | * Filesystem based user-mode API to USB Gadget controller hardware |