diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 13:23:47 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 13:23:47 -0400 |
| commit | 9fc377799bc9bfd8d5cb35d0d1ea2e2458cbdbb3 (patch) | |
| tree | fe93603b4e33dd50ff5f95ff769a0748b230cdf9 /drivers/usb/core | |
| parent | 5e23ae49960d05f578a73ecd19749c45af682c2b (diff) | |
| parent | e387ef5c47ddeaeaa3cbdc54424cdb7a28dae2c0 (diff) | |
Merge tag 'usb-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman:
"Here's the big USB patch set for the 3.6-rc1 merge window.
Lots of little changes in here, primarily for gadget controllers and
drivers. There's some scsi changes that I think also went in through
the scsi tree, but they merge just fine. All of these patches have
been in the linux-next tree for a while now.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Fix up trivial conflicts in include/scsi/scsi_device.h (same libata
conflict that Jeff had already encountered)
* tag 'usb-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (207 commits)
usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams
usb: Add quirk detection based on interface information
usb: s3c-hsotg: Add header file protection macros in s3c-hsotg.h
USB: ehci-s5p: Add vbus setup function to the s5p ehci glue layer
USB: add USB_VENDOR_AND_INTERFACE_INFO() macro
USB: notify phy when root hub port connect change
USB: remove 8 bytes of padding from usb_host_interface on 64 bit builds
USB: option: add ZTE MF821D
USB: sierra: QMI mode MC7710 moved to qcserial
USB: qcserial: adding Sierra Wireless devices
USB: qcserial: support generic Qualcomm serial ports
USB: qcserial: make probe more flexible
USB: qcserial: centralize probe exit path
USB: qcserial: consolidate usb_set_interface calls
USB: ehci-s5p: Add support for device tree
USB: ohci-exynos: Add support for device tree
USB: ehci-omap: fix compile failure(v1)
usb: host: tegra: pass correct pointer in ehci_setup()
USB: ehci-fsl: Update ifdef check to work on 64-bit ppc
USB: serial: keyspan: Removed unrequired parentheses.
...
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/devio.c | 169 | ||||
| -rw-r--r-- | drivers/usb/core/driver.c | 48 | ||||
| -rw-r--r-- | drivers/usb/core/file.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 10 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 139 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 16 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 151 | ||||
| -rw-r--r-- | drivers/usb/core/sysfs.c | 15 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 1 | ||||
| -rw-r--r-- | drivers/usb/core/usb.h | 13 |
10 files changed, 414 insertions, 150 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e0f107948eba..ebb8a9de8b5f 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <linux/notifier.h> | 47 | #include <linux/notifier.h> |
| 48 | #include <linux/security.h> | 48 | #include <linux/security.h> |
| 49 | #include <linux/user_namespace.h> | 49 | #include <linux/user_namespace.h> |
| 50 | #include <linux/scatterlist.h> | ||
| 50 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
| 51 | #include <asm/byteorder.h> | 52 | #include <asm/byteorder.h> |
| 52 | #include <linux/moduleparam.h> | 53 | #include <linux/moduleparam.h> |
| @@ -55,6 +56,7 @@ | |||
| 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 |
| 59 | #define USB_SG_SIZE 16384 /* split-size for large txs */ | ||
| 58 | 60 | ||
| 59 | /* Mutual exclusion for removal, open, and release */ | 61 | /* Mutual exclusion for removal, open, and release */ |
| 60 | DEFINE_MUTEX(usbfs_mutex); | 62 | DEFINE_MUTEX(usbfs_mutex); |
| @@ -285,9 +287,16 @@ static struct async *alloc_async(unsigned int numisoframes) | |||
| 285 | 287 | ||
| 286 | static void free_async(struct async *as) | 288 | static void free_async(struct async *as) |
| 287 | { | 289 | { |
| 290 | int i; | ||
| 291 | |||
| 288 | put_pid(as->pid); | 292 | put_pid(as->pid); |
| 289 | if (as->cred) | 293 | if (as->cred) |
| 290 | put_cred(as->cred); | 294 | put_cred(as->cred); |
| 295 | for (i = 0; i < as->urb->num_sgs; i++) { | ||
| 296 | if (sg_page(&as->urb->sg[i])) | ||
| 297 | kfree(sg_virt(&as->urb->sg[i])); | ||
| 298 | } | ||
| 299 | kfree(as->urb->sg); | ||
| 291 | kfree(as->urb->transfer_buffer); | 300 | kfree(as->urb->transfer_buffer); |
| 292 | kfree(as->urb->setup_packet); | 301 | kfree(as->urb->setup_packet); |
| 293 | usb_free_urb(as->urb); | 302 | usb_free_urb(as->urb); |
| @@ -388,6 +397,53 @@ static void snoop_urb(struct usb_device *udev, | |||
| 388 | } | 397 | } |
| 389 | } | 398 | } |
| 390 | 399 | ||
| 400 | static void snoop_urb_data(struct urb *urb, unsigned len) | ||
| 401 | { | ||
| 402 | int i, size; | ||
| 403 | |||
| 404 | if (!usbfs_snoop) | ||
| 405 | return; | ||
| 406 | |||
| 407 | if (urb->num_sgs == 0) { | ||
| 408 | print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, | ||
| 409 | urb->transfer_buffer, len, 1); | ||
| 410 | return; | ||
| 411 | } | ||
| 412 | |||
| 413 | for (i = 0; i < urb->num_sgs && len; i++) { | ||
| 414 | size = (len > USB_SG_SIZE) ? USB_SG_SIZE : len; | ||
| 415 | print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, | ||
| 416 | sg_virt(&urb->sg[i]), size, 1); | ||
| 417 | len -= size; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | static int copy_urb_data_to_user(u8 __user *userbuffer, struct urb *urb) | ||
| 422 | { | ||
| 423 | unsigned i, len, size; | ||
| 424 | |||
| 425 | if (urb->number_of_packets > 0) /* Isochronous */ | ||
| 426 | len = urb->transfer_buffer_length; | ||
| 427 | else /* Non-Isoc */ | ||
| 428 | len = urb->actual_length; | ||
| 429 | |||
| 430 | if (urb->num_sgs == 0) { | ||
| 431 | if (copy_to_user(userbuffer, urb->transfer_buffer, len)) | ||
| 432 | return -EFAULT; | ||
| 433 | return 0; | ||
| 434 | } | ||
| 435 | |||
| 436 | for (i = 0; i < urb->num_sgs && len; i++) { | ||
| 437 | size = (len > USB_SG_SIZE) ? USB_SG_SIZE : len; | ||
| 438 | if (copy_to_user(userbuffer, sg_virt(&urb->sg[i]), size)) | ||
| 439 | return -EFAULT; | ||
| 440 | userbuffer += size; | ||
| 441 | len -= size; | ||
| 442 | } | ||
| 443 | |||
| 444 | return 0; | ||
| 445 | } | ||
| 446 | |||
| 391 | #define AS_CONTINUATION 1 | 447 | #define AS_CONTINUATION 1 |
| 392 | #define AS_UNLINK 2 | 448 | #define AS_UNLINK 2 |
| 393 | 449 | ||
| @@ -454,9 +510,10 @@ static void async_completed(struct urb *urb) | |||
| 454 | } | 510 | } |
| 455 | snoop(&urb->dev->dev, "urb complete\n"); | 511 | snoop(&urb->dev->dev, "urb complete\n"); |
| 456 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, | 512 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, |
| 457 | as->status, COMPLETE, | 513 | as->status, COMPLETE, NULL, 0); |
| 458 | ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_OUT) ? | 514 | if ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_IN) |
| 459 | NULL : urb->transfer_buffer, urb->actual_length); | 515 | snoop_urb_data(urb, urb->actual_length); |
| 516 | |||
| 460 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && | 517 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && |
| 461 | as->status != -ENOENT) | 518 | as->status != -ENOENT) |
| 462 | cancel_bulk_urbs(ps, as->bulk_addr); | 519 | cancel_bulk_urbs(ps, as->bulk_addr); |
| @@ -1114,8 +1171,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1114 | struct async *as = NULL; | 1171 | struct async *as = NULL; |
| 1115 | struct usb_ctrlrequest *dr = NULL; | 1172 | struct usb_ctrlrequest *dr = NULL; |
| 1116 | unsigned int u, totlen, isofrmlen; | 1173 | unsigned int u, totlen, isofrmlen; |
| 1117 | int ret, ifnum = -1; | 1174 | int i, ret, is_in, num_sgs = 0, ifnum = -1; |
| 1118 | int is_in; | 1175 | void *buf; |
| 1119 | 1176 | ||
| 1120 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | | 1177 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | |
| 1121 | USBDEVFS_URB_SHORT_NOT_OK | | 1178 | USBDEVFS_URB_SHORT_NOT_OK | |
| @@ -1199,6 +1256,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1199 | goto interrupt_urb; | 1256 | goto interrupt_urb; |
| 1200 | } | 1257 | } |
| 1201 | uurb->number_of_packets = 0; | 1258 | uurb->number_of_packets = 0; |
| 1259 | num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); | ||
| 1260 | if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize) | ||
| 1261 | num_sgs = 0; | ||
| 1202 | break; | 1262 | break; |
| 1203 | 1263 | ||
| 1204 | case USBDEVFS_URB_TYPE_INTERRUPT: | 1264 | case USBDEVFS_URB_TYPE_INTERRUPT: |
| @@ -1255,26 +1315,67 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1255 | ret = -ENOMEM; | 1315 | ret = -ENOMEM; |
| 1256 | goto error; | 1316 | goto error; |
| 1257 | } | 1317 | } |
| 1258 | u += sizeof(struct async) + sizeof(struct urb) + uurb->buffer_length; | 1318 | |
| 1319 | u += sizeof(struct async) + sizeof(struct urb) + uurb->buffer_length + | ||
| 1320 | num_sgs * sizeof(struct scatterlist); | ||
| 1259 | ret = usbfs_increase_memory_usage(u); | 1321 | ret = usbfs_increase_memory_usage(u); |
| 1260 | if (ret) | 1322 | if (ret) |
| 1261 | goto error; | 1323 | goto error; |
| 1262 | as->mem_usage = u; | 1324 | as->mem_usage = u; |
| 1263 | 1325 | ||
| 1264 | if (uurb->buffer_length > 0) { | 1326 | if (num_sgs) { |
| 1327 | as->urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist), | ||
| 1328 | GFP_KERNEL); | ||
| 1329 | if (!as->urb->sg) { | ||
| 1330 | ret = -ENOMEM; | ||
| 1331 | goto error; | ||
| 1332 | } | ||
| 1333 | as->urb->num_sgs = num_sgs; | ||
| 1334 | sg_init_table(as->urb->sg, as->urb->num_sgs); | ||
| 1335 | |||
| 1336 | totlen = uurb->buffer_length; | ||
| 1337 | for (i = 0; i < as->urb->num_sgs; i++) { | ||
| 1338 | u = (totlen > USB_SG_SIZE) ? USB_SG_SIZE : totlen; | ||
| 1339 | buf = kmalloc(u, GFP_KERNEL); | ||
| 1340 | if (!buf) { | ||
| 1341 | ret = -ENOMEM; | ||
| 1342 | goto error; | ||
| 1343 | } | ||
| 1344 | sg_set_buf(&as->urb->sg[i], buf, u); | ||
| 1345 | |||
| 1346 | if (!is_in) { | ||
| 1347 | if (copy_from_user(buf, uurb->buffer, u)) { | ||
| 1348 | ret = -EFAULT; | ||
| 1349 | goto error; | ||
| 1350 | } | ||
| 1351 | } | ||
| 1352 | totlen -= u; | ||
| 1353 | } | ||
| 1354 | } else if (uurb->buffer_length > 0) { | ||
| 1265 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, | 1355 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, |
| 1266 | GFP_KERNEL); | 1356 | GFP_KERNEL); |
| 1267 | if (!as->urb->transfer_buffer) { | 1357 | if (!as->urb->transfer_buffer) { |
| 1268 | ret = -ENOMEM; | 1358 | ret = -ENOMEM; |
| 1269 | goto error; | 1359 | goto error; |
| 1270 | } | 1360 | } |
| 1271 | /* Isochronous input data may end up being discontiguous | 1361 | |
| 1272 | * if some of the packets are short. Clear the buffer so | 1362 | if (!is_in) { |
| 1273 | * that the gaps don't leak kernel data to userspace. | 1363 | if (copy_from_user(as->urb->transfer_buffer, |
| 1274 | */ | 1364 | uurb->buffer, |
| 1275 | if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) | 1365 | uurb->buffer_length)) { |
| 1366 | ret = -EFAULT; | ||
| 1367 | goto error; | ||
| 1368 | } | ||
| 1369 | } else if (uurb->type == USBDEVFS_URB_TYPE_ISO) { | ||
| 1370 | /* | ||
| 1371 | * Isochronous input data may end up being | ||
| 1372 | * discontiguous if some of the packets are short. | ||
| 1373 | * Clear the buffer so that the gaps don't leak | ||
| 1374 | * kernel data to userspace. | ||
| 1375 | */ | ||
| 1276 | memset(as->urb->transfer_buffer, 0, | 1376 | memset(as->urb->transfer_buffer, 0, |
| 1277 | uurb->buffer_length); | 1377 | uurb->buffer_length); |
| 1378 | } | ||
| 1278 | } | 1379 | } |
| 1279 | as->urb->dev = ps->dev; | 1380 | as->urb->dev = ps->dev; |
| 1280 | as->urb->pipe = (uurb->type << 30) | | 1381 | as->urb->pipe = (uurb->type << 30) | |
| @@ -1328,17 +1429,12 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1328 | as->pid = get_pid(task_pid(current)); | 1429 | as->pid = get_pid(task_pid(current)); |
| 1329 | as->cred = get_current_cred(); | 1430 | as->cred = get_current_cred(); |
| 1330 | security_task_getsecid(current, &as->secid); | 1431 | security_task_getsecid(current, &as->secid); |
| 1331 | if (!is_in && uurb->buffer_length > 0) { | ||
| 1332 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, | ||
| 1333 | uurb->buffer_length)) { | ||
| 1334 | ret = -EFAULT; | ||
| 1335 | goto error; | ||
| 1336 | } | ||
| 1337 | } | ||
| 1338 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, | 1432 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, |
| 1339 | as->urb->transfer_buffer_length, 0, SUBMIT, | 1433 | as->urb->transfer_buffer_length, 0, SUBMIT, |
| 1340 | is_in ? NULL : as->urb->transfer_buffer, | 1434 | NULL, 0); |
| 1341 | uurb->buffer_length); | 1435 | if (!is_in) |
| 1436 | snoop_urb_data(as->urb, as->urb->transfer_buffer_length); | ||
| 1437 | |||
| 1342 | async_newpending(as); | 1438 | async_newpending(as); |
| 1343 | 1439 | ||
| 1344 | if (usb_endpoint_xfer_bulk(&ep->desc)) { | 1440 | if (usb_endpoint_xfer_bulk(&ep->desc)) { |
| @@ -1433,11 +1529,7 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
| 1433 | unsigned int i; | 1529 | unsigned int i; |
| 1434 | 1530 | ||
| 1435 | if (as->userbuffer && urb->actual_length) { | 1531 | if (as->userbuffer && urb->actual_length) { |
| 1436 | if (urb->number_of_packets > 0) /* Isochronous */ | 1532 | if (copy_urb_data_to_user(as->userbuffer, urb)) |
| 1437 | i = urb->transfer_buffer_length; | ||
| 1438 | else /* Non-Isoc */ | ||
| 1439 | i = urb->actual_length; | ||
| 1440 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) | ||
| 1441 | goto err_out; | 1533 | goto err_out; |
| 1442 | } | 1534 | } |
| 1443 | if (put_user(as->status, &userurb->status)) | 1535 | if (put_user(as->status, &userurb->status)) |
| @@ -1604,10 +1696,10 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
| 1604 | void __user *addr = as->userurb; | 1696 | void __user *addr = as->userurb; |
| 1605 | unsigned int i; | 1697 | unsigned int i; |
| 1606 | 1698 | ||
| 1607 | if (as->userbuffer && urb->actual_length) | 1699 | if (as->userbuffer && urb->actual_length) { |
| 1608 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1700 | if (copy_urb_data_to_user(as->userbuffer, urb)) |
| 1609 | urb->actual_length)) | ||
| 1610 | return -EFAULT; | 1701 | return -EFAULT; |
| 1702 | } | ||
| 1611 | if (put_user(as->status, &userurb->status)) | 1703 | if (put_user(as->status, &userurb->status)) |
| 1612 | return -EFAULT; | 1704 | return -EFAULT; |
| 1613 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1705 | if (put_user(urb->actual_length, &userurb->actual_length)) |
| @@ -1820,6 +1912,22 @@ static int proc_release_port(struct dev_state *ps, void __user *arg) | |||
| 1820 | return usb_hub_release_port(ps->dev, portnum, ps); | 1912 | return usb_hub_release_port(ps->dev, portnum, ps); |
| 1821 | } | 1913 | } |
| 1822 | 1914 | ||
| 1915 | static int proc_get_capabilities(struct dev_state *ps, void __user *arg) | ||
| 1916 | { | ||
| 1917 | __u32 caps; | ||
| 1918 | |||
| 1919 | caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM; | ||
| 1920 | if (!ps->dev->bus->no_stop_on_short) | ||
| 1921 | caps |= USBDEVFS_CAP_BULK_CONTINUATION; | ||
| 1922 | if (ps->dev->bus->sg_tablesize) | ||
| 1923 | caps |= USBDEVFS_CAP_BULK_SCATTER_GATHER; | ||
| 1924 | |||
| 1925 | if (put_user(caps, (__u32 __user *)arg)) | ||
| 1926 | return -EFAULT; | ||
| 1927 | |||
| 1928 | return 0; | ||
| 1929 | } | ||
| 1930 | |||
| 1823 | /* | 1931 | /* |
| 1824 | * NOTE: All requests here that have interface numbers as parameters | 1932 | * NOTE: All requests here that have interface numbers as parameters |
| 1825 | * are assuming that somehow the configuration has been prevented from | 1933 | * are assuming that somehow the configuration has been prevented from |
| @@ -1990,6 +2098,9 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 1990 | snoop(&dev->dev, "%s: RELEASE_PORT\n", __func__); | 2098 | snoop(&dev->dev, "%s: RELEASE_PORT\n", __func__); |
| 1991 | ret = proc_release_port(ps, p); | 2099 | ret = proc_release_port(ps, p); |
| 1992 | break; | 2100 | break; |
| 2101 | case USBDEVFS_GET_CAPABILITIES: | ||
| 2102 | ret = proc_get_capabilities(ps, p); | ||
| 2103 | break; | ||
| 1993 | } | 2104 | } |
| 1994 | usb_unlock_device(dev); | 2105 | usb_unlock_device(dev); |
| 1995 | if (ret >= 0) | 2106 | if (ret >= 0) |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f536aebc958e..445455a4429b 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -367,6 +367,7 @@ static int usb_probe_interface(struct device *dev) | |||
| 367 | return error; | 367 | return error; |
| 368 | 368 | ||
| 369 | err: | 369 | err: |
| 370 | usb_set_intfdata(intf, NULL); | ||
| 370 | intf->needs_remote_wakeup = 0; | 371 | intf->needs_remote_wakeup = 0; |
| 371 | intf->condition = USB_INTERFACE_UNBOUND; | 372 | intf->condition = USB_INTERFACE_UNBOUND; |
| 372 | usb_cancel_queued_reset(intf); | 373 | usb_cancel_queued_reset(intf); |
| @@ -606,30 +607,19 @@ int usb_match_device(struct usb_device *dev, const struct usb_device_id *id) | |||
| 606 | } | 607 | } |
| 607 | 608 | ||
| 608 | /* returns 0 if no match, 1 if match */ | 609 | /* returns 0 if no match, 1 if match */ |
| 609 | int usb_match_one_id(struct usb_interface *interface, | 610 | int usb_match_one_id_intf(struct usb_device *dev, |
| 610 | const struct usb_device_id *id) | 611 | struct usb_host_interface *intf, |
| 612 | const struct usb_device_id *id) | ||
| 611 | { | 613 | { |
| 612 | struct usb_host_interface *intf; | 614 | /* The interface class, subclass, protocol and number should never be |
| 613 | struct usb_device *dev; | ||
| 614 | |||
| 615 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
| 616 | if (id == NULL) | ||
| 617 | return 0; | ||
| 618 | |||
| 619 | intf = interface->cur_altsetting; | ||
| 620 | dev = interface_to_usbdev(interface); | ||
| 621 | |||
| 622 | if (!usb_match_device(dev, id)) | ||
| 623 | return 0; | ||
| 624 | |||
| 625 | /* The interface class, subclass, and protocol should never be | ||
| 626 | * checked for a match if the device class is Vendor Specific, | 615 | * checked for a match if the device class is Vendor Specific, |
| 627 | * unless the match record specifies the Vendor ID. */ | 616 | * unless the match record specifies the Vendor ID. */ |
| 628 | if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && | 617 | if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && |
| 629 | !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | 618 | !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && |
| 630 | (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | | 619 | (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | |
| 631 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | | 620 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | |
| 632 | USB_DEVICE_ID_MATCH_INT_PROTOCOL))) | 621 | USB_DEVICE_ID_MATCH_INT_PROTOCOL | |
| 622 | USB_DEVICE_ID_MATCH_INT_NUMBER))) | ||
| 633 | return 0; | 623 | return 0; |
| 634 | 624 | ||
| 635 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | 625 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && |
| @@ -644,8 +634,32 @@ int usb_match_one_id(struct usb_interface *interface, | |||
| 644 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | 634 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) |
| 645 | return 0; | 635 | return 0; |
| 646 | 636 | ||
| 637 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) && | ||
| 638 | (id->bInterfaceNumber != intf->desc.bInterfaceNumber)) | ||
| 639 | return 0; | ||
| 640 | |||
| 647 | return 1; | 641 | return 1; |
| 648 | } | 642 | } |
| 643 | |||
| 644 | /* returns 0 if no match, 1 if match */ | ||
| 645 | int usb_match_one_id(struct usb_interface *interface, | ||
| 646 | const struct usb_device_id *id) | ||
| 647 | { | ||
| 648 | struct usb_host_interface *intf; | ||
| 649 | struct usb_device *dev; | ||
| 650 | |||
| 651 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
| 652 | if (id == NULL) | ||
| 653 | return 0; | ||
| 654 | |||
| 655 | intf = interface->cur_altsetting; | ||
| 656 | dev = interface_to_usbdev(interface); | ||
| 657 | |||
| 658 | if (!usb_match_device(dev, id)) | ||
| 659 | return 0; | ||
| 660 | |||
| 661 | return usb_match_one_id_intf(dev, intf, id); | ||
| 662 | } | ||
| 649 | EXPORT_SYMBOL_GPL(usb_match_one_id); | 663 | EXPORT_SYMBOL_GPL(usb_match_one_id); |
| 650 | 664 | ||
| 651 | /** | 665 | /** |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index e673b26e598f..e5387a47ef6f 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
| @@ -92,7 +92,7 @@ static int init_usb_class(void) | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | kref_init(&usb_class->kref); | 94 | kref_init(&usb_class->kref); |
| 95 | usb_class->class = class_create(THIS_MODULE, "usb"); | 95 | usb_class->class = class_create(THIS_MODULE, "usbmisc"); |
| 96 | if (IS_ERR(usb_class->class)) { | 96 | if (IS_ERR(usb_class->class)) { |
| 97 | result = IS_ERR(usb_class->class); | 97 | result = IS_ERR(usb_class->class); |
| 98 | printk(KERN_ERR "class_create failed for usb devices\n"); | 98 | printk(KERN_ERR "class_create failed for usb devices\n"); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 190b1ec7bdcb..bc84106ac057 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -1398,7 +1398,15 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
| 1398 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { | 1398 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { |
| 1399 | if (hcd->self.uses_dma) { | 1399 | if (hcd->self.uses_dma) { |
| 1400 | if (urb->num_sgs) { | 1400 | if (urb->num_sgs) { |
| 1401 | int n = dma_map_sg( | 1401 | int n; |
| 1402 | |||
| 1403 | /* We don't support sg for isoc transfers ! */ | ||
| 1404 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { | ||
| 1405 | WARN_ON(1); | ||
| 1406 | return -EINVAL; | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | n = dma_map_sg( | ||
| 1402 | hcd->self.controller, | 1410 | hcd->self.controller, |
| 1403 | urb->sg, | 1411 | urb->sg, |
| 1404 | urb->num_sgs, | 1412 | urb->num_sgs, |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8fb484984c86..821126eb8176 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
| 21 | #include <linux/usbdevice_fs.h> | 21 | #include <linux/usbdevice_fs.h> |
| 22 | #include <linux/usb/hcd.h> | 22 | #include <linux/usb/hcd.h> |
| 23 | #include <linux/usb/otg.h> | ||
| 23 | #include <linux/usb/quirks.h> | 24 | #include <linux/usb/quirks.h> |
| 24 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
| 25 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
| @@ -81,7 +82,7 @@ struct usb_hub { | |||
| 81 | u8 indicator[USB_MAXCHILDREN]; | 82 | u8 indicator[USB_MAXCHILDREN]; |
| 82 | struct delayed_work leds; | 83 | struct delayed_work leds; |
| 83 | struct delayed_work init_work; | 84 | struct delayed_work init_work; |
| 84 | void **port_owners; | 85 | struct dev_state **port_owners; |
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| 87 | static inline int hub_is_superspeed(struct usb_device *hdev) | 88 | static inline int hub_is_superspeed(struct usb_device *hdev) |
| @@ -1271,7 +1272,8 @@ static int hub_configure(struct usb_hub *hub, | |||
| 1271 | 1272 | ||
| 1272 | hdev->children = kzalloc(hdev->maxchild * | 1273 | hdev->children = kzalloc(hdev->maxchild * |
| 1273 | sizeof(struct usb_device *), GFP_KERNEL); | 1274 | sizeof(struct usb_device *), GFP_KERNEL); |
| 1274 | hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL); | 1275 | hub->port_owners = kzalloc(hdev->maxchild * sizeof(struct dev_state *), |
| 1276 | GFP_KERNEL); | ||
| 1275 | if (!hdev->children || !hub->port_owners) { | 1277 | if (!hdev->children || !hub->port_owners) { |
| 1276 | ret = -ENOMEM; | 1278 | ret = -ENOMEM; |
| 1277 | goto fail; | 1279 | goto fail; |
| @@ -1649,7 +1651,7 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) | |||
| 1649 | * to one of these "claimed" ports, the program will "own" the device. | 1651 | * to one of these "claimed" ports, the program will "own" the device. |
| 1650 | */ | 1652 | */ |
| 1651 | static int find_port_owner(struct usb_device *hdev, unsigned port1, | 1653 | static int find_port_owner(struct usb_device *hdev, unsigned port1, |
| 1652 | void ***ppowner) | 1654 | struct dev_state ***ppowner) |
| 1653 | { | 1655 | { |
| 1654 | if (hdev->state == USB_STATE_NOTATTACHED) | 1656 | if (hdev->state == USB_STATE_NOTATTACHED) |
| 1655 | return -ENODEV; | 1657 | return -ENODEV; |
| @@ -1664,10 +1666,11 @@ static int find_port_owner(struct usb_device *hdev, unsigned port1, | |||
| 1664 | } | 1666 | } |
| 1665 | 1667 | ||
| 1666 | /* In the following three functions, the caller must hold hdev's lock */ | 1668 | /* In the following three functions, the caller must hold hdev's lock */ |
| 1667 | int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner) | 1669 | int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, |
| 1670 | struct dev_state *owner) | ||
| 1668 | { | 1671 | { |
| 1669 | int rc; | 1672 | int rc; |
| 1670 | void **powner; | 1673 | struct dev_state **powner; |
| 1671 | 1674 | ||
| 1672 | rc = find_port_owner(hdev, port1, &powner); | 1675 | rc = find_port_owner(hdev, port1, &powner); |
| 1673 | if (rc) | 1676 | if (rc) |
| @@ -1678,10 +1681,11 @@ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner) | |||
| 1678 | return rc; | 1681 | return rc; |
| 1679 | } | 1682 | } |
| 1680 | 1683 | ||
| 1681 | int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner) | 1684 | int usb_hub_release_port(struct usb_device *hdev, unsigned port1, |
| 1685 | struct dev_state *owner) | ||
| 1682 | { | 1686 | { |
| 1683 | int rc; | 1687 | int rc; |
| 1684 | void **powner; | 1688 | struct dev_state **powner; |
| 1685 | 1689 | ||
| 1686 | rc = find_port_owner(hdev, port1, &powner); | 1690 | rc = find_port_owner(hdev, port1, &powner); |
| 1687 | if (rc) | 1691 | if (rc) |
| @@ -1692,10 +1696,10 @@ int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner) | |||
| 1692 | return rc; | 1696 | return rc; |
| 1693 | } | 1697 | } |
| 1694 | 1698 | ||
| 1695 | void usb_hub_release_all_ports(struct usb_device *hdev, void *owner) | 1699 | void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner) |
| 1696 | { | 1700 | { |
| 1697 | int n; | 1701 | int n; |
| 1698 | void **powner; | 1702 | struct dev_state **powner; |
| 1699 | 1703 | ||
| 1700 | n = find_port_owner(hdev, 1, &powner); | 1704 | n = find_port_owner(hdev, 1, &powner); |
| 1701 | if (n == 0) { | 1705 | if (n == 0) { |
| @@ -2065,7 +2069,7 @@ static int usb_enumerate_device(struct usb_device *udev) | |||
| 2065 | if (err < 0) { | 2069 | if (err < 0) { |
| 2066 | dev_err(&udev->dev, "can't read configurations, error %d\n", | 2070 | dev_err(&udev->dev, "can't read configurations, error %d\n", |
| 2067 | err); | 2071 | err); |
| 2068 | goto fail; | 2072 | return err; |
| 2069 | } | 2073 | } |
| 2070 | } | 2074 | } |
| 2071 | if (udev->wusb == 1 && udev->authorized == 0) { | 2075 | if (udev->wusb == 1 && udev->authorized == 0) { |
| @@ -2081,8 +2085,12 @@ static int usb_enumerate_device(struct usb_device *udev) | |||
| 2081 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | 2085 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); |
| 2082 | } | 2086 | } |
| 2083 | err = usb_enumerate_device_otg(udev); | 2087 | err = usb_enumerate_device_otg(udev); |
| 2084 | fail: | 2088 | if (err < 0) |
| 2085 | return err; | 2089 | return err; |
| 2090 | |||
| 2091 | usb_detect_interface_quirks(udev); | ||
| 2092 | |||
| 2093 | return 0; | ||
| 2086 | } | 2094 | } |
| 2087 | 2095 | ||
| 2088 | static void set_usb_port_removable(struct usb_device *udev) | 2096 | static void set_usb_port_removable(struct usb_device *udev) |
| @@ -2611,6 +2619,50 @@ static int check_port_resume_type(struct usb_device *udev, | |||
| 2611 | return status; | 2619 | return status; |
| 2612 | } | 2620 | } |
| 2613 | 2621 | ||
| 2622 | int usb_disable_ltm(struct usb_device *udev) | ||
| 2623 | { | ||
| 2624 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
| 2625 | |||
| 2626 | /* Check if the roothub and device supports LTM. */ | ||
| 2627 | if (!usb_device_supports_ltm(hcd->self.root_hub) || | ||
| 2628 | !usb_device_supports_ltm(udev)) | ||
| 2629 | return 0; | ||
| 2630 | |||
| 2631 | /* Clear Feature LTM Enable can only be sent if the device is | ||
| 2632 | * configured. | ||
| 2633 | */ | ||
| 2634 | if (!udev->actconfig) | ||
| 2635 | return 0; | ||
| 2636 | |||
| 2637 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
| 2638 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, | ||
| 2639 | USB_DEVICE_LTM_ENABLE, 0, NULL, 0, | ||
| 2640 | USB_CTRL_SET_TIMEOUT); | ||
| 2641 | } | ||
| 2642 | EXPORT_SYMBOL_GPL(usb_disable_ltm); | ||
| 2643 | |||
| 2644 | void usb_enable_ltm(struct usb_device *udev) | ||
| 2645 | { | ||
| 2646 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
| 2647 | |||
| 2648 | /* Check if the roothub and device supports LTM. */ | ||
| 2649 | if (!usb_device_supports_ltm(hcd->self.root_hub) || | ||
| 2650 | !usb_device_supports_ltm(udev)) | ||
| 2651 | return; | ||
| 2652 | |||
| 2653 | /* Set Feature LTM Enable can only be sent if the device is | ||
| 2654 | * configured. | ||
| 2655 | */ | ||
| 2656 | if (!udev->actconfig) | ||
| 2657 | return; | ||
| 2658 | |||
| 2659 | usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
| 2660 | USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, | ||
| 2661 | USB_DEVICE_LTM_ENABLE, 0, NULL, 0, | ||
| 2662 | USB_CTRL_SET_TIMEOUT); | ||
| 2663 | } | ||
| 2664 | EXPORT_SYMBOL_GPL(usb_enable_ltm); | ||
| 2665 | |||
| 2614 | #ifdef CONFIG_USB_SUSPEND | 2666 | #ifdef CONFIG_USB_SUSPEND |
| 2615 | 2667 | ||
| 2616 | /* | 2668 | /* |
| @@ -2706,6 +2758,11 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
| 2706 | if (udev->usb2_hw_lpm_enabled == 1) | 2758 | if (udev->usb2_hw_lpm_enabled == 1) |
| 2707 | usb_set_usb2_hardware_lpm(udev, 0); | 2759 | usb_set_usb2_hardware_lpm(udev, 0); |
| 2708 | 2760 | ||
| 2761 | if (usb_disable_ltm(udev)) { | ||
| 2762 | dev_err(&udev->dev, "%s Failed to disable LTM before suspend\n.", | ||
| 2763 | __func__); | ||
| 2764 | return -ENOMEM; | ||
| 2765 | } | ||
| 2709 | if (usb_unlocked_disable_lpm(udev)) { | 2766 | if (usb_unlocked_disable_lpm(udev)) { |
| 2710 | dev_err(&udev->dev, "%s Failed to disable LPM before suspend\n.", | 2767 | dev_err(&udev->dev, "%s Failed to disable LPM before suspend\n.", |
| 2711 | __func__); | 2768 | __func__); |
| @@ -2735,7 +2792,8 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
| 2735 | if (udev->usb2_hw_lpm_capable == 1) | 2792 | if (udev->usb2_hw_lpm_capable == 1) |
| 2736 | usb_set_usb2_hardware_lpm(udev, 1); | 2793 | usb_set_usb2_hardware_lpm(udev, 1); |
| 2737 | 2794 | ||
| 2738 | /* Try to enable USB3 LPM again */ | 2795 | /* Try to enable USB3 LTM and LPM again */ |
| 2796 | usb_enable_ltm(udev); | ||
| 2739 | usb_unlocked_enable_lpm(udev); | 2797 | usb_unlocked_enable_lpm(udev); |
| 2740 | 2798 | ||
| 2741 | /* System sleep transitions should never fail */ | 2799 | /* System sleep transitions should never fail */ |
| @@ -2936,7 +2994,8 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
| 2936 | if (udev->usb2_hw_lpm_capable == 1) | 2994 | if (udev->usb2_hw_lpm_capable == 1) |
| 2937 | usb_set_usb2_hardware_lpm(udev, 1); | 2995 | usb_set_usb2_hardware_lpm(udev, 1); |
| 2938 | 2996 | ||
| 2939 | /* Try to enable USB3 LPM */ | 2997 | /* Try to enable USB3 LTM and LPM */ |
| 2998 | usb_enable_ltm(udev); | ||
| 2940 | usb_unlocked_enable_lpm(udev); | 2999 | usb_unlocked_enable_lpm(udev); |
| 2941 | } | 3000 | } |
| 2942 | 3001 | ||
| @@ -3489,6 +3548,15 @@ EXPORT_SYMBOL_GPL(usb_unlocked_disable_lpm); | |||
| 3489 | 3548 | ||
| 3490 | void usb_unlocked_enable_lpm(struct usb_device *udev) { } | 3549 | void usb_unlocked_enable_lpm(struct usb_device *udev) { } |
| 3491 | EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm); | 3550 | EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm); |
| 3551 | |||
| 3552 | int usb_disable_ltm(struct usb_device *udev) | ||
| 3553 | { | ||
| 3554 | return 0; | ||
| 3555 | } | ||
| 3556 | EXPORT_SYMBOL_GPL(usb_disable_ltm); | ||
| 3557 | |||
| 3558 | void usb_enable_ltm(struct usb_device *udev) { } | ||
| 3559 | EXPORT_SYMBOL_GPL(usb_enable_ltm); | ||
| 3492 | #endif | 3560 | #endif |
| 3493 | 3561 | ||
| 3494 | 3562 | ||
| @@ -4038,6 +4106,13 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
| 4038 | } | 4106 | } |
| 4039 | } | 4107 | } |
| 4040 | 4108 | ||
| 4109 | if (hcd->phy && !hdev->parent) { | ||
| 4110 | if (portstatus & USB_PORT_STAT_CONNECTION) | ||
| 4111 | usb_phy_notify_connect(hcd->phy, port1); | ||
| 4112 | else | ||
| 4113 | usb_phy_notify_disconnect(hcd->phy, port1); | ||
| 4114 | } | ||
| 4115 | |||
| 4041 | /* Return now if debouncing failed or nothing is connected or | 4116 | /* Return now if debouncing failed or nothing is connected or |
| 4042 | * the device was "removed". | 4117 | * the device was "removed". |
| 4043 | */ | 4118 | */ |
| @@ -4672,6 +4747,23 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
| 4672 | } | 4747 | } |
| 4673 | parent_hub = hdev_to_hub(parent_hdev); | 4748 | parent_hub = hdev_to_hub(parent_hdev); |
| 4674 | 4749 | ||
| 4750 | /* Disable LPM and LTM while we reset the device and reinstall the alt | ||
| 4751 | * settings. Device-initiated LPM settings, and system exit latency | ||
| 4752 | * settings are cleared when the device is reset, so we have to set | ||
| 4753 | * them up again. | ||
| 4754 | */ | ||
| 4755 | ret = usb_unlocked_disable_lpm(udev); | ||
| 4756 | if (ret) { | ||
| 4757 | dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__); | ||
| 4758 | goto re_enumerate; | ||
| 4759 | } | ||
| 4760 | ret = usb_disable_ltm(udev); | ||
| 4761 | if (ret) { | ||
| 4762 | dev_err(&udev->dev, "%s Failed to disable LTM\n.", | ||
| 4763 | __func__); | ||
| 4764 | goto re_enumerate; | ||
| 4765 | } | ||
| 4766 | |||
| 4675 | set_bit(port1, parent_hub->busy_bits); | 4767 | set_bit(port1, parent_hub->busy_bits); |
| 4676 | for (i = 0; i < SET_CONFIG_TRIES; ++i) { | 4768 | for (i = 0; i < SET_CONFIG_TRIES; ++i) { |
| 4677 | 4769 | ||
| @@ -4699,22 +4791,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
| 4699 | goto done; | 4791 | goto done; |
| 4700 | 4792 | ||
| 4701 | mutex_lock(hcd->bandwidth_mutex); | 4793 | mutex_lock(hcd->bandwidth_mutex); |
| 4702 | /* Disable LPM while we reset the device and reinstall the alt settings. | ||
| 4703 | * Device-initiated LPM settings, and system exit latency settings are | ||
| 4704 | * cleared when the device is reset, so we have to set them up again. | ||
| 4705 | */ | ||
| 4706 | ret = usb_disable_lpm(udev); | ||
| 4707 | if (ret) { | ||
| 4708 | dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__); | ||
| 4709 | mutex_unlock(hcd->bandwidth_mutex); | ||
| 4710 | goto done; | ||
| 4711 | } | ||
| 4712 | ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); | 4794 | ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); |
| 4713 | if (ret < 0) { | 4795 | if (ret < 0) { |
| 4714 | dev_warn(&udev->dev, | 4796 | dev_warn(&udev->dev, |
| 4715 | "Busted HC? Not enough HCD resources for " | 4797 | "Busted HC? Not enough HCD resources for " |
| 4716 | "old configuration.\n"); | 4798 | "old configuration.\n"); |
| 4717 | usb_enable_lpm(udev); | ||
| 4718 | mutex_unlock(hcd->bandwidth_mutex); | 4799 | mutex_unlock(hcd->bandwidth_mutex); |
| 4719 | goto re_enumerate; | 4800 | goto re_enumerate; |
| 4720 | } | 4801 | } |
| @@ -4726,7 +4807,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
| 4726 | dev_err(&udev->dev, | 4807 | dev_err(&udev->dev, |
| 4727 | "can't restore configuration #%d (error=%d)\n", | 4808 | "can't restore configuration #%d (error=%d)\n", |
| 4728 | udev->actconfig->desc.bConfigurationValue, ret); | 4809 | udev->actconfig->desc.bConfigurationValue, ret); |
| 4729 | usb_enable_lpm(udev); | ||
| 4730 | mutex_unlock(hcd->bandwidth_mutex); | 4810 | mutex_unlock(hcd->bandwidth_mutex); |
| 4731 | goto re_enumerate; | 4811 | goto re_enumerate; |
| 4732 | } | 4812 | } |
| @@ -4765,17 +4845,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
| 4765 | desc->bInterfaceNumber, | 4845 | desc->bInterfaceNumber, |
| 4766 | desc->bAlternateSetting, | 4846 | desc->bAlternateSetting, |
| 4767 | ret); | 4847 | ret); |
| 4768 | usb_unlocked_enable_lpm(udev); | ||
| 4769 | goto re_enumerate; | 4848 | goto re_enumerate; |
| 4770 | } | 4849 | } |
| 4771 | } | 4850 | } |
| 4772 | 4851 | ||
| 4773 | /* Now that the alt settings are re-installed, enable LPM. */ | ||
| 4774 | usb_unlocked_enable_lpm(udev); | ||
| 4775 | done: | 4852 | done: |
| 4853 | /* Now that the alt settings are re-installed, enable LTM and LPM. */ | ||
| 4854 | usb_unlocked_enable_lpm(udev); | ||
| 4855 | usb_enable_ltm(udev); | ||
| 4776 | return 0; | 4856 | return 0; |
| 4777 | 4857 | ||
| 4778 | re_enumerate: | 4858 | re_enumerate: |
| 4859 | /* LPM state doesn't matter when we're about to destroy the device. */ | ||
| 4779 | hub_port_logical_disconnect(parent_hub, port1); | 4860 | hub_port_logical_disconnect(parent_hub, port1); |
| 4780 | return -ENODEV; | 4861 | return -ENODEV; |
| 4781 | } | 4862 | } |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index bdd1c6749d88..0ab7da2283e3 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -1174,6 +1174,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
| 1174 | put_device(&dev->actconfig->interface[i]->dev); | 1174 | put_device(&dev->actconfig->interface[i]->dev); |
| 1175 | dev->actconfig->interface[i] = NULL; | 1175 | dev->actconfig->interface[i] = NULL; |
| 1176 | } | 1176 | } |
| 1177 | usb_unlocked_disable_lpm(dev); | ||
| 1178 | usb_disable_ltm(dev); | ||
| 1177 | dev->actconfig = NULL; | 1179 | dev->actconfig = NULL; |
| 1178 | if (dev->state == USB_STATE_CONFIGURED) | 1180 | if (dev->state == USB_STATE_CONFIGURED) |
| 1179 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1181 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
| @@ -1559,7 +1561,7 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 1559 | 1561 | ||
| 1560 | if (add_uevent_var(env, | 1562 | if (add_uevent_var(env, |
| 1561 | "MODALIAS=usb:" | 1563 | "MODALIAS=usb:" |
| 1562 | "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | 1564 | "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X", |
| 1563 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1565 | le16_to_cpu(usb_dev->descriptor.idVendor), |
| 1564 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1566 | le16_to_cpu(usb_dev->descriptor.idProduct), |
| 1565 | le16_to_cpu(usb_dev->descriptor.bcdDevice), | 1567 | le16_to_cpu(usb_dev->descriptor.bcdDevice), |
| @@ -1568,7 +1570,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 1568 | usb_dev->descriptor.bDeviceProtocol, | 1570 | usb_dev->descriptor.bDeviceProtocol, |
| 1569 | alt->desc.bInterfaceClass, | 1571 | alt->desc.bInterfaceClass, |
| 1570 | alt->desc.bInterfaceSubClass, | 1572 | alt->desc.bInterfaceSubClass, |
| 1571 | alt->desc.bInterfaceProtocol)) | 1573 | alt->desc.bInterfaceProtocol, |
| 1574 | alt->desc.bInterfaceNumber)) | ||
| 1572 | return -ENOMEM; | 1575 | return -ENOMEM; |
| 1573 | 1576 | ||
| 1574 | return 0; | 1577 | return 0; |
| @@ -1791,14 +1794,15 @@ free_interfaces: | |||
| 1791 | * installed, so that the xHCI driver can recalculate the U1/U2 | 1794 | * installed, so that the xHCI driver can recalculate the U1/U2 |
| 1792 | * timeouts. | 1795 | * timeouts. |
| 1793 | */ | 1796 | */ |
| 1794 | if (usb_disable_lpm(dev)) { | 1797 | if (dev->actconfig && usb_disable_lpm(dev)) { |
| 1795 | dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__); | 1798 | dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__); |
| 1796 | mutex_unlock(hcd->bandwidth_mutex); | 1799 | mutex_unlock(hcd->bandwidth_mutex); |
| 1797 | return -ENOMEM; | 1800 | return -ENOMEM; |
| 1798 | } | 1801 | } |
| 1799 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); | 1802 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); |
| 1800 | if (ret < 0) { | 1803 | if (ret < 0) { |
| 1801 | usb_enable_lpm(dev); | 1804 | if (dev->actconfig) |
| 1805 | usb_enable_lpm(dev); | ||
| 1802 | mutex_unlock(hcd->bandwidth_mutex); | 1806 | mutex_unlock(hcd->bandwidth_mutex); |
| 1803 | usb_autosuspend_device(dev); | 1807 | usb_autosuspend_device(dev); |
| 1804 | goto free_interfaces; | 1808 | goto free_interfaces; |
| @@ -1818,7 +1822,7 @@ free_interfaces: | |||
| 1818 | if (!cp) { | 1822 | if (!cp) { |
| 1819 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1823 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
| 1820 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); | 1824 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); |
| 1821 | usb_enable_lpm(dev); | 1825 | /* Leave LPM disabled while the device is unconfigured. */ |
| 1822 | mutex_unlock(hcd->bandwidth_mutex); | 1826 | mutex_unlock(hcd->bandwidth_mutex); |
| 1823 | usb_autosuspend_device(dev); | 1827 | usb_autosuspend_device(dev); |
| 1824 | goto free_interfaces; | 1828 | goto free_interfaces; |
| @@ -1876,6 +1880,8 @@ free_interfaces: | |||
| 1876 | 1880 | ||
| 1877 | /* Now that the interfaces are installed, re-enable LPM. */ | 1881 | /* Now that the interfaces are installed, re-enable LPM. */ |
| 1878 | usb_unlocked_enable_lpm(dev); | 1882 | usb_unlocked_enable_lpm(dev); |
| 1883 | /* Enable LTM if it was turned off by usb_disable_device. */ | ||
| 1884 | usb_enable_ltm(dev); | ||
| 1879 | 1885 | ||
| 1880 | /* Now that all the interfaces are set up, register them | 1886 | /* Now that all the interfaces are set up, register them |
| 1881 | * to trigger binding of drivers to interfaces. probe() | 1887 | * to trigger binding of drivers to interfaces. probe() |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 32d3adc315f5..f15501f4c585 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -15,17 +15,22 @@ | |||
| 15 | #include <linux/usb/quirks.h> | 15 | #include <linux/usb/quirks.h> |
| 16 | #include "usb.h" | 16 | #include "usb.h" |
| 17 | 17 | ||
| 18 | /* List of quirky USB devices. Please keep this list ordered by: | 18 | /* Lists of quirky USB devices, split in device quirks and interface quirks. |
| 19 | * Device quirks are applied at the very beginning of the enumeration process, | ||
| 20 | * right after reading the device descriptor. They can thus only match on device | ||
| 21 | * information. | ||
| 22 | * | ||
| 23 | * Interface quirks are applied after reading all the configuration descriptors. | ||
| 24 | * They can match on both device and interface information. | ||
| 25 | * | ||
| 26 | * Note that the DELAY_INIT and HONOR_BNUMINTERFACES quirks do not make sense as | ||
| 27 | * interface quirks, as they only influence the enumeration process which is run | ||
| 28 | * before processing the interface quirks. | ||
| 29 | * | ||
| 30 | * Please keep the lists ordered by: | ||
| 19 | * 1) Vendor ID | 31 | * 1) Vendor ID |
| 20 | * 2) Product ID | 32 | * 2) Product ID |
| 21 | * 3) Class ID | 33 | * 3) Class ID |
| 22 | * | ||
| 23 | * as we want specific devices to be overridden first, and only after that, any | ||
| 24 | * class specific quirks. | ||
| 25 | * | ||
| 26 | * Right now the logic aborts if it finds a valid device in the table, we might | ||
| 27 | * want to change that in the future if it turns out that a whole class of | ||
| 28 | * devices is broken... | ||
| 29 | */ | 34 | */ |
| 30 | static const struct usb_device_id usb_quirk_list[] = { | 35 | static const struct usb_device_id usb_quirk_list[] = { |
| 31 | /* CBM - Flash disk */ | 36 | /* CBM - Flash disk */ |
| @@ -38,53 +43,23 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 38 | /* Creative SB Audigy 2 NX */ | 43 | /* Creative SB Audigy 2 NX */ |
| 39 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, | 44 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 40 | 45 | ||
| 41 | /* Logitech Webcam C200 */ | 46 | /* Logitech Quickcam Fusion */ |
| 42 | { USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME }, | 47 | { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 43 | |||
| 44 | /* Logitech Webcam C250 */ | ||
| 45 | { USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 46 | |||
| 47 | /* Logitech Webcam C300 */ | ||
| 48 | { USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 49 | |||
| 50 | /* Logitech Webcam B/C500 */ | ||
| 51 | { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 52 | |||
| 53 | /* Logitech Webcam C600 */ | ||
| 54 | { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 55 | |||
| 56 | /* Logitech Webcam Pro 9000 */ | ||
| 57 | { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 58 | 48 | ||
| 59 | /* Logitech Webcam C905 */ | 49 | /* Logitech Quickcam Orbit MP */ |
| 60 | { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, | 50 | { USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 61 | 51 | ||
| 62 | /* Logitech Webcam C210 */ | 52 | /* Logitech Quickcam Pro for Notebook */ |
| 63 | { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, | 53 | { USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 64 | 54 | ||
| 65 | /* Logitech Webcam C260 */ | 55 | /* Logitech Quickcam Pro 5000 */ |
| 66 | { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, | 56 | { USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 67 | 57 | ||
| 68 | /* Logitech Webcam C310 */ | 58 | /* Logitech Quickcam OEM Dell Notebook */ |
| 69 | { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, | 59 | { USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 70 | 60 | ||
| 71 | /* Logitech Webcam C910 */ | 61 | /* Logitech Quickcam OEM Cisco VT Camera II */ |
| 72 | { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, | 62 | { USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 73 | |||
| 74 | /* Logitech Webcam C160 */ | ||
| 75 | { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 76 | |||
| 77 | /* Logitech Webcam C270 */ | ||
| 78 | { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 79 | |||
| 80 | /* Logitech Quickcam Pro 9000 */ | ||
| 81 | { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 82 | |||
| 83 | /* Logitech Quickcam E3500 */ | ||
| 84 | { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 85 | |||
| 86 | /* Logitech Quickcam Vision Pro */ | ||
| 87 | { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 88 | 63 | ||
| 89 | /* Logitech Harmony 700-series */ | 64 | /* Logitech Harmony 700-series */ |
| 90 | { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, | 65 | { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, |
| @@ -156,16 +131,57 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 156 | { } /* terminating entry must be last */ | 131 | { } /* terminating entry must be last */ |
| 157 | }; | 132 | }; |
| 158 | 133 | ||
| 159 | static const struct usb_device_id *find_id(struct usb_device *udev) | 134 | static const struct usb_device_id usb_interface_quirk_list[] = { |
| 135 | /* Logitech UVC Cameras */ | ||
| 136 | { USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0), | ||
| 137 | .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 138 | |||
| 139 | { } /* terminating entry must be last */ | ||
| 140 | }; | ||
| 141 | |||
| 142 | static bool usb_match_any_interface(struct usb_device *udev, | ||
| 143 | const struct usb_device_id *id) | ||
| 160 | { | 144 | { |
| 161 | const struct usb_device_id *id = usb_quirk_list; | 145 | unsigned int i; |
| 162 | 146 | ||
| 163 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | 147 | for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) { |
| 164 | id->driver_info; id++) { | 148 | struct usb_host_config *cfg = &udev->config[i]; |
| 165 | if (usb_match_device(udev, id)) | 149 | unsigned int j; |
| 166 | return id; | 150 | |
| 151 | for (j = 0; j < cfg->desc.bNumInterfaces; ++j) { | ||
| 152 | struct usb_interface_cache *cache; | ||
| 153 | struct usb_host_interface *intf; | ||
| 154 | |||
| 155 | cache = cfg->intf_cache[j]; | ||
| 156 | if (cache->num_altsetting == 0) | ||
| 157 | continue; | ||
| 158 | |||
| 159 | intf = &cache->altsetting[0]; | ||
| 160 | if (usb_match_one_id_intf(udev, intf, id)) | ||
| 161 | return true; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | return false; | ||
| 166 | } | ||
| 167 | |||
| 168 | static u32 __usb_detect_quirks(struct usb_device *udev, | ||
| 169 | const struct usb_device_id *id) | ||
| 170 | { | ||
| 171 | u32 quirks = 0; | ||
| 172 | |||
| 173 | for (; id->match_flags; id++) { | ||
| 174 | if (!usb_match_device(udev, id)) | ||
| 175 | continue; | ||
| 176 | |||
| 177 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) && | ||
| 178 | !usb_match_any_interface(udev, id)) | ||
| 179 | continue; | ||
| 180 | |||
| 181 | quirks |= (u32)(id->driver_info); | ||
| 167 | } | 182 | } |
| 168 | return NULL; | 183 | |
| 184 | return quirks; | ||
| 169 | } | 185 | } |
| 170 | 186 | ||
| 171 | /* | 187 | /* |
| @@ -173,14 +189,10 @@ static const struct usb_device_id *find_id(struct usb_device *udev) | |||
| 173 | */ | 189 | */ |
| 174 | void usb_detect_quirks(struct usb_device *udev) | 190 | void usb_detect_quirks(struct usb_device *udev) |
| 175 | { | 191 | { |
| 176 | const struct usb_device_id *id = usb_quirk_list; | 192 | udev->quirks = __usb_detect_quirks(udev, usb_quirk_list); |
| 177 | |||
| 178 | id = find_id(udev); | ||
| 179 | if (id) | ||
| 180 | udev->quirks = (u32)(id->driver_info); | ||
| 181 | if (udev->quirks) | 193 | if (udev->quirks) |
| 182 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", | 194 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", |
| 183 | udev->quirks); | 195 | udev->quirks); |
| 184 | 196 | ||
| 185 | /* For the present, all devices default to USB-PERSIST enabled */ | 197 | /* For the present, all devices default to USB-PERSIST enabled */ |
| 186 | #if 0 /* was: #ifdef CONFIG_PM */ | 198 | #if 0 /* was: #ifdef CONFIG_PM */ |
| @@ -197,3 +209,16 @@ void usb_detect_quirks(struct usb_device *udev) | |||
| 197 | udev->persist_enabled = 1; | 209 | udev->persist_enabled = 1; |
| 198 | #endif /* CONFIG_PM */ | 210 | #endif /* CONFIG_PM */ |
| 199 | } | 211 | } |
| 212 | |||
| 213 | void usb_detect_interface_quirks(struct usb_device *udev) | ||
| 214 | { | ||
| 215 | u32 quirks; | ||
| 216 | |||
| 217 | quirks = __usb_detect_quirks(udev, usb_interface_quirk_list); | ||
| 218 | if (quirks == 0) | ||
| 219 | return; | ||
| 220 | |||
| 221 | dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n", | ||
| 222 | quirks); | ||
| 223 | udev->quirks |= quirks; | ||
| 224 | } | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 9a56e3adf476..682e8256b95d 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
| @@ -253,6 +253,15 @@ show_removable(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 253 | } | 253 | } |
| 254 | static DEVICE_ATTR(removable, S_IRUGO, show_removable, NULL); | 254 | static DEVICE_ATTR(removable, S_IRUGO, show_removable, NULL); |
| 255 | 255 | ||
| 256 | static ssize_t | ||
| 257 | show_ltm_capable(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 258 | { | ||
| 259 | if (usb_device_supports_ltm(to_usb_device(dev))) | ||
| 260 | return sprintf(buf, "%s\n", "yes"); | ||
| 261 | return sprintf(buf, "%s\n", "no"); | ||
| 262 | } | ||
| 263 | static DEVICE_ATTR(ltm_capable, S_IRUGO, show_ltm_capable, NULL); | ||
| 264 | |||
| 256 | #ifdef CONFIG_PM | 265 | #ifdef CONFIG_PM |
| 257 | 266 | ||
| 258 | static ssize_t | 267 | static ssize_t |
| @@ -649,6 +658,7 @@ static struct attribute *dev_attrs[] = { | |||
| 649 | &dev_attr_authorized.attr, | 658 | &dev_attr_authorized.attr, |
| 650 | &dev_attr_remove.attr, | 659 | &dev_attr_remove.attr, |
| 651 | &dev_attr_removable.attr, | 660 | &dev_attr_removable.attr, |
| 661 | &dev_attr_ltm_capable.attr, | ||
| 652 | NULL, | 662 | NULL, |
| 653 | }; | 663 | }; |
| 654 | static struct attribute_group dev_attr_grp = { | 664 | static struct attribute_group dev_attr_grp = { |
| @@ -840,7 +850,7 @@ static ssize_t show_modalias(struct device *dev, | |||
| 840 | alt = intf->cur_altsetting; | 850 | alt = intf->cur_altsetting; |
| 841 | 851 | ||
| 842 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" | 852 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" |
| 843 | "ic%02Xisc%02Xip%02X\n", | 853 | "ic%02Xisc%02Xip%02Xin%02X\n", |
| 844 | le16_to_cpu(udev->descriptor.idVendor), | 854 | le16_to_cpu(udev->descriptor.idVendor), |
| 845 | le16_to_cpu(udev->descriptor.idProduct), | 855 | le16_to_cpu(udev->descriptor.idProduct), |
| 846 | le16_to_cpu(udev->descriptor.bcdDevice), | 856 | le16_to_cpu(udev->descriptor.bcdDevice), |
| @@ -849,7 +859,8 @@ static ssize_t show_modalias(struct device *dev, | |||
| 849 | udev->descriptor.bDeviceProtocol, | 859 | udev->descriptor.bDeviceProtocol, |
| 850 | alt->desc.bInterfaceClass, | 860 | alt->desc.bInterfaceClass, |
| 851 | alt->desc.bInterfaceSubClass, | 861 | alt->desc.bInterfaceSubClass, |
| 852 | alt->desc.bInterfaceProtocol); | 862 | alt->desc.bInterfaceProtocol, |
| 863 | alt->desc.bInterfaceNumber); | ||
| 853 | } | 864 | } |
| 854 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | 865 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); |
| 855 | 866 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 25d0c61c3f8a..cd8fb44a3e16 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -396,6 +396,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
| 396 | dev->dev.dma_mask = bus->controller->dma_mask; | 396 | dev->dev.dma_mask = bus->controller->dma_mask; |
| 397 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); | 397 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); |
| 398 | dev->state = USB_STATE_ATTACHED; | 398 | dev->state = USB_STATE_ATTACHED; |
| 399 | dev->lpm_disable_count = 1; | ||
| 399 | atomic_set(&dev->urbnum, 0); | 400 | atomic_set(&dev->urbnum, 0); |
| 400 | 401 | ||
| 401 | INIT_LIST_HEAD(&dev->ep0.urb_list); | 402 | INIT_LIST_HEAD(&dev->ep0.urb_list); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 5c5c538ea73d..acb103c5c391 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | #include <linux/pm.h> | 1 | #include <linux/pm.h> |
| 2 | 2 | ||
| 3 | struct dev_state; | ||
| 4 | |||
| 3 | /* Functions local to drivers/usb/core/ */ | 5 | /* Functions local to drivers/usb/core/ */ |
| 4 | 6 | ||
| 5 | extern int usb_create_sysfs_dev_files(struct usb_device *dev); | 7 | extern int usb_create_sysfs_dev_files(struct usb_device *dev); |
| @@ -24,6 +26,7 @@ extern void usb_disable_device(struct usb_device *dev, int skip_ep0); | |||
| 24 | extern int usb_deauthorize_device(struct usb_device *); | 26 | extern int usb_deauthorize_device(struct usb_device *); |
| 25 | extern int usb_authorize_device(struct usb_device *); | 27 | extern int usb_authorize_device(struct usb_device *); |
| 26 | extern void usb_detect_quirks(struct usb_device *udev); | 28 | extern void usb_detect_quirks(struct usb_device *udev); |
| 29 | extern void usb_detect_interface_quirks(struct usb_device *udev); | ||
| 27 | extern int usb_remove_device(struct usb_device *udev); | 30 | extern int usb_remove_device(struct usb_device *udev); |
| 28 | 31 | ||
| 29 | extern int usb_get_device_descriptor(struct usb_device *dev, | 32 | extern int usb_get_device_descriptor(struct usb_device *dev, |
| @@ -35,16 +38,20 @@ extern int usb_set_configuration(struct usb_device *dev, int configuration); | |||
| 35 | extern int usb_choose_configuration(struct usb_device *udev); | 38 | extern int usb_choose_configuration(struct usb_device *udev); |
| 36 | 39 | ||
| 37 | extern void usb_kick_khubd(struct usb_device *dev); | 40 | extern void usb_kick_khubd(struct usb_device *dev); |
| 41 | extern int usb_match_one_id_intf(struct usb_device *dev, | ||
| 42 | struct usb_host_interface *intf, | ||
| 43 | const struct usb_device_id *id); | ||
| 38 | extern int usb_match_device(struct usb_device *dev, | 44 | extern int usb_match_device(struct usb_device *dev, |
| 39 | const struct usb_device_id *id); | 45 | const struct usb_device_id *id); |
| 40 | extern void usb_forced_unbind_intf(struct usb_interface *intf); | 46 | extern void usb_forced_unbind_intf(struct usb_interface *intf); |
| 41 | extern void usb_rebind_intf(struct usb_interface *intf); | 47 | extern void usb_rebind_intf(struct usb_interface *intf); |
| 42 | 48 | ||
| 43 | extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port, | 49 | extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port, |
| 44 | void *owner); | 50 | struct dev_state *owner); |
| 45 | extern int usb_hub_release_port(struct usb_device *hdev, unsigned port, | 51 | extern int usb_hub_release_port(struct usb_device *hdev, unsigned port, |
| 46 | void *owner); | 52 | struct dev_state *owner); |
| 47 | extern void usb_hub_release_all_ports(struct usb_device *hdev, void *owner); | 53 | extern void usb_hub_release_all_ports(struct usb_device *hdev, |
| 54 | struct dev_state *owner); | ||
| 48 | extern bool usb_device_is_owned(struct usb_device *udev); | 55 | extern bool usb_device_is_owned(struct usb_device *udev); |
| 49 | 56 | ||
| 50 | extern int usb_hub_init(void); | 57 | extern int usb_hub_init(void); |
