diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-07 05:15:40 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-07 05:15:40 -0400 |
commit | 5e34437840d33554f69380584311743b39e8fbeb (patch) | |
tree | e081135619ee146af5efb9ee883afca950df5757 /drivers/usb/core | |
parent | 77d05632baee21b1cef8730d7c06aa69601e4dca (diff) | |
parent | d508afb437daee7cf07da085b635c44a4ebf9b38 (diff) |
Merge branch 'linus' into core/softlockup
Conflicts:
kernel/sysctl.c
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/devices.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 33 | ||||
-rw-r--r-- | drivers/usb/core/endpoint.c | 9 | ||||
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 15 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 33 | ||||
-rw-r--r-- | drivers/usb/core/hcd.h | 1 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 34 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 22 | ||||
-rw-r--r-- | drivers/usb/core/quirks.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/sysfs.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 4 |
11 files changed, 82 insertions, 79 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 6ec38175a817..73c108d117b4 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -187,7 +187,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, | |||
187 | } | 187 | } |
188 | 188 | ||
189 | /* this isn't checking for illegal values */ | 189 | /* this isn't checking for illegal values */ |
190 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 190 | switch (usb_endpoint_type(desc)) { |
191 | case USB_ENDPOINT_XFER_CONTROL: | 191 | case USB_ENDPOINT_XFER_CONTROL: |
192 | type = "Ctrl"; | 192 | type = "Ctrl"; |
193 | if (speed == USB_SPEED_HIGH) /* uframes per NAK */ | 193 | if (speed == USB_SPEED_HIGH) /* uframes per NAK */ |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 7513bb083c15..df3c539f652a 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); | |||
104 | 104 | ||
105 | #define MAX_USBFS_BUFFER_SIZE 16384 | 105 | #define MAX_USBFS_BUFFER_SIZE 16384 |
106 | 106 | ||
107 | static inline int connected(struct dev_state *ps) | 107 | static int connected(struct dev_state *ps) |
108 | { | 108 | { |
109 | return (!list_empty(&ps->list) && | 109 | return (!list_empty(&ps->list) && |
110 | ps->dev->state != USB_STATE_NOTATTACHED); | 110 | ps->dev->state != USB_STATE_NOTATTACHED); |
@@ -248,7 +248,7 @@ static void free_async(struct async *as) | |||
248 | kfree(as); | 248 | kfree(as); |
249 | } | 249 | } |
250 | 250 | ||
251 | static inline void async_newpending(struct async *as) | 251 | static void async_newpending(struct async *as) |
252 | { | 252 | { |
253 | struct dev_state *ps = as->ps; | 253 | struct dev_state *ps = as->ps; |
254 | unsigned long flags; | 254 | unsigned long flags; |
@@ -258,7 +258,7 @@ static inline void async_newpending(struct async *as) | |||
258 | spin_unlock_irqrestore(&ps->lock, flags); | 258 | spin_unlock_irqrestore(&ps->lock, flags); |
259 | } | 259 | } |
260 | 260 | ||
261 | static inline void async_removepending(struct async *as) | 261 | static void async_removepending(struct async *as) |
262 | { | 262 | { |
263 | struct dev_state *ps = as->ps; | 263 | struct dev_state *ps = as->ps; |
264 | unsigned long flags; | 264 | unsigned long flags; |
@@ -268,7 +268,7 @@ static inline void async_removepending(struct async *as) | |||
268 | spin_unlock_irqrestore(&ps->lock, flags); | 268 | spin_unlock_irqrestore(&ps->lock, flags); |
269 | } | 269 | } |
270 | 270 | ||
271 | static inline struct async *async_getcompleted(struct dev_state *ps) | 271 | static struct async *async_getcompleted(struct dev_state *ps) |
272 | { | 272 | { |
273 | unsigned long flags; | 273 | unsigned long flags; |
274 | struct async *as = NULL; | 274 | struct async *as = NULL; |
@@ -283,7 +283,7 @@ static inline struct async *async_getcompleted(struct dev_state *ps) | |||
283 | return as; | 283 | return as; |
284 | } | 284 | } |
285 | 285 | ||
286 | static inline struct async *async_getpending(struct dev_state *ps, | 286 | static struct async *async_getpending(struct dev_state *ps, |
287 | void __user *userurb) | 287 | void __user *userurb) |
288 | { | 288 | { |
289 | unsigned long flags; | 289 | unsigned long flags; |
@@ -302,7 +302,7 @@ static inline struct async *async_getpending(struct dev_state *ps, | |||
302 | 302 | ||
303 | static void snoop_urb(struct urb *urb, void __user *userurb) | 303 | static void snoop_urb(struct urb *urb, void __user *userurb) |
304 | { | 304 | { |
305 | int j; | 305 | unsigned j; |
306 | unsigned char *data = urb->transfer_buffer; | 306 | unsigned char *data = urb->transfer_buffer; |
307 | 307 | ||
308 | if (!usbfs_snoop) | 308 | if (!usbfs_snoop) |
@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
311 | dev_info(&urb->dev->dev, "direction=%s\n", | 311 | dev_info(&urb->dev->dev, "direction=%s\n", |
312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); | 312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); |
313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | 313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); |
314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", | 314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n", |
315 | urb->transfer_buffer_length); | 315 | urb->transfer_buffer_length); |
316 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); | 316 | dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length); |
317 | dev_info(&urb->dev->dev, "data: "); | 317 | dev_info(&urb->dev->dev, "data: "); |
318 | for (j = 0; j < urb->transfer_buffer_length; ++j) | 318 | for (j = 0; j < urb->transfer_buffer_length; ++j) |
319 | printk("%02x ", data[j]); | 319 | printk("%02x ", data[j]); |
@@ -359,11 +359,6 @@ static void destroy_async(struct dev_state *ps, struct list_head *list) | |||
359 | spin_lock_irqsave(&ps->lock, flags); | 359 | spin_lock_irqsave(&ps->lock, flags); |
360 | } | 360 | } |
361 | spin_unlock_irqrestore(&ps->lock, flags); | 361 | spin_unlock_irqrestore(&ps->lock, flags); |
362 | as = async_getcompleted(ps); | ||
363 | while (as) { | ||
364 | free_async(as); | ||
365 | as = async_getcompleted(ps); | ||
366 | } | ||
367 | } | 362 | } |
368 | 363 | ||
369 | static void destroy_async_on_interface(struct dev_state *ps, | 364 | static void destroy_async_on_interface(struct dev_state *ps, |
@@ -381,7 +376,7 @@ static void destroy_async_on_interface(struct dev_state *ps, | |||
381 | destroy_async(ps, &hitlist); | 376 | destroy_async(ps, &hitlist); |
382 | } | 377 | } |
383 | 378 | ||
384 | static inline void destroy_all_async(struct dev_state *ps) | 379 | static void destroy_all_async(struct dev_state *ps) |
385 | { | 380 | { |
386 | destroy_async(ps, &ps->async_pending); | 381 | destroy_async(ps, &ps->async_pending); |
387 | } | 382 | } |
@@ -530,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | |||
530 | { | 525 | { |
531 | int ret = 0; | 526 | int ret = 0; |
532 | 527 | ||
533 | if (ps->dev->state != USB_STATE_ADDRESS | 528 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED |
529 | && ps->dev->state != USB_STATE_ADDRESS | ||
534 | && ps->dev->state != USB_STATE_CONFIGURED) | 530 | && ps->dev->state != USB_STATE_CONFIGURED) |
535 | return -EHOSTUNREACH; | 531 | return -EHOSTUNREACH; |
536 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) | 532 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) |
@@ -643,6 +639,7 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
643 | struct dev_state *ps = file->private_data; | 639 | struct dev_state *ps = file->private_data; |
644 | struct usb_device *dev = ps->dev; | 640 | struct usb_device *dev = ps->dev; |
645 | unsigned int ifnum; | 641 | unsigned int ifnum; |
642 | struct async *as; | ||
646 | 643 | ||
647 | usb_lock_device(dev); | 644 | usb_lock_device(dev); |
648 | 645 | ||
@@ -661,6 +658,12 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
661 | usb_unlock_device(dev); | 658 | usb_unlock_device(dev); |
662 | usb_put_dev(dev); | 659 | usb_put_dev(dev); |
663 | put_pid(ps->disc_pid); | 660 | put_pid(ps->disc_pid); |
661 | |||
662 | as = async_getcompleted(ps); | ||
663 | while (as) { | ||
664 | free_async(as); | ||
665 | as = async_getcompleted(ps); | ||
666 | } | ||
664 | kfree(ps); | 667 | kfree(ps); |
665 | return 0; | 668 | return 0; |
666 | } | 669 | } |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index e1710f260b4f..40dee2ac0133 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -66,7 +66,7 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, | |||
66 | struct ep_device *ep = to_ep_device(dev); | 66 | struct ep_device *ep = to_ep_device(dev); |
67 | char *type = "unknown"; | 67 | char *type = "unknown"; |
68 | 68 | ||
69 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 69 | switch (usb_endpoint_type(ep->desc)) { |
70 | case USB_ENDPOINT_XFER_CONTROL: | 70 | case USB_ENDPOINT_XFER_CONTROL: |
71 | type = "Control"; | 71 | type = "Control"; |
72 | break; | 72 | break; |
@@ -94,7 +94,7 @@ static ssize_t show_ep_interval(struct device *dev, | |||
94 | 94 | ||
95 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); | 95 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); |
96 | 96 | ||
97 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 97 | switch (usb_endpoint_type(ep->desc)) { |
98 | case USB_ENDPOINT_XFER_CONTROL: | 98 | case USB_ENDPOINT_XFER_CONTROL: |
99 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ | 99 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ |
100 | interval = ep->desc->bInterval; | 100 | interval = ep->desc->bInterval; |
@@ -131,10 +131,9 @@ static ssize_t show_ep_direction(struct device *dev, | |||
131 | struct ep_device *ep = to_ep_device(dev); | 131 | struct ep_device *ep = to_ep_device(dev); |
132 | char *direction; | 132 | char *direction; |
133 | 133 | ||
134 | if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 134 | if (usb_endpoint_xfer_control(ep->desc)) |
135 | USB_ENDPOINT_XFER_CONTROL) | ||
136 | direction = "both"; | 135 | direction = "both"; |
137 | else if (ep->desc->bEndpointAddress & USB_DIR_IN) | 136 | else if (usb_endpoint_dir_in(ep->desc)) |
138 | direction = "in"; | 137 | direction = "in"; |
139 | else | 138 | else |
140 | direction = "out"; | 139 | direction = "out"; |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index c54fc40458b1..a4301dc02d27 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -298,19 +298,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) | |||
298 | EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); | 298 | EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); |
299 | 299 | ||
300 | /** | 300 | /** |
301 | * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled | ||
302 | * @dev: USB Host Controller being resumed | ||
303 | * | ||
304 | * Store this function in the HCD's struct pci_driver as .resume_early. | ||
305 | */ | ||
306 | int usb_hcd_pci_resume_early(struct pci_dev *dev) | ||
307 | { | ||
308 | pci_restore_state(dev); | ||
309 | return 0; | ||
310 | } | ||
311 | EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early); | ||
312 | |||
313 | /** | ||
314 | * usb_hcd_pci_resume - power management resume of a PCI-based HCD | 301 | * usb_hcd_pci_resume - power management resume of a PCI-based HCD |
315 | * @dev: USB Host Controller being resumed | 302 | * @dev: USB Host Controller being resumed |
316 | * | 303 | * |
@@ -333,6 +320,8 @@ int usb_hcd_pci_resume(struct pci_dev *dev) | |||
333 | } | 320 | } |
334 | #endif | 321 | #endif |
335 | 322 | ||
323 | pci_restore_state(dev); | ||
324 | |||
336 | hcd = pci_get_drvdata(dev); | 325 | hcd = pci_get_drvdata(dev); |
337 | if (hcd->state != HC_STATE_SUSPENDED) { | 326 | if (hcd->state != HC_STATE_SUSPENDED) { |
338 | dev_dbg(hcd->self.controller, | 327 | dev_dbg(hcd->self.controller, |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 3c711db55d86..81fa8506825d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = { | |||
279 | * helper routine for returning string descriptors in UTF-16LE | 279 | * helper routine for returning string descriptors in UTF-16LE |
280 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset | 280 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset |
281 | */ | 281 | */ |
282 | static int ascii2utf (char *s, u8 *utf, int utfmax) | 282 | static unsigned ascii2utf(char *s, u8 *utf, int utfmax) |
283 | { | 283 | { |
284 | int retval; | 284 | unsigned retval; |
285 | 285 | ||
286 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { | 286 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { |
287 | *utf++ = *s++; | 287 | *utf++ = *s++; |
@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax) | |||
304 | * Produces either a manufacturer, product or serial number string for the | 304 | * Produces either a manufacturer, product or serial number string for the |
305 | * virtual root hub device. | 305 | * virtual root hub device. |
306 | */ | 306 | */ |
307 | static int rh_string ( | 307 | static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len) |
308 | int id, | 308 | { |
309 | struct usb_hcd *hcd, | ||
310 | u8 *data, | ||
311 | int len | ||
312 | ) { | ||
313 | char buf [100]; | 309 | char buf [100]; |
314 | 310 | ||
315 | // language ids | 311 | // language ids |
316 | if (id == 0) { | 312 | if (id == 0) { |
317 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ | 313 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ |
318 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ | 314 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ |
319 | len = min (len, 4); | 315 | len = min_t(unsigned, len, 4); |
320 | memcpy (data, buf, len); | 316 | memcpy (data, buf, len); |
321 | return len; | 317 | return len; |
322 | 318 | ||
@@ -332,10 +328,7 @@ static int rh_string ( | |||
332 | } else if (id == 3) { | 328 | } else if (id == 3) { |
333 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, | 329 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, |
334 | init_utsname()->release, hcd->driver->description); | 330 | init_utsname()->release, hcd->driver->description); |
335 | 331 | } | |
336 | // unsupported IDs --> "protocol stall" | ||
337 | } else | ||
338 | return -EPIPE; | ||
339 | 332 | ||
340 | switch (len) { /* All cases fall through */ | 333 | switch (len) { /* All cases fall through */ |
341 | default: | 334 | default: |
@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
360 | u8 tbuf [sizeof (struct usb_hub_descriptor)] | 353 | u8 tbuf [sizeof (struct usb_hub_descriptor)] |
361 | __attribute__((aligned(4))); | 354 | __attribute__((aligned(4))); |
362 | const u8 *bufp = tbuf; | 355 | const u8 *bufp = tbuf; |
363 | int len = 0; | 356 | unsigned len = 0; |
364 | int status; | 357 | int status; |
365 | int n; | ||
366 | u8 patch_wakeup = 0; | 358 | u8 patch_wakeup = 0; |
367 | u8 patch_protocol = 0; | 359 | u8 patch_protocol = 0; |
368 | 360 | ||
@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
456 | patch_wakeup = 1; | 448 | patch_wakeup = 1; |
457 | break; | 449 | break; |
458 | case USB_DT_STRING << 8: | 450 | case USB_DT_STRING << 8: |
459 | n = rh_string (wValue & 0xff, hcd, ubuf, wLength); | 451 | if ((wValue & 0xff) < 4) |
460 | if (n < 0) | 452 | urb->actual_length = rh_string(wValue & 0xff, |
453 | hcd, ubuf, wLength); | ||
454 | else /* unsupported IDs --> "protocol stall" */ | ||
461 | goto error; | 455 | goto error; |
462 | urb->actual_length = n; | ||
463 | break; | 456 | break; |
464 | default: | 457 | default: |
465 | goto error; | 458 | goto error; |
@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) | |||
629 | { | 622 | { |
630 | int retval; | 623 | int retval; |
631 | unsigned long flags; | 624 | unsigned long flags; |
632 | int len = 1 + (urb->dev->maxchild / 8); | 625 | unsigned len = 1 + (urb->dev->maxchild / 8); |
633 | 626 | ||
634 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 627 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
635 | if (hcd->status_urb || urb->transfer_buffer_length < len) { | 628 | if (hcd->status_urb || urb->transfer_buffer_length < len) { |
@@ -901,7 +894,7 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
901 | 894 | ||
902 | mutex_lock(&usb_bus_list_lock); | 895 | mutex_lock(&usb_bus_list_lock); |
903 | 896 | ||
904 | usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 897 | usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
905 | retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); | 898 | retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); |
906 | if (retval != sizeof usb_dev->descriptor) { | 899 | if (retval != sizeof usb_dev->descriptor) { |
907 | mutex_unlock(&usb_bus_list_lock); | 900 | mutex_unlock(&usb_bus_list_lock); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 5b94a56bec23..f750eb1ab595 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -257,7 +257,6 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev); | |||
257 | 257 | ||
258 | #ifdef CONFIG_PM | 258 | #ifdef CONFIG_PM |
259 | extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); | 259 | extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); |
260 | extern int usb_hcd_pci_resume_early(struct pci_dev *dev); | ||
261 | extern int usb_hcd_pci_resume(struct pci_dev *dev); | 260 | extern int usb_hcd_pci_resume(struct pci_dev *dev); |
262 | #endif /* CONFIG_PM */ | 261 | #endif /* CONFIG_PM */ |
263 | 262 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index cd50d86029e7..be86ae3f4088 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb) | |||
392 | { | 392 | { |
393 | struct usb_hub *hub = urb->context; | 393 | struct usb_hub *hub = urb->context; |
394 | int status = urb->status; | 394 | int status = urb->status; |
395 | int i; | 395 | unsigned i; |
396 | unsigned long bits; | 396 | unsigned long bits; |
397 | 397 | ||
398 | switch (status) { | 398 | switch (status) { |
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev, | |||
1305 | recursively_mark_NOTATTACHED(udev); | 1305 | recursively_mark_NOTATTACHED(udev); |
1306 | spin_unlock_irqrestore(&device_state_lock, flags); | 1306 | spin_unlock_irqrestore(&device_state_lock, flags); |
1307 | } | 1307 | } |
1308 | EXPORT_SYMBOL_GPL(usb_set_device_state); | ||
1308 | 1309 | ||
1309 | /* | 1310 | /* |
1310 | * WUSB devices are simple: they have no hubs behind, so the mapping | 1311 | * WUSB devices are simple: they have no hubs behind, so the mapping |
@@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2471 | */ | 2472 | */ |
2472 | switch (udev->speed) { | 2473 | switch (udev->speed) { |
2473 | case USB_SPEED_VARIABLE: /* fixed at 512 */ | 2474 | case USB_SPEED_VARIABLE: /* fixed at 512 */ |
2474 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512); | 2475 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); |
2475 | break; | 2476 | break; |
2476 | case USB_SPEED_HIGH: /* fixed at 64 */ | 2477 | case USB_SPEED_HIGH: /* fixed at 64 */ |
2477 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2478 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
2478 | break; | 2479 | break; |
2479 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ | 2480 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ |
2480 | /* to determine the ep0 maxpacket size, try to read | 2481 | /* to determine the ep0 maxpacket size, try to read |
2481 | * the device descriptor to get bMaxPacketSize0 and | 2482 | * the device descriptor to get bMaxPacketSize0 and |
2482 | * then correct our initial guess. | 2483 | * then correct our initial guess. |
2483 | */ | 2484 | */ |
2484 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2485 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
2485 | break; | 2486 | break; |
2486 | case USB_SPEED_LOW: /* fixed at 8 */ | 2487 | case USB_SPEED_LOW: /* fixed at 8 */ |
2487 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8); | 2488 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); |
2488 | break; | 2489 | break; |
2489 | default: | 2490 | default: |
2490 | goto fail; | 2491 | goto fail; |
@@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3392 | udev->descriptor = descriptor; /* for disconnect() calls */ | 3393 | udev->descriptor = descriptor; /* for disconnect() calls */ |
3393 | goto re_enumerate; | 3394 | goto re_enumerate; |
3394 | } | 3395 | } |
3395 | 3396 | ||
3397 | /* Restore the device's previous configuration */ | ||
3396 | if (!udev->actconfig) | 3398 | if (!udev->actconfig) |
3397 | goto done; | 3399 | goto done; |
3398 | |||
3399 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 3400 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
3400 | USB_REQ_SET_CONFIGURATION, 0, | 3401 | USB_REQ_SET_CONFIGURATION, 0, |
3401 | udev->actconfig->desc.bConfigurationValue, 0, | 3402 | udev->actconfig->desc.bConfigurationValue, 0, |
@@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3408 | } | 3409 | } |
3409 | usb_set_device_state(udev, USB_STATE_CONFIGURED); | 3410 | usb_set_device_state(udev, USB_STATE_CONFIGURED); |
3410 | 3411 | ||
3412 | /* Put interfaces back into the same altsettings as before. | ||
3413 | * Don't bother to send the Set-Interface request for interfaces | ||
3414 | * that were already in altsetting 0; besides being unnecessary, | ||
3415 | * many devices can't handle it. Instead just reset the host-side | ||
3416 | * endpoint state. | ||
3417 | */ | ||
3411 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 3418 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
3412 | struct usb_interface *intf = udev->actconfig->interface[i]; | 3419 | struct usb_interface *intf = udev->actconfig->interface[i]; |
3413 | struct usb_interface_descriptor *desc; | 3420 | struct usb_interface_descriptor *desc; |
3414 | 3421 | ||
3415 | /* set_interface resets host side toggle even | ||
3416 | * for altsetting zero. the interface may have no driver. | ||
3417 | */ | ||
3418 | desc = &intf->cur_altsetting->desc; | 3422 | desc = &intf->cur_altsetting->desc; |
3419 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | 3423 | if (desc->bAlternateSetting == 0) { |
3420 | desc->bAlternateSetting); | 3424 | usb_disable_interface(udev, intf, true); |
3425 | usb_enable_interface(udev, intf, true); | ||
3426 | ret = 0; | ||
3427 | } else { | ||
3428 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | ||
3429 | desc->bAlternateSetting); | ||
3430 | } | ||
3421 | if (ret < 0) { | 3431 | if (ret < 0) { |
3422 | dev_err(&udev->dev, "failed to restore interface %d " | 3432 | dev_err(&udev->dev, "failed to restore interface %d " |
3423 | "altsetting %d (error=%d)\n", | 3433 | "altsetting %d (error=%d)\n", |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 31fb204f44c6..30a0690f3683 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | |||
59 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); | 59 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); |
60 | 60 | ||
61 | dev_dbg(&urb->dev->dev, | 61 | dev_dbg(&urb->dev->dev, |
62 | "%s timed out on ep%d%s len=%d/%d\n", | 62 | "%s timed out on ep%d%s len=%u/%u\n", |
63 | current->comm, | 63 | current->comm, |
64 | usb_endpoint_num(&urb->ep->desc), | 64 | usb_endpoint_num(&urb->ep->desc), |
65 | usb_urb_dir_in(urb) ? "in" : "out", | 65 | usb_urb_dir_in(urb) ? "in" : "out", |
@@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, | |||
653 | if (result <= 0 && result != -ETIMEDOUT) | 653 | if (result <= 0 && result != -ETIMEDOUT) |
654 | continue; | 654 | continue; |
655 | if (result > 1 && ((u8 *)buf)[1] != type) { | 655 | if (result > 1 && ((u8 *)buf)[1] != type) { |
656 | result = -EPROTO; | 656 | result = -ENODATA; |
657 | continue; | 657 | continue; |
658 | } | 658 | } |
659 | break; | 659 | break; |
@@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid, | |||
696 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 696 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
697 | (USB_DT_STRING << 8) + index, langid, buf, size, | 697 | (USB_DT_STRING << 8) + index, langid, buf, size, |
698 | USB_CTRL_GET_TIMEOUT); | 698 | USB_CTRL_GET_TIMEOUT); |
699 | if (!(result == 0 || result == -EPIPE)) | 699 | if (result == 0 || result == -EPIPE) |
700 | break; | 700 | continue; |
701 | if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { | ||
702 | result = -ENODATA; | ||
703 | continue; | ||
704 | } | ||
705 | break; | ||
701 | } | 706 | } |
702 | return result; | 707 | return result; |
703 | } | 708 | } |
@@ -799,18 +804,16 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
799 | dev_err(&dev->dev, | 804 | dev_err(&dev->dev, |
800 | "string descriptor 0 read error: %d\n", | 805 | "string descriptor 0 read error: %d\n", |
801 | err); | 806 | err); |
802 | goto errout; | ||
803 | } else if (err < 4) { | 807 | } else if (err < 4) { |
804 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | 808 | dev_err(&dev->dev, "string descriptor 0 too short\n"); |
805 | err = -EINVAL; | ||
806 | goto errout; | ||
807 | } else { | 809 | } else { |
808 | dev->have_langid = 1; | ||
809 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | 810 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); |
810 | /* always use the first langid listed */ | 811 | /* always use the first langid listed */ |
811 | dev_dbg(&dev->dev, "default language 0x%04x\n", | 812 | dev_dbg(&dev->dev, "default language 0x%04x\n", |
812 | dev->string_langid); | 813 | dev->string_langid); |
813 | } | 814 | } |
815 | |||
816 | dev->have_langid = 1; | ||
814 | } | 817 | } |
815 | 818 | ||
816 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 819 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
@@ -1714,7 +1717,8 @@ free_interfaces: | |||
1714 | } | 1717 | } |
1715 | kfree(new_interfaces); | 1718 | kfree(new_interfaces); |
1716 | 1719 | ||
1717 | if (cp->string == NULL) | 1720 | if (cp->string == NULL && |
1721 | !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
1718 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); | 1722 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); |
1719 | 1723 | ||
1720 | /* Now that all the interfaces are set up, register them | 1724 | /* Now that all the interfaces are set up, register them |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c070b34b669d..ab93918d9207 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -54,6 +54,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = | 54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = |
55 | USB_QUIRK_STRING_FETCH_255 }, | 55 | USB_QUIRK_STRING_FETCH_255 }, |
56 | 56 | ||
57 | /* Saitek Cyborg Gold Joystick */ | ||
58 | { USB_DEVICE(0x06a3, 0x0006), .driver_info = | ||
59 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
60 | |||
57 | /* M-Systems Flash Disk Pioneers */ | 61 | /* M-Systems Flash Disk Pioneers */ |
58 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 62 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
59 | 63 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4cc2456ef3be..c66789197927 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/usb/quirks.h> | ||
16 | #include "usb.h" | 17 | #include "usb.h" |
17 | 18 | ||
18 | /* Active configuration fields */ | 19 | /* Active configuration fields */ |
@@ -813,7 +814,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) | |||
813 | if (intf->sysfs_files_created || intf->unregistering) | 814 | if (intf->sysfs_files_created || intf->unregistering) |
814 | return 0; | 815 | return 0; |
815 | 816 | ||
816 | if (alt->string == NULL) | 817 | if (alt->string == NULL && |
818 | !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
817 | alt->string = usb_cache_string(udev, alt->desc.iInterface); | 819 | alt->string = usb_cache_string(udev, alt->desc.iInterface); |
818 | if (alt->string) | 820 | if (alt->string) |
819 | retval = device_create_file(&intf->dev, &dev_attr_interface); | 821 | retval = device_create_file(&intf->dev, &dev_attr_interface); |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 58bc5e3c2560..3376055f36e7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
295 | if (!urb || urb->hcpriv || !urb->complete) | 295 | if (!urb || urb->hcpriv || !urb->complete) |
296 | return -EINVAL; | 296 | return -EINVAL; |
297 | dev = urb->dev; | 297 | dev = urb->dev; |
298 | if ((!dev) || (dev->state < USB_STATE_DEFAULT)) | 298 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) |
299 | return -ENODEV; | 299 | return -ENODEV; |
300 | 300 | ||
301 | /* For now, get the endpoint from the pipe. Eventually drivers | 301 | /* For now, get the endpoint from the pipe. Eventually drivers |
@@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
370 | } | 370 | } |
371 | 371 | ||
372 | /* the I/O buffer must be mapped/unmapped, except when length=0 */ | 372 | /* the I/O buffer must be mapped/unmapped, except when length=0 */ |
373 | if (urb->transfer_buffer_length < 0) | 373 | if (urb->transfer_buffer_length > INT_MAX) |
374 | return -EMSGSIZE; | 374 | return -EMSGSIZE; |
375 | 375 | ||
376 | #ifdef DEBUG | 376 | #ifdef DEBUG |