diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:25:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:25:16 -0400 |
commit | be90a49ca22a95f184d9f32d35b5247b44032849 (patch) | |
tree | d3c2edc18c003c384366f57901616ac29c80bc27 /drivers/usb/core | |
parent | 1f0918d03ff4b5c94540c71ce889672abdbc2f4a (diff) | |
parent | a87371b477774b290c27bc5cb7f4ccc5379574a9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (142 commits)
USB: Fix sysfs paths in documentation
USB: skeleton: fix coding style issues.
USB: O_NONBLOCK in read path of skeleton
USB: make usb-skeleton honor O_NONBLOCK in write path
USB: skel_read really sucks royally
USB: Add hub descriptor update hook for xHCI
USB: xhci: Support USB hubs.
USB: xhci: Set multi-TT field for LS/FS devices under hubs.
USB: xhci: Set route string for all devices.
USB: xhci: Fix command wait list handling.
USB: xhci: Change how xHCI commands are handled.
USB: xhci: Refactor input device context setup.
USB: xhci: Endpoint representation refactoring.
USB: gadget: ether needs to select CRC32
USB: fix USBTMC get_capabilities success handling
USB: fix missing error check in probing
USB: usbfs: add USBDEVFS_URB_BULK_CONTINUATION flag
USB: support for autosuspend in sierra while online
USB: ehci-dbgp,ehci: Allow dbpg to work with suspend/resume
USB: ehci-dbgp,documentation: Documentation updates for ehci-dbgp
...
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/config.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 247 | ||||
-rw-r--r-- | drivers/usb/core/driver.c | 75 | ||||
-rw-r--r-- | drivers/usb/core/generic.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 111 | ||||
-rw-r--r-- | drivers/usb/core/hcd.h | 5 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 126 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 32 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 13 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 7 |
10 files changed, 430 insertions, 192 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index a16c538d0132..0d3af6a6ee49 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -105,7 +105,7 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, | |||
105 | ep->ss_ep_comp->extralen = i; | 105 | ep->ss_ep_comp->extralen = i; |
106 | buffer += i; | 106 | buffer += i; |
107 | size -= i; | 107 | size -= i; |
108 | retval = buffer - buffer_start + i; | 108 | retval = buffer - buffer_start; |
109 | if (num_skipped > 0) | 109 | if (num_skipped > 0) |
110 | dev_dbg(ddev, "skipped %d descriptor%s after %s\n", | 110 | dev_dbg(ddev, "skipped %d descriptor%s after %s\n", |
111 | num_skipped, plural(num_skipped), | 111 | num_skipped, plural(num_skipped), |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4247eccf858c..181f78c84105 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -52,6 +52,7 @@ | |||
52 | 52 | ||
53 | #include "hcd.h" /* for usbcore internals */ | 53 | #include "hcd.h" /* for usbcore internals */ |
54 | #include "usb.h" | 54 | #include "usb.h" |
55 | #include "hub.h" | ||
55 | 56 | ||
56 | #define USB_MAXBUS 64 | 57 | #define USB_MAXBUS 64 |
57 | #define USB_DEVICE_MAX USB_MAXBUS * 128 | 58 | #define USB_DEVICE_MAX USB_MAXBUS * 128 |
@@ -73,6 +74,7 @@ struct dev_state { | |||
73 | void __user *disccontext; | 74 | void __user *disccontext; |
74 | unsigned long ifclaimed; | 75 | unsigned long ifclaimed; |
75 | u32 secid; | 76 | u32 secid; |
77 | u32 disabled_bulk_eps; | ||
76 | }; | 78 | }; |
77 | 79 | ||
78 | struct async { | 80 | struct async { |
@@ -87,6 +89,8 @@ struct async { | |||
87 | struct urb *urb; | 89 | struct urb *urb; |
88 | int status; | 90 | int status; |
89 | u32 secid; | 91 | u32 secid; |
92 | u8 bulk_addr; | ||
93 | u8 bulk_status; | ||
90 | }; | 94 | }; |
91 | 95 | ||
92 | static int usbfs_snoop; | 96 | static int usbfs_snoop; |
@@ -99,11 +103,15 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); | |||
99 | dev_info(dev , format , ## arg); \ | 103 | dev_info(dev , format , ## arg); \ |
100 | } while (0) | 104 | } while (0) |
101 | 105 | ||
102 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) | 106 | enum snoop_when { |
107 | SUBMIT, COMPLETE | ||
108 | }; | ||
103 | 109 | ||
110 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) | ||
104 | 111 | ||
105 | #define MAX_USBFS_BUFFER_SIZE 16384 | 112 | #define MAX_USBFS_BUFFER_SIZE 16384 |
106 | 113 | ||
114 | |||
107 | static int connected(struct dev_state *ps) | 115 | static int connected(struct dev_state *ps) |
108 | { | 116 | { |
109 | return (!list_empty(&ps->list) && | 117 | return (!list_empty(&ps->list) && |
@@ -300,24 +308,79 @@ static struct async *async_getpending(struct dev_state *ps, | |||
300 | return NULL; | 308 | return NULL; |
301 | } | 309 | } |
302 | 310 | ||
303 | static void snoop_urb(struct urb *urb, void __user *userurb) | 311 | static void snoop_urb(struct usb_device *udev, |
312 | void __user *userurb, int pipe, unsigned length, | ||
313 | int timeout_or_status, enum snoop_when when) | ||
304 | { | 314 | { |
305 | unsigned j; | 315 | static const char *types[] = {"isoc", "int", "ctrl", "bulk"}; |
306 | unsigned char *data = urb->transfer_buffer; | 316 | static const char *dirs[] = {"out", "in"}; |
317 | int ep; | ||
318 | const char *t, *d; | ||
307 | 319 | ||
308 | if (!usbfs_snoop) | 320 | if (!usbfs_snoop) |
309 | return; | 321 | return; |
310 | 322 | ||
311 | dev_info(&urb->dev->dev, "direction=%s\n", | 323 | ep = usb_pipeendpoint(pipe); |
312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); | 324 | t = types[usb_pipetype(pipe)]; |
313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | 325 | d = dirs[!!usb_pipein(pipe)]; |
314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n", | 326 | |
315 | urb->transfer_buffer_length); | 327 | if (userurb) { /* Async */ |
316 | dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length); | 328 | if (when == SUBMIT) |
317 | dev_info(&urb->dev->dev, "data: "); | 329 | dev_info(&udev->dev, "userurb %p, ep%d %s-%s, " |
318 | for (j = 0; j < urb->transfer_buffer_length; ++j) | 330 | "length %u\n", |
319 | printk("%02x ", data[j]); | 331 | userurb, ep, t, d, length); |
320 | printk("\n"); | 332 | else |
333 | dev_info(&udev->dev, "userurb %p, ep%d %s-%s, " | ||
334 | "actual_length %u status %d\n", | ||
335 | userurb, ep, t, d, length, | ||
336 | timeout_or_status); | ||
337 | } else { | ||
338 | if (when == SUBMIT) | ||
339 | dev_info(&udev->dev, "ep%d %s-%s, length %u, " | ||
340 | "timeout %d\n", | ||
341 | ep, t, d, length, timeout_or_status); | ||
342 | else | ||
343 | dev_info(&udev->dev, "ep%d %s-%s, actual_length %u, " | ||
344 | "status %d\n", | ||
345 | ep, t, d, length, timeout_or_status); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | #define AS_CONTINUATION 1 | ||
350 | #define AS_UNLINK 2 | ||
351 | |||
352 | static void cancel_bulk_urbs(struct dev_state *ps, unsigned bulk_addr) | ||
353 | __releases(ps->lock) | ||
354 | __acquires(ps->lock) | ||
355 | { | ||
356 | struct async *as; | ||
357 | |||
358 | /* Mark all the pending URBs that match bulk_addr, up to but not | ||
359 | * including the first one without AS_CONTINUATION. If such an | ||
360 | * URB is encountered then a new transfer has already started so | ||
361 | * the endpoint doesn't need to be disabled; otherwise it does. | ||
362 | */ | ||
363 | list_for_each_entry(as, &ps->async_pending, asynclist) { | ||
364 | if (as->bulk_addr == bulk_addr) { | ||
365 | if (as->bulk_status != AS_CONTINUATION) | ||
366 | goto rescan; | ||
367 | as->bulk_status = AS_UNLINK; | ||
368 | as->bulk_addr = 0; | ||
369 | } | ||
370 | } | ||
371 | ps->disabled_bulk_eps |= (1 << bulk_addr); | ||
372 | |||
373 | /* Now carefully unlink all the marked pending URBs */ | ||
374 | rescan: | ||
375 | list_for_each_entry(as, &ps->async_pending, asynclist) { | ||
376 | if (as->bulk_status == AS_UNLINK) { | ||
377 | as->bulk_status = 0; /* Only once */ | ||
378 | spin_unlock(&ps->lock); /* Allow completions */ | ||
379 | usb_unlink_urb(as->urb); | ||
380 | spin_lock(&ps->lock); | ||
381 | goto rescan; | ||
382 | } | ||
383 | } | ||
321 | } | 384 | } |
322 | 385 | ||
323 | static void async_completed(struct urb *urb) | 386 | static void async_completed(struct urb *urb) |
@@ -346,7 +409,11 @@ static void async_completed(struct urb *urb) | |||
346 | secid = as->secid; | 409 | secid = as->secid; |
347 | } | 410 | } |
348 | snoop(&urb->dev->dev, "urb complete\n"); | 411 | snoop(&urb->dev->dev, "urb complete\n"); |
349 | snoop_urb(urb, as->userurb); | 412 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, |
413 | as->status, COMPLETE); | ||
414 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && | ||
415 | as->status != -ENOENT) | ||
416 | cancel_bulk_urbs(ps, as->bulk_addr); | ||
350 | spin_unlock(&ps->lock); | 417 | spin_unlock(&ps->lock); |
351 | 418 | ||
352 | if (signr) | 419 | if (signr) |
@@ -655,6 +722,7 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
655 | struct async *as; | 722 | struct async *as; |
656 | 723 | ||
657 | usb_lock_device(dev); | 724 | usb_lock_device(dev); |
725 | usb_hub_release_all_ports(dev, ps); | ||
658 | 726 | ||
659 | /* Protect against simultaneous open */ | 727 | /* Protect against simultaneous open */ |
660 | mutex_lock(&usbfs_mutex); | 728 | mutex_lock(&usbfs_mutex); |
@@ -688,7 +756,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
688 | unsigned int tmo; | 756 | unsigned int tmo; |
689 | unsigned char *tbuf; | 757 | unsigned char *tbuf; |
690 | unsigned wLength; | 758 | unsigned wLength; |
691 | int i, j, ret; | 759 | int i, pipe, ret; |
692 | 760 | ||
693 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 761 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
694 | return -EFAULT; | 762 | return -EFAULT; |
@@ -708,24 +776,17 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
708 | free_page((unsigned long)tbuf); | 776 | free_page((unsigned long)tbuf); |
709 | return -EINVAL; | 777 | return -EINVAL; |
710 | } | 778 | } |
711 | snoop(&dev->dev, "control read: bRequest=%02x " | 779 | pipe = usb_rcvctrlpipe(dev, 0); |
712 | "bRrequestType=%02x wValue=%04x " | 780 | snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT); |
713 | "wIndex=%04x wLength=%04x\n", | ||
714 | ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, | ||
715 | ctrl.wIndex, ctrl.wLength); | ||
716 | 781 | ||
717 | usb_unlock_device(dev); | 782 | usb_unlock_device(dev); |
718 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, | 783 | i = usb_control_msg(dev, pipe, ctrl.bRequest, |
719 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, | 784 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
720 | tbuf, ctrl.wLength, tmo); | 785 | tbuf, ctrl.wLength, tmo); |
721 | usb_lock_device(dev); | 786 | usb_lock_device(dev); |
787 | snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE); | ||
788 | |||
722 | if ((i > 0) && ctrl.wLength) { | 789 | if ((i > 0) && ctrl.wLength) { |
723 | if (usbfs_snoop) { | ||
724 | dev_info(&dev->dev, "control read: data "); | ||
725 | for (j = 0; j < i; ++j) | ||
726 | printk("%02x ", (u8)(tbuf)[j]); | ||
727 | printk("\n"); | ||
728 | } | ||
729 | if (copy_to_user(ctrl.data, tbuf, i)) { | 790 | if (copy_to_user(ctrl.data, tbuf, i)) { |
730 | free_page((unsigned long)tbuf); | 791 | free_page((unsigned long)tbuf); |
731 | return -EFAULT; | 792 | return -EFAULT; |
@@ -738,22 +799,15 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
738 | return -EFAULT; | 799 | return -EFAULT; |
739 | } | 800 | } |
740 | } | 801 | } |
741 | snoop(&dev->dev, "control write: bRequest=%02x " | 802 | pipe = usb_sndctrlpipe(dev, 0); |
742 | "bRrequestType=%02x wValue=%04x " | 803 | snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT); |
743 | "wIndex=%04x wLength=%04x\n", | 804 | |
744 | ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, | ||
745 | ctrl.wIndex, ctrl.wLength); | ||
746 | if (usbfs_snoop) { | ||
747 | dev_info(&dev->dev, "control write: data: "); | ||
748 | for (j = 0; j < ctrl.wLength; ++j) | ||
749 | printk("%02x ", (unsigned char)(tbuf)[j]); | ||
750 | printk("\n"); | ||
751 | } | ||
752 | usb_unlock_device(dev); | 805 | usb_unlock_device(dev); |
753 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, | 806 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, |
754 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, | 807 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
755 | tbuf, ctrl.wLength, tmo); | 808 | tbuf, ctrl.wLength, tmo); |
756 | usb_lock_device(dev); | 809 | usb_lock_device(dev); |
810 | snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE); | ||
757 | } | 811 | } |
758 | free_page((unsigned long)tbuf); | 812 | free_page((unsigned long)tbuf); |
759 | if (i < 0 && i != -EPIPE) { | 813 | if (i < 0 && i != -EPIPE) { |
@@ -772,7 +826,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
772 | unsigned int tmo, len1, pipe; | 826 | unsigned int tmo, len1, pipe; |
773 | int len2; | 827 | int len2; |
774 | unsigned char *tbuf; | 828 | unsigned char *tbuf; |
775 | int i, j, ret; | 829 | int i, ret; |
776 | 830 | ||
777 | if (copy_from_user(&bulk, arg, sizeof(bulk))) | 831 | if (copy_from_user(&bulk, arg, sizeof(bulk))) |
778 | return -EFAULT; | 832 | return -EFAULT; |
@@ -799,18 +853,14 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
799 | kfree(tbuf); | 853 | kfree(tbuf); |
800 | return -EINVAL; | 854 | return -EINVAL; |
801 | } | 855 | } |
802 | snoop(&dev->dev, "bulk read: len=0x%02x timeout=%04d\n", | 856 | snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT); |
803 | bulk.len, bulk.timeout); | 857 | |
804 | usb_unlock_device(dev); | 858 | usb_unlock_device(dev); |
805 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); | 859 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); |
806 | usb_lock_device(dev); | 860 | usb_lock_device(dev); |
861 | snoop_urb(dev, NULL, pipe, len2, i, COMPLETE); | ||
862 | |||
807 | if (!i && len2) { | 863 | if (!i && len2) { |
808 | if (usbfs_snoop) { | ||
809 | dev_info(&dev->dev, "bulk read: data "); | ||
810 | for (j = 0; j < len2; ++j) | ||
811 | printk("%02x ", (u8)(tbuf)[j]); | ||
812 | printk("\n"); | ||
813 | } | ||
814 | if (copy_to_user(bulk.data, tbuf, len2)) { | 864 | if (copy_to_user(bulk.data, tbuf, len2)) { |
815 | kfree(tbuf); | 865 | kfree(tbuf); |
816 | return -EFAULT; | 866 | return -EFAULT; |
@@ -823,17 +873,12 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
823 | return -EFAULT; | 873 | return -EFAULT; |
824 | } | 874 | } |
825 | } | 875 | } |
826 | snoop(&dev->dev, "bulk write: len=0x%02x timeout=%04d\n", | 876 | snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT); |
827 | bulk.len, bulk.timeout); | 877 | |
828 | if (usbfs_snoop) { | ||
829 | dev_info(&dev->dev, "bulk write: data: "); | ||
830 | for (j = 0; j < len1; ++j) | ||
831 | printk("%02x ", (unsigned char)(tbuf)[j]); | ||
832 | printk("\n"); | ||
833 | } | ||
834 | usb_unlock_device(dev); | 878 | usb_unlock_device(dev); |
835 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); | 879 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); |
836 | usb_lock_device(dev); | 880 | usb_lock_device(dev); |
881 | snoop_urb(dev, NULL, pipe, len2, i, COMPLETE); | ||
837 | } | 882 | } |
838 | kfree(tbuf); | 883 | kfree(tbuf); |
839 | if (i < 0) | 884 | if (i < 0) |
@@ -991,6 +1036,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
991 | 1036 | ||
992 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | | 1037 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | |
993 | USBDEVFS_URB_SHORT_NOT_OK | | 1038 | USBDEVFS_URB_SHORT_NOT_OK | |
1039 | USBDEVFS_URB_BULK_CONTINUATION | | ||
994 | USBDEVFS_URB_NO_FSBR | | 1040 | USBDEVFS_URB_NO_FSBR | |
995 | USBDEVFS_URB_ZERO_PACKET | | 1041 | USBDEVFS_URB_ZERO_PACKET | |
996 | USBDEVFS_URB_NO_INTERRUPT)) | 1042 | USBDEVFS_URB_NO_INTERRUPT)) |
@@ -1051,13 +1097,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1051 | is_in = 0; | 1097 | is_in = 0; |
1052 | uurb->endpoint &= ~USB_DIR_IN; | 1098 | uurb->endpoint &= ~USB_DIR_IN; |
1053 | } | 1099 | } |
1054 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " | ||
1055 | "bRrequestType=%02x wValue=%04x " | ||
1056 | "wIndex=%04x wLength=%04x\n", | ||
1057 | dr->bRequest, dr->bRequestType, | ||
1058 | __le16_to_cpup(&dr->wValue), | ||
1059 | __le16_to_cpup(&dr->wIndex), | ||
1060 | __le16_to_cpup(&dr->wLength)); | ||
1061 | break; | 1100 | break; |
1062 | 1101 | ||
1063 | case USBDEVFS_URB_TYPE_BULK: | 1102 | case USBDEVFS_URB_TYPE_BULK: |
@@ -1070,7 +1109,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1070 | uurb->number_of_packets = 0; | 1109 | uurb->number_of_packets = 0; |
1071 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1110 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1072 | return -EINVAL; | 1111 | return -EINVAL; |
1073 | snoop(&ps->dev->dev, "bulk urb\n"); | ||
1074 | break; | 1112 | break; |
1075 | 1113 | ||
1076 | case USBDEVFS_URB_TYPE_ISO: | 1114 | case USBDEVFS_URB_TYPE_ISO: |
@@ -1097,12 +1135,12 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1097 | } | 1135 | } |
1098 | totlen += isopkt[u].length; | 1136 | totlen += isopkt[u].length; |
1099 | } | 1137 | } |
1100 | if (totlen > 32768) { | 1138 | /* 3072 * 64 microframes */ |
1139 | if (totlen > 196608) { | ||
1101 | kfree(isopkt); | 1140 | kfree(isopkt); |
1102 | return -EINVAL; | 1141 | return -EINVAL; |
1103 | } | 1142 | } |
1104 | uurb->buffer_length = totlen; | 1143 | uurb->buffer_length = totlen; |
1105 | snoop(&ps->dev->dev, "iso urb\n"); | ||
1106 | break; | 1144 | break; |
1107 | 1145 | ||
1108 | case USBDEVFS_URB_TYPE_INTERRUPT: | 1146 | case USBDEVFS_URB_TYPE_INTERRUPT: |
@@ -1111,7 +1149,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1111 | return -EINVAL; | 1149 | return -EINVAL; |
1112 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1150 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1113 | return -EINVAL; | 1151 | return -EINVAL; |
1114 | snoop(&ps->dev->dev, "interrupt urb\n"); | ||
1115 | break; | 1152 | break; |
1116 | 1153 | ||
1117 | default: | 1154 | default: |
@@ -1198,11 +1235,46 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1198 | return -EFAULT; | 1235 | return -EFAULT; |
1199 | } | 1236 | } |
1200 | } | 1237 | } |
1201 | snoop_urb(as->urb, as->userurb); | 1238 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, |
1239 | as->urb->transfer_buffer_length, 0, SUBMIT); | ||
1202 | async_newpending(as); | 1240 | async_newpending(as); |
1203 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { | 1241 | |
1242 | if (usb_endpoint_xfer_bulk(&ep->desc)) { | ||
1243 | spin_lock_irq(&ps->lock); | ||
1244 | |||
1245 | /* Not exactly the endpoint address; the direction bit is | ||
1246 | * shifted to the 0x10 position so that the value will be | ||
1247 | * between 0 and 31. | ||
1248 | */ | ||
1249 | as->bulk_addr = usb_endpoint_num(&ep->desc) | | ||
1250 | ((ep->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
1251 | >> 3); | ||
1252 | |||
1253 | /* If this bulk URB is the start of a new transfer, re-enable | ||
1254 | * the endpoint. Otherwise mark it as a continuation URB. | ||
1255 | */ | ||
1256 | if (uurb->flags & USBDEVFS_URB_BULK_CONTINUATION) | ||
1257 | as->bulk_status = AS_CONTINUATION; | ||
1258 | else | ||
1259 | ps->disabled_bulk_eps &= ~(1 << as->bulk_addr); | ||
1260 | |||
1261 | /* Don't accept continuation URBs if the endpoint is | ||
1262 | * disabled because of an earlier error. | ||
1263 | */ | ||
1264 | if (ps->disabled_bulk_eps & (1 << as->bulk_addr)) | ||
1265 | ret = -EREMOTEIO; | ||
1266 | else | ||
1267 | ret = usb_submit_urb(as->urb, GFP_ATOMIC); | ||
1268 | spin_unlock_irq(&ps->lock); | ||
1269 | } else { | ||
1270 | ret = usb_submit_urb(as->urb, GFP_KERNEL); | ||
1271 | } | ||
1272 | |||
1273 | if (ret) { | ||
1204 | dev_printk(KERN_DEBUG, &ps->dev->dev, | 1274 | dev_printk(KERN_DEBUG, &ps->dev->dev, |
1205 | "usbfs: usb_submit_urb returned %d\n", ret); | 1275 | "usbfs: usb_submit_urb returned %d\n", ret); |
1276 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, | ||
1277 | 0, ret, COMPLETE); | ||
1206 | async_removepending(as); | 1278 | async_removepending(as); |
1207 | free_async(as); | 1279 | free_async(as); |
1208 | return ret; | 1280 | return ret; |
@@ -1548,6 +1620,29 @@ static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg) | |||
1548 | } | 1620 | } |
1549 | #endif | 1621 | #endif |
1550 | 1622 | ||
1623 | static int proc_claim_port(struct dev_state *ps, void __user *arg) | ||
1624 | { | ||
1625 | unsigned portnum; | ||
1626 | int rc; | ||
1627 | |||
1628 | if (get_user(portnum, (unsigned __user *) arg)) | ||
1629 | return -EFAULT; | ||
1630 | rc = usb_hub_claim_port(ps->dev, portnum, ps); | ||
1631 | if (rc == 0) | ||
1632 | snoop(&ps->dev->dev, "port %d claimed by process %d: %s\n", | ||
1633 | portnum, task_pid_nr(current), current->comm); | ||
1634 | return rc; | ||
1635 | } | ||
1636 | |||
1637 | static int proc_release_port(struct dev_state *ps, void __user *arg) | ||
1638 | { | ||
1639 | unsigned portnum; | ||
1640 | |||
1641 | if (get_user(portnum, (unsigned __user *) arg)) | ||
1642 | return -EFAULT; | ||
1643 | return usb_hub_release_port(ps->dev, portnum, ps); | ||
1644 | } | ||
1645 | |||
1551 | /* | 1646 | /* |
1552 | * NOTE: All requests here that have interface numbers as parameters | 1647 | * NOTE: All requests here that have interface numbers as parameters |
1553 | * are assuming that somehow the configuration has been prevented from | 1648 | * are assuming that somehow the configuration has been prevented from |
@@ -1645,7 +1740,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, | |||
1645 | break; | 1740 | break; |
1646 | 1741 | ||
1647 | case USBDEVFS_REAPURBNDELAY32: | 1742 | case USBDEVFS_REAPURBNDELAY32: |
1648 | snoop(&dev->dev, "%s: REAPURBDELAY32\n", __func__); | 1743 | snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); |
1649 | ret = proc_reapurbnonblock_compat(ps, p); | 1744 | ret = proc_reapurbnonblock_compat(ps, p); |
1650 | break; | 1745 | break; |
1651 | 1746 | ||
@@ -1666,7 +1761,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, | |||
1666 | break; | 1761 | break; |
1667 | 1762 | ||
1668 | case USBDEVFS_REAPURBNDELAY: | 1763 | case USBDEVFS_REAPURBNDELAY: |
1669 | snoop(&dev->dev, "%s: REAPURBDELAY\n", __func__); | 1764 | snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); |
1670 | ret = proc_reapurbnonblock(ps, p); | 1765 | ret = proc_reapurbnonblock(ps, p); |
1671 | break; | 1766 | break; |
1672 | 1767 | ||
@@ -1689,6 +1784,16 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, | |||
1689 | snoop(&dev->dev, "%s: IOCTL\n", __func__); | 1784 | snoop(&dev->dev, "%s: IOCTL\n", __func__); |
1690 | ret = proc_ioctl_default(ps, p); | 1785 | ret = proc_ioctl_default(ps, p); |
1691 | break; | 1786 | break; |
1787 | |||
1788 | case USBDEVFS_CLAIM_PORT: | ||
1789 | snoop(&dev->dev, "%s: CLAIM_PORT\n", __func__); | ||
1790 | ret = proc_claim_port(ps, p); | ||
1791 | break; | ||
1792 | |||
1793 | case USBDEVFS_RELEASE_PORT: | ||
1794 | snoop(&dev->dev, "%s: RELEASE_PORT\n", __func__); | ||
1795 | ret = proc_release_port(ps, p); | ||
1796 | break; | ||
1692 | } | 1797 | } |
1693 | usb_unlock_device(dev); | 1798 | usb_unlock_device(dev); |
1694 | if (ret >= 0) | 1799 | if (ret >= 0) |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 69e5773abfce..4f864472c5c4 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -207,6 +207,9 @@ static int usb_probe_interface(struct device *dev) | |||
207 | 207 | ||
208 | intf->needs_binding = 0; | 208 | intf->needs_binding = 0; |
209 | 209 | ||
210 | if (usb_device_is_owned(udev)) | ||
211 | return -ENODEV; | ||
212 | |||
210 | if (udev->authorized == 0) { | 213 | if (udev->authorized == 0) { |
211 | dev_err(&intf->dev, "Device is not authorized for usage\n"); | 214 | dev_err(&intf->dev, "Device is not authorized for usage\n"); |
212 | return -ENODEV; | 215 | return -ENODEV; |
@@ -232,28 +235,35 @@ static int usb_probe_interface(struct device *dev) | |||
232 | /* The interface should always appear to be in use | 235 | /* The interface should always appear to be in use |
233 | * unless the driver suports autosuspend. | 236 | * unless the driver suports autosuspend. |
234 | */ | 237 | */ |
235 | intf->pm_usage_cnt = !(driver->supports_autosuspend); | 238 | atomic_set(&intf->pm_usage_cnt, !driver->supports_autosuspend); |
236 | 239 | ||
237 | /* Carry out a deferred switch to altsetting 0 */ | 240 | /* Carry out a deferred switch to altsetting 0 */ |
238 | if (intf->needs_altsetting0) { | 241 | if (intf->needs_altsetting0) { |
239 | usb_set_interface(udev, intf->altsetting[0]. | 242 | error = usb_set_interface(udev, intf->altsetting[0]. |
240 | desc.bInterfaceNumber, 0); | 243 | desc.bInterfaceNumber, 0); |
244 | if (error < 0) | ||
245 | goto err; | ||
246 | |||
241 | intf->needs_altsetting0 = 0; | 247 | intf->needs_altsetting0 = 0; |
242 | } | 248 | } |
243 | 249 | ||
244 | error = driver->probe(intf, id); | 250 | error = driver->probe(intf, id); |
245 | if (error) { | 251 | if (error) |
246 | mark_quiesced(intf); | 252 | goto err; |
247 | intf->needs_remote_wakeup = 0; | ||
248 | intf->condition = USB_INTERFACE_UNBOUND; | ||
249 | usb_cancel_queued_reset(intf); | ||
250 | } else | ||
251 | intf->condition = USB_INTERFACE_BOUND; | ||
252 | 253 | ||
254 | intf->condition = USB_INTERFACE_BOUND; | ||
253 | usb_autosuspend_device(udev); | 255 | usb_autosuspend_device(udev); |
254 | } | 256 | } |
255 | 257 | ||
256 | return error; | 258 | return error; |
259 | |||
260 | err: | ||
261 | mark_quiesced(intf); | ||
262 | intf->needs_remote_wakeup = 0; | ||
263 | intf->condition = USB_INTERFACE_UNBOUND; | ||
264 | usb_cancel_queued_reset(intf); | ||
265 | usb_autosuspend_device(udev); | ||
266 | return error; | ||
257 | } | 267 | } |
258 | 268 | ||
259 | /* called from driver core with dev locked */ | 269 | /* called from driver core with dev locked */ |
@@ -262,7 +272,7 @@ static int usb_unbind_interface(struct device *dev) | |||
262 | struct usb_driver *driver = to_usb_driver(dev->driver); | 272 | struct usb_driver *driver = to_usb_driver(dev->driver); |
263 | struct usb_interface *intf = to_usb_interface(dev); | 273 | struct usb_interface *intf = to_usb_interface(dev); |
264 | struct usb_device *udev; | 274 | struct usb_device *udev; |
265 | int error; | 275 | int error, r; |
266 | 276 | ||
267 | intf->condition = USB_INTERFACE_UNBINDING; | 277 | intf->condition = USB_INTERFACE_UNBINDING; |
268 | 278 | ||
@@ -290,11 +300,14 @@ static int usb_unbind_interface(struct device *dev) | |||
290 | * Just re-enable it without affecting the endpoint toggles. | 300 | * Just re-enable it without affecting the endpoint toggles. |
291 | */ | 301 | */ |
292 | usb_enable_interface(udev, intf, false); | 302 | usb_enable_interface(udev, intf, false); |
293 | } else if (!error && intf->dev.power.status == DPM_ON) | 303 | } else if (!error && intf->dev.power.status == DPM_ON) { |
294 | usb_set_interface(udev, intf->altsetting[0]. | 304 | r = usb_set_interface(udev, intf->altsetting[0]. |
295 | desc.bInterfaceNumber, 0); | 305 | desc.bInterfaceNumber, 0); |
296 | else | 306 | if (r < 0) |
307 | intf->needs_altsetting0 = 1; | ||
308 | } else { | ||
297 | intf->needs_altsetting0 = 1; | 309 | intf->needs_altsetting0 = 1; |
310 | } | ||
298 | usb_set_intfdata(intf, NULL); | 311 | usb_set_intfdata(intf, NULL); |
299 | 312 | ||
300 | intf->condition = USB_INTERFACE_UNBOUND; | 313 | intf->condition = USB_INTERFACE_UNBOUND; |
@@ -344,7 +357,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
344 | usb_pm_lock(udev); | 357 | usb_pm_lock(udev); |
345 | iface->condition = USB_INTERFACE_BOUND; | 358 | iface->condition = USB_INTERFACE_BOUND; |
346 | mark_active(iface); | 359 | mark_active(iface); |
347 | iface->pm_usage_cnt = !(driver->supports_autosuspend); | 360 | atomic_set(&iface->pm_usage_cnt, !driver->supports_autosuspend); |
348 | usb_pm_unlock(udev); | 361 | usb_pm_unlock(udev); |
349 | 362 | ||
350 | /* if interface was already added, bind now; else let | 363 | /* if interface was already added, bind now; else let |
@@ -1065,7 +1078,7 @@ static int autosuspend_check(struct usb_device *udev, int reschedule) | |||
1065 | intf = udev->actconfig->interface[i]; | 1078 | intf = udev->actconfig->interface[i]; |
1066 | if (!is_active(intf)) | 1079 | if (!is_active(intf)) |
1067 | continue; | 1080 | continue; |
1068 | if (intf->pm_usage_cnt > 0) | 1081 | if (atomic_read(&intf->pm_usage_cnt) > 0) |
1069 | return -EBUSY; | 1082 | return -EBUSY; |
1070 | if (intf->needs_remote_wakeup && | 1083 | if (intf->needs_remote_wakeup && |
1071 | !udev->do_remote_wakeup) { | 1084 | !udev->do_remote_wakeup) { |
@@ -1461,17 +1474,19 @@ static int usb_autopm_do_interface(struct usb_interface *intf, | |||
1461 | status = -ENODEV; | 1474 | status = -ENODEV; |
1462 | else { | 1475 | else { |
1463 | udev->auto_pm = 1; | 1476 | udev->auto_pm = 1; |
1464 | intf->pm_usage_cnt += inc_usage_cnt; | 1477 | atomic_add(inc_usage_cnt, &intf->pm_usage_cnt); |
1465 | udev->last_busy = jiffies; | 1478 | udev->last_busy = jiffies; |
1466 | if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { | 1479 | if (inc_usage_cnt >= 0 && |
1480 | atomic_read(&intf->pm_usage_cnt) > 0) { | ||
1467 | if (udev->state == USB_STATE_SUSPENDED) | 1481 | if (udev->state == USB_STATE_SUSPENDED) |
1468 | status = usb_resume_both(udev, | 1482 | status = usb_resume_both(udev, |
1469 | PMSG_AUTO_RESUME); | 1483 | PMSG_AUTO_RESUME); |
1470 | if (status != 0) | 1484 | if (status != 0) |
1471 | intf->pm_usage_cnt -= inc_usage_cnt; | 1485 | atomic_sub(inc_usage_cnt, &intf->pm_usage_cnt); |
1472 | else | 1486 | else |
1473 | udev->last_busy = jiffies; | 1487 | udev->last_busy = jiffies; |
1474 | } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { | 1488 | } else if (inc_usage_cnt <= 0 && |
1489 | atomic_read(&intf->pm_usage_cnt) <= 0) { | ||
1475 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); | 1490 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); |
1476 | } | 1491 | } |
1477 | } | 1492 | } |
@@ -1516,7 +1531,7 @@ void usb_autopm_put_interface(struct usb_interface *intf) | |||
1516 | 1531 | ||
1517 | status = usb_autopm_do_interface(intf, -1); | 1532 | status = usb_autopm_do_interface(intf, -1); |
1518 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1533 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", |
1519 | __func__, status, intf->pm_usage_cnt); | 1534 | __func__, status, atomic_read(&intf->pm_usage_cnt)); |
1520 | } | 1535 | } |
1521 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface); | 1536 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface); |
1522 | 1537 | ||
@@ -1544,10 +1559,10 @@ void usb_autopm_put_interface_async(struct usb_interface *intf) | |||
1544 | status = -ENODEV; | 1559 | status = -ENODEV; |
1545 | } else { | 1560 | } else { |
1546 | udev->last_busy = jiffies; | 1561 | udev->last_busy = jiffies; |
1547 | --intf->pm_usage_cnt; | 1562 | atomic_dec(&intf->pm_usage_cnt); |
1548 | if (udev->autosuspend_disabled || udev->autosuspend_delay < 0) | 1563 | if (udev->autosuspend_disabled || udev->autosuspend_delay < 0) |
1549 | status = -EPERM; | 1564 | status = -EPERM; |
1550 | else if (intf->pm_usage_cnt <= 0 && | 1565 | else if (atomic_read(&intf->pm_usage_cnt) <= 0 && |
1551 | !timer_pending(&udev->autosuspend.timer)) { | 1566 | !timer_pending(&udev->autosuspend.timer)) { |
1552 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | 1567 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, |
1553 | round_jiffies_up_relative( | 1568 | round_jiffies_up_relative( |
@@ -1555,7 +1570,7 @@ void usb_autopm_put_interface_async(struct usb_interface *intf) | |||
1555 | } | 1570 | } |
1556 | } | 1571 | } |
1557 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1572 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", |
1558 | __func__, status, intf->pm_usage_cnt); | 1573 | __func__, status, atomic_read(&intf->pm_usage_cnt)); |
1559 | } | 1574 | } |
1560 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); | 1575 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); |
1561 | 1576 | ||
@@ -1599,7 +1614,7 @@ int usb_autopm_get_interface(struct usb_interface *intf) | |||
1599 | 1614 | ||
1600 | status = usb_autopm_do_interface(intf, 1); | 1615 | status = usb_autopm_do_interface(intf, 1); |
1601 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1616 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", |
1602 | __func__, status, intf->pm_usage_cnt); | 1617 | __func__, status, atomic_read(&intf->pm_usage_cnt)); |
1603 | return status; | 1618 | return status; |
1604 | } | 1619 | } |
1605 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface); | 1620 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface); |
@@ -1627,10 +1642,14 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) | |||
1627 | status = -ENODEV; | 1642 | status = -ENODEV; |
1628 | else if (udev->autoresume_disabled) | 1643 | else if (udev->autoresume_disabled) |
1629 | status = -EPERM; | 1644 | status = -EPERM; |
1630 | else if (++intf->pm_usage_cnt > 0 && udev->state == USB_STATE_SUSPENDED) | 1645 | else { |
1631 | queue_work(ksuspend_usb_wq, &udev->autoresume); | 1646 | atomic_inc(&intf->pm_usage_cnt); |
1647 | if (atomic_read(&intf->pm_usage_cnt) > 0 && | ||
1648 | udev->state == USB_STATE_SUSPENDED) | ||
1649 | queue_work(ksuspend_usb_wq, &udev->autoresume); | ||
1650 | } | ||
1632 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1651 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", |
1633 | __func__, status, intf->pm_usage_cnt); | 1652 | __func__, status, atomic_read(&intf->pm_usage_cnt)); |
1634 | return status; | 1653 | return status; |
1635 | } | 1654 | } |
1636 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); | 1655 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); |
@@ -1652,7 +1671,7 @@ int usb_autopm_set_interface(struct usb_interface *intf) | |||
1652 | 1671 | ||
1653 | status = usb_autopm_do_interface(intf, 0); | 1672 | status = usb_autopm_do_interface(intf, 0); |
1654 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1673 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", |
1655 | __func__, status, intf->pm_usage_cnt); | 1674 | __func__, status, atomic_read(&intf->pm_usage_cnt)); |
1656 | return status; | 1675 | return status; |
1657 | } | 1676 | } |
1658 | EXPORT_SYMBOL_GPL(usb_autopm_set_interface); | 1677 | EXPORT_SYMBOL_GPL(usb_autopm_set_interface); |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 30ecac3af15a..05e6d313961e 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -158,7 +158,9 @@ static int generic_probe(struct usb_device *udev) | |||
158 | /* Choose and set the configuration. This registers the interfaces | 158 | /* Choose and set the configuration. This registers the interfaces |
159 | * with the driver core and lets interface drivers bind to them. | 159 | * with the driver core and lets interface drivers bind to them. |
160 | */ | 160 | */ |
161 | if (udev->authorized == 0) | 161 | if (usb_device_is_owned(udev)) |
162 | ; /* Don't configure if the device is owned */ | ||
163 | else if (udev->authorized == 0) | ||
162 | dev_err(&udev->dev, "Device is not authorized for usage\n"); | 164 | dev_err(&udev->dev, "Device is not authorized for usage\n"); |
163 | else { | 165 | else { |
164 | c = usb_choose_configuration(udev); | 166 | c = usb_choose_configuration(udev); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 95ccfa0b9fc5..34de475f016e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -337,72 +337,89 @@ static const u8 ss_rh_config_descriptor[] = { | |||
337 | 337 | ||
338 | /*-------------------------------------------------------------------------*/ | 338 | /*-------------------------------------------------------------------------*/ |
339 | 339 | ||
340 | /* | 340 | /** |
341 | * helper routine for returning string descriptors in UTF-16LE | 341 | * ascii2desc() - Helper routine for producing UTF-16LE string descriptors |
342 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset | 342 | * @s: Null-terminated ASCII (actually ISO-8859-1) string |
343 | * @buf: Buffer for USB string descriptor (header + UTF-16LE) | ||
344 | * @len: Length (in bytes; may be odd) of descriptor buffer. | ||
345 | * | ||
346 | * The return value is the number of bytes filled in: 2 + 2*strlen(s) or | ||
347 | * buflen, whichever is less. | ||
348 | * | ||
349 | * USB String descriptors can contain at most 126 characters; input | ||
350 | * strings longer than that are truncated. | ||
343 | */ | 351 | */ |
344 | static unsigned ascii2utf(char *s, u8 *utf, int utfmax) | 352 | static unsigned |
353 | ascii2desc(char const *s, u8 *buf, unsigned len) | ||
345 | { | 354 | { |
346 | unsigned retval; | 355 | unsigned n, t = 2 + 2*strlen(s); |
347 | 356 | ||
348 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { | 357 | if (t > 254) |
349 | *utf++ = *s++; | 358 | t = 254; /* Longest possible UTF string descriptor */ |
350 | *utf++ = 0; | 359 | if (len > t) |
351 | } | 360 | len = t; |
352 | if (utfmax > 0) { | 361 | |
353 | *utf = *s; | 362 | t += USB_DT_STRING << 8; /* Now t is first 16 bits to store */ |
354 | ++retval; | 363 | |
364 | n = len; | ||
365 | while (n--) { | ||
366 | *buf++ = t; | ||
367 | if (!n--) | ||
368 | break; | ||
369 | *buf++ = t >> 8; | ||
370 | t = (unsigned char)*s++; | ||
355 | } | 371 | } |
356 | return retval; | 372 | return len; |
357 | } | 373 | } |
358 | 374 | ||
359 | /* | 375 | /** |
360 | * rh_string - provides manufacturer, product and serial strings for root hub | 376 | * rh_string() - provides string descriptors for root hub |
361 | * @id: the string ID number (1: serial number, 2: product, 3: vendor) | 377 | * @id: the string ID number (0: langids, 1: serial #, 2: product, 3: vendor) |
362 | * @hcd: the host controller for this root hub | 378 | * @hcd: the host controller for this root hub |
363 | * @data: return packet in UTF-16 LE | 379 | * @data: buffer for output packet |
364 | * @len: length of the return packet | 380 | * @len: length of the provided buffer |
365 | * | 381 | * |
366 | * Produces either a manufacturer, product or serial number string for the | 382 | * Produces either a manufacturer, product or serial number string for the |
367 | * virtual root hub device. | 383 | * virtual root hub device. |
384 | * Returns the number of bytes filled in: the length of the descriptor or | ||
385 | * of the provided buffer, whichever is less. | ||
368 | */ | 386 | */ |
369 | static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len) | 387 | static unsigned |
388 | rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len) | ||
370 | { | 389 | { |
371 | char buf [100]; | 390 | char buf[100]; |
391 | char const *s; | ||
392 | static char const langids[4] = {4, USB_DT_STRING, 0x09, 0x04}; | ||
372 | 393 | ||
373 | // language ids | 394 | // language ids |
374 | if (id == 0) { | 395 | switch (id) { |
375 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ | 396 | case 0: |
376 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ | 397 | /* Array of LANGID codes (0x0409 is MSFT-speak for "en-us") */ |
377 | len = min_t(unsigned, len, 4); | 398 | /* See http://www.usb.org/developers/docs/USB_LANGIDs.pdf */ |
378 | memcpy (data, buf, len); | 399 | if (len > 4) |
400 | len = 4; | ||
401 | memcpy(data, langids, len); | ||
379 | return len; | 402 | return len; |
380 | 403 | case 1: | |
381 | // serial number | 404 | /* Serial number */ |
382 | } else if (id == 1) { | 405 | s = hcd->self.bus_name; |
383 | strlcpy (buf, hcd->self.bus_name, sizeof buf); | 406 | break; |
384 | 407 | case 2: | |
385 | // product description | 408 | /* Product name */ |
386 | } else if (id == 2) { | 409 | s = hcd->product_desc; |
387 | strlcpy (buf, hcd->product_desc, sizeof buf); | 410 | break; |
388 | 411 | case 3: | |
389 | // id 3 == vendor description | 412 | /* Manufacturer */ |
390 | } else if (id == 3) { | ||
391 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, | 413 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, |
392 | init_utsname()->release, hcd->driver->description); | 414 | init_utsname()->release, hcd->driver->description); |
393 | } | 415 | s = buf; |
394 | 416 | break; | |
395 | switch (len) { /* All cases fall through */ | ||
396 | default: | 417 | default: |
397 | len = 2 + ascii2utf (buf, data + 2, len - 2); | 418 | /* Can't happen; caller guarantees it */ |
398 | case 2: | 419 | return 0; |
399 | data [1] = 3; /* type == string */ | ||
400 | case 1: | ||
401 | data [0] = 2 * (strlen (buf) + 1); | ||
402 | case 0: | ||
403 | ; /* Compiler wants a statement here */ | ||
404 | } | 420 | } |
405 | return len; | 421 | |
422 | return ascii2desc(s, data, len); | ||
406 | } | 423 | } |
407 | 424 | ||
408 | 425 | ||
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index ec5c67ea07b7..79782a1c43f6 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -267,6 +267,11 @@ struct hc_driver { | |||
267 | void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); | 267 | void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); |
268 | /* Returns the hardware-chosen device address */ | 268 | /* Returns the hardware-chosen device address */ |
269 | int (*address_device)(struct usb_hcd *, struct usb_device *udev); | 269 | int (*address_device)(struct usb_hcd *, struct usb_device *udev); |
270 | /* Notifies the HCD after a hub descriptor is fetched. | ||
271 | * Will block. | ||
272 | */ | ||
273 | int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev, | ||
274 | struct usb_tt *tt, gfp_t mem_flags); | ||
270 | }; | 275 | }; |
271 | 276 | ||
272 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 277 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 71f86c60d83c..5ce839137ad6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -78,6 +78,7 @@ struct usb_hub { | |||
78 | u8 indicator[USB_MAXCHILDREN]; | 78 | u8 indicator[USB_MAXCHILDREN]; |
79 | struct delayed_work leds; | 79 | struct delayed_work leds; |
80 | struct delayed_work init_work; | 80 | struct delayed_work init_work; |
81 | void **port_owners; | ||
81 | }; | 82 | }; |
82 | 83 | ||
83 | 84 | ||
@@ -162,8 +163,10 @@ static inline char *portspeed(int portstatus) | |||
162 | } | 163 | } |
163 | 164 | ||
164 | /* Note that hdev or one of its children must be locked! */ | 165 | /* Note that hdev or one of its children must be locked! */ |
165 | static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev) | 166 | static struct usb_hub *hdev_to_hub(struct usb_device *hdev) |
166 | { | 167 | { |
168 | if (!hdev || !hdev->actconfig) | ||
169 | return NULL; | ||
167 | return usb_get_intfdata(hdev->actconfig->interface[0]); | 170 | return usb_get_intfdata(hdev->actconfig->interface[0]); |
168 | } | 171 | } |
169 | 172 | ||
@@ -372,7 +375,7 @@ static void kick_khubd(struct usb_hub *hub) | |||
372 | unsigned long flags; | 375 | unsigned long flags; |
373 | 376 | ||
374 | /* Suppress autosuspend until khubd runs */ | 377 | /* Suppress autosuspend until khubd runs */ |
375 | to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; | 378 | atomic_set(&to_usb_interface(hub->intfdev)->pm_usage_cnt, 1); |
376 | 379 | ||
377 | spin_lock_irqsave(&hub_event_lock, flags); | 380 | spin_lock_irqsave(&hub_event_lock, flags); |
378 | if (!hub->disconnected && list_empty(&hub->event_list)) { | 381 | if (!hub->disconnected && list_empty(&hub->event_list)) { |
@@ -384,8 +387,10 @@ static void kick_khubd(struct usb_hub *hub) | |||
384 | 387 | ||
385 | void usb_kick_khubd(struct usb_device *hdev) | 388 | void usb_kick_khubd(struct usb_device *hdev) |
386 | { | 389 | { |
387 | /* FIXME: What if hdev isn't bound to the hub driver? */ | 390 | struct usb_hub *hub = hdev_to_hub(hdev); |
388 | kick_khubd(hdev_to_hub(hdev)); | 391 | |
392 | if (hub) | ||
393 | kick_khubd(hub); | ||
389 | } | 394 | } |
390 | 395 | ||
391 | 396 | ||
@@ -677,7 +682,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
677 | msecs_to_jiffies(delay)); | 682 | msecs_to_jiffies(delay)); |
678 | 683 | ||
679 | /* Suppress autosuspend until init is done */ | 684 | /* Suppress autosuspend until init is done */ |
680 | to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; | 685 | atomic_set(&to_usb_interface(hub->intfdev)-> |
686 | pm_usage_cnt, 1); | ||
681 | return; /* Continues at init2: below */ | 687 | return; /* Continues at init2: below */ |
682 | } else { | 688 | } else { |
683 | hub_power_on(hub, true); | 689 | hub_power_on(hub, true); |
@@ -854,25 +860,24 @@ static int hub_post_reset(struct usb_interface *intf) | |||
854 | static int hub_configure(struct usb_hub *hub, | 860 | static int hub_configure(struct usb_hub *hub, |
855 | struct usb_endpoint_descriptor *endpoint) | 861 | struct usb_endpoint_descriptor *endpoint) |
856 | { | 862 | { |
863 | struct usb_hcd *hcd; | ||
857 | struct usb_device *hdev = hub->hdev; | 864 | struct usb_device *hdev = hub->hdev; |
858 | struct device *hub_dev = hub->intfdev; | 865 | struct device *hub_dev = hub->intfdev; |
859 | u16 hubstatus, hubchange; | 866 | u16 hubstatus, hubchange; |
860 | u16 wHubCharacteristics; | 867 | u16 wHubCharacteristics; |
861 | unsigned int pipe; | 868 | unsigned int pipe; |
862 | int maxp, ret; | 869 | int maxp, ret; |
863 | char *message; | 870 | char *message = "out of memory"; |
864 | 871 | ||
865 | hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL, | 872 | hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL, |
866 | &hub->buffer_dma); | 873 | &hub->buffer_dma); |
867 | if (!hub->buffer) { | 874 | if (!hub->buffer) { |
868 | message = "can't allocate hub irq buffer"; | ||
869 | ret = -ENOMEM; | 875 | ret = -ENOMEM; |
870 | goto fail; | 876 | goto fail; |
871 | } | 877 | } |
872 | 878 | ||
873 | hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL); | 879 | hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL); |
874 | if (!hub->status) { | 880 | if (!hub->status) { |
875 | message = "can't kmalloc hub status buffer"; | ||
876 | ret = -ENOMEM; | 881 | ret = -ENOMEM; |
877 | goto fail; | 882 | goto fail; |
878 | } | 883 | } |
@@ -880,7 +885,6 @@ static int hub_configure(struct usb_hub *hub, | |||
880 | 885 | ||
881 | hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); | 886 | hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); |
882 | if (!hub->descriptor) { | 887 | if (!hub->descriptor) { |
883 | message = "can't kmalloc hub descriptor"; | ||
884 | ret = -ENOMEM; | 888 | ret = -ENOMEM; |
885 | goto fail; | 889 | goto fail; |
886 | } | 890 | } |
@@ -904,6 +908,12 @@ static int hub_configure(struct usb_hub *hub, | |||
904 | dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, | 908 | dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, |
905 | (hdev->maxchild == 1) ? "" : "s"); | 909 | (hdev->maxchild == 1) ? "" : "s"); |
906 | 910 | ||
911 | hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL); | ||
912 | if (!hub->port_owners) { | ||
913 | ret = -ENOMEM; | ||
914 | goto fail; | ||
915 | } | ||
916 | |||
907 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 917 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); |
908 | 918 | ||
909 | if (wHubCharacteristics & HUB_CHAR_COMPOUND) { | 919 | if (wHubCharacteristics & HUB_CHAR_COMPOUND) { |
@@ -1052,6 +1062,19 @@ static int hub_configure(struct usb_hub *hub, | |||
1052 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", | 1062 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", |
1053 | hub->mA_per_port); | 1063 | hub->mA_per_port); |
1054 | 1064 | ||
1065 | /* Update the HCD's internal representation of this hub before khubd | ||
1066 | * starts getting port status changes for devices under the hub. | ||
1067 | */ | ||
1068 | hcd = bus_to_hcd(hdev->bus); | ||
1069 | if (hcd->driver->update_hub_device) { | ||
1070 | ret = hcd->driver->update_hub_device(hcd, hdev, | ||
1071 | &hub->tt, GFP_KERNEL); | ||
1072 | if (ret < 0) { | ||
1073 | message = "can't update HCD hub info"; | ||
1074 | goto fail; | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1055 | ret = hub_hub_status(hub, &hubstatus, &hubchange); | 1078 | ret = hub_hub_status(hub, &hubstatus, &hubchange); |
1056 | if (ret < 0) { | 1079 | if (ret < 0) { |
1057 | message = "can't get hub status"; | 1080 | message = "can't get hub status"; |
@@ -1082,7 +1105,6 @@ static int hub_configure(struct usb_hub *hub, | |||
1082 | 1105 | ||
1083 | hub->urb = usb_alloc_urb(0, GFP_KERNEL); | 1106 | hub->urb = usb_alloc_urb(0, GFP_KERNEL); |
1084 | if (!hub->urb) { | 1107 | if (!hub->urb) { |
1085 | message = "couldn't allocate interrupt urb"; | ||
1086 | ret = -ENOMEM; | 1108 | ret = -ENOMEM; |
1087 | goto fail; | 1109 | goto fail; |
1088 | } | 1110 | } |
@@ -1131,11 +1153,13 @@ static void hub_disconnect(struct usb_interface *intf) | |||
1131 | hub_quiesce(hub, HUB_DISCONNECT); | 1153 | hub_quiesce(hub, HUB_DISCONNECT); |
1132 | 1154 | ||
1133 | usb_set_intfdata (intf, NULL); | 1155 | usb_set_intfdata (intf, NULL); |
1156 | hub->hdev->maxchild = 0; | ||
1134 | 1157 | ||
1135 | if (hub->hdev->speed == USB_SPEED_HIGH) | 1158 | if (hub->hdev->speed == USB_SPEED_HIGH) |
1136 | highspeed_hubs--; | 1159 | highspeed_hubs--; |
1137 | 1160 | ||
1138 | usb_free_urb(hub->urb); | 1161 | usb_free_urb(hub->urb); |
1162 | kfree(hub->port_owners); | ||
1139 | kfree(hub->descriptor); | 1163 | kfree(hub->descriptor); |
1140 | kfree(hub->status); | 1164 | kfree(hub->status); |
1141 | usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer, | 1165 | usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer, |
@@ -1250,6 +1274,79 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) | |||
1250 | } | 1274 | } |
1251 | } | 1275 | } |
1252 | 1276 | ||
1277 | /* | ||
1278 | * Allow user programs to claim ports on a hub. When a device is attached | ||
1279 | * to one of these "claimed" ports, the program will "own" the device. | ||
1280 | */ | ||
1281 | static int find_port_owner(struct usb_device *hdev, unsigned port1, | ||
1282 | void ***ppowner) | ||
1283 | { | ||
1284 | if (hdev->state == USB_STATE_NOTATTACHED) | ||
1285 | return -ENODEV; | ||
1286 | if (port1 == 0 || port1 > hdev->maxchild) | ||
1287 | return -EINVAL; | ||
1288 | |||
1289 | /* This assumes that devices not managed by the hub driver | ||
1290 | * will always have maxchild equal to 0. | ||
1291 | */ | ||
1292 | *ppowner = &(hdev_to_hub(hdev)->port_owners[port1 - 1]); | ||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | /* In the following three functions, the caller must hold hdev's lock */ | ||
1297 | int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner) | ||
1298 | { | ||
1299 | int rc; | ||
1300 | void **powner; | ||
1301 | |||
1302 | rc = find_port_owner(hdev, port1, &powner); | ||
1303 | if (rc) | ||
1304 | return rc; | ||
1305 | if (*powner) | ||
1306 | return -EBUSY; | ||
1307 | *powner = owner; | ||
1308 | return rc; | ||
1309 | } | ||
1310 | |||
1311 | int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner) | ||
1312 | { | ||
1313 | int rc; | ||
1314 | void **powner; | ||
1315 | |||
1316 | rc = find_port_owner(hdev, port1, &powner); | ||
1317 | if (rc) | ||
1318 | return rc; | ||
1319 | if (*powner != owner) | ||
1320 | return -ENOENT; | ||
1321 | *powner = NULL; | ||
1322 | return rc; | ||
1323 | } | ||
1324 | |||
1325 | void usb_hub_release_all_ports(struct usb_device *hdev, void *owner) | ||
1326 | { | ||
1327 | int n; | ||
1328 | void **powner; | ||
1329 | |||
1330 | n = find_port_owner(hdev, 1, &powner); | ||
1331 | if (n == 0) { | ||
1332 | for (; n < hdev->maxchild; (++n, ++powner)) { | ||
1333 | if (*powner == owner) | ||
1334 | *powner = NULL; | ||
1335 | } | ||
1336 | } | ||
1337 | } | ||
1338 | |||
1339 | /* The caller must hold udev's lock */ | ||
1340 | bool usb_device_is_owned(struct usb_device *udev) | ||
1341 | { | ||
1342 | struct usb_hub *hub; | ||
1343 | |||
1344 | if (udev->state == USB_STATE_NOTATTACHED || !udev->parent) | ||
1345 | return false; | ||
1346 | hub = hdev_to_hub(udev->parent); | ||
1347 | return !!hub->port_owners[udev->portnum - 1]; | ||
1348 | } | ||
1349 | |||
1253 | 1350 | ||
1254 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) | 1351 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) |
1255 | { | 1352 | { |
@@ -2849,14 +2946,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2849 | /* For a suspended device, treat this as a | 2946 | /* For a suspended device, treat this as a |
2850 | * remote wakeup event. | 2947 | * remote wakeup event. |
2851 | */ | 2948 | */ |
2852 | if (udev->do_remote_wakeup) | 2949 | status = remote_wakeup(udev); |
2853 | status = remote_wakeup(udev); | ||
2854 | |||
2855 | /* Otherwise leave it be; devices can't tell the | ||
2856 | * difference between suspended and disabled. | ||
2857 | */ | ||
2858 | else | ||
2859 | status = 0; | ||
2860 | #endif | 2950 | #endif |
2861 | 2951 | ||
2862 | } else { | 2952 | } else { |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 9720e699f472..da718e84d58d 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -459,35 +459,23 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
459 | io->urbs[i]->context = io; | 459 | io->urbs[i]->context = io; |
460 | 460 | ||
461 | /* | 461 | /* |
462 | * Some systems need to revert to PIO when DMA is | 462 | * Some systems need to revert to PIO when DMA is temporarily |
463 | * temporarily unavailable. For their sakes, both | 463 | * unavailable. For their sakes, both transfer_buffer and |
464 | * transfer_buffer and transfer_dma are set when | 464 | * transfer_dma are set when possible. |
465 | * possible. However this can only work on systems | ||
466 | * without: | ||
467 | * | 465 | * |
468 | * - HIGHMEM, since DMA buffers located in high memory | 466 | * Note that if IOMMU coalescing occurred, we cannot |
469 | * are not directly addressable by the CPU for PIO; | 467 | * trust sg_page anymore, so check if S/G list shrunk. |
470 | * | ||
471 | * - IOMMU, since dma_map_sg() is allowed to use an | ||
472 | * IOMMU to make virtually discontiguous buffers be | ||
473 | * "dma-contiguous" so that PIO and DMA need diferent | ||
474 | * numbers of URBs. | ||
475 | * | ||
476 | * So when HIGHMEM or IOMMU are in use, transfer_buffer | ||
477 | * is NULL to prevent stale pointers and to help spot | ||
478 | * bugs. | ||
479 | */ | 468 | */ |
469 | if (io->nents == io->entries && !PageHighMem(sg_page(sg))) | ||
470 | io->urbs[i]->transfer_buffer = sg_virt(sg); | ||
471 | else | ||
472 | io->urbs[i]->transfer_buffer = NULL; | ||
473 | |||
480 | if (dma) { | 474 | if (dma) { |
481 | io->urbs[i]->transfer_dma = sg_dma_address(sg); | 475 | io->urbs[i]->transfer_dma = sg_dma_address(sg); |
482 | len = sg_dma_len(sg); | 476 | len = sg_dma_len(sg); |
483 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU) | ||
484 | io->urbs[i]->transfer_buffer = NULL; | ||
485 | #else | ||
486 | io->urbs[i]->transfer_buffer = sg_virt(sg); | ||
487 | #endif | ||
488 | } else { | 477 | } else { |
489 | /* hc may use _only_ transfer_buffer */ | 478 | /* hc may use _only_ transfer_buffer */ |
490 | io->urbs[i]->transfer_buffer = sg_virt(sg); | ||
491 | len = sg->length; | 479 | len = sg->length; |
492 | } | 480 | } |
493 | 481 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 43ee943d757a..b1b85abb9a2d 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -413,8 +413,13 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
413 | } else { | 413 | } else { |
414 | snprintf(dev->devpath, sizeof dev->devpath, | 414 | snprintf(dev->devpath, sizeof dev->devpath, |
415 | "%s.%d", parent->devpath, port1); | 415 | "%s.%d", parent->devpath, port1); |
416 | dev->route = parent->route + | 416 | /* Route string assumes hubs have less than 16 ports */ |
417 | (port1 << ((parent->level - 1)*4)); | 417 | if (port1 < 15) |
418 | dev->route = parent->route + | ||
419 | (port1 << ((parent->level - 1)*4)); | ||
420 | else | ||
421 | dev->route = parent->route + | ||
422 | (15 << ((parent->level - 1)*4)); | ||
418 | } | 423 | } |
419 | 424 | ||
420 | dev->dev.parent = &parent->dev; | 425 | dev->dev.parent = &parent->dev; |
@@ -914,11 +919,11 @@ int usb_buffer_map_sg(const struct usb_device *dev, int is_in, | |||
914 | || !(bus = dev->bus) | 919 | || !(bus = dev->bus) |
915 | || !(controller = bus->controller) | 920 | || !(controller = bus->controller) |
916 | || !controller->dma_mask) | 921 | || !controller->dma_mask) |
917 | return -1; | 922 | return -EINVAL; |
918 | 923 | ||
919 | /* FIXME generic api broken like pci, can't report errors */ | 924 | /* FIXME generic api broken like pci, can't report errors */ |
920 | return dma_map_sg(controller, sg, nents, | 925 | return dma_map_sg(controller, sg, nents, |
921 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 926 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE) ? : -ENOMEM; |
922 | } | 927 | } |
923 | EXPORT_SYMBOL_GPL(usb_buffer_map_sg); | 928 | EXPORT_SYMBOL_GPL(usb_buffer_map_sg); |
924 | 929 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index c0e0ae2bb8e7..9a8b15e6377a 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -37,6 +37,13 @@ extern int usb_match_device(struct usb_device *dev, | |||
37 | extern void usb_forced_unbind_intf(struct usb_interface *intf); | 37 | extern void usb_forced_unbind_intf(struct usb_interface *intf); |
38 | extern void usb_rebind_intf(struct usb_interface *intf); | 38 | extern void usb_rebind_intf(struct usb_interface *intf); |
39 | 39 | ||
40 | extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port, | ||
41 | void *owner); | ||
42 | extern int usb_hub_release_port(struct usb_device *hdev, unsigned port, | ||
43 | void *owner); | ||
44 | extern void usb_hub_release_all_ports(struct usb_device *hdev, void *owner); | ||
45 | extern bool usb_device_is_owned(struct usb_device *udev); | ||
46 | |||
40 | extern int usb_hub_init(void); | 47 | extern int usb_hub_init(void); |
41 | extern void usb_hub_cleanup(void); | 48 | extern void usb_hub_cleanup(void); |
42 | extern int usb_major_init(void); | 49 | extern int usb_major_init(void); |