diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-16 12:57:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-16 12:57:38 -0400 |
| commit | 89cb9ae2382b59585381c3ae619840e64df8df97 (patch) | |
| tree | 8e97576b8ddfdd88c59a27acdf55526101e69b67 | |
| parent | ddea368c78ff9acf45261a7c82635b98e9c1fcd6 (diff) | |
| parent | ff8a43c10f1440f07a5faca0c1556921259f7f76 (diff) | |
Merge tag 'usb-3.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH:
"Here are some small USB fixes for 3.11-rc6 that have accumulated.
Nothing huge, a EHCI fix that solves a much-reported audio USB
problem, some usb-serial driver endian fixes and other minor fixes, a
wireless USB oops fix, and two new quirks"
* tag 'usb-3.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
USB: keyspan: fix null-deref at disconnect and release
USB: mos7720: fix broken control requests
usb: add two quirky touchscreen
USB: ti_usb_3410_5052: fix big-endian firmware handling
USB: adutux: fix big-endian device-type reporting
USB: usbtmc: fix big-endian probe of Rigol devices
USB: mos7840: fix big-endian probe
USB-Serial: Fix error handling of usb_wwan
wusbcore: fix kernel panic when disconnecting a wireless USB->serial device
USB: EHCI: accept very late isochronous URBs
| -rw-r--r-- | drivers/usb/class/usbtmc.c | 8 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-sched.c | 13 | ||||
| -rw-r--r-- | drivers/usb/misc/adutux.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/keyspan.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/mos7720.c | 21 | ||||
| -rw-r--r-- | drivers/usb/serial/mos7840.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.c | 9 | ||||
| -rw-r--r-- | drivers/usb/serial/usb_wwan.c | 20 | ||||
| -rw-r--r-- | drivers/usb/wusbcore/wa-xfer.c | 9 |
10 files changed, 55 insertions, 37 deletions
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 609dbc2f7151..83b4ef4dfcf8 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
| @@ -1119,11 +1119,11 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
| 1119 | /* Determine if it is a Rigol or not */ | 1119 | /* Determine if it is a Rigol or not */ |
| 1120 | data->rigol_quirk = 0; | 1120 | data->rigol_quirk = 0; |
| 1121 | dev_dbg(&intf->dev, "Trying to find if device Vendor 0x%04X Product 0x%04X has the RIGOL quirk\n", | 1121 | dev_dbg(&intf->dev, "Trying to find if device Vendor 0x%04X Product 0x%04X has the RIGOL quirk\n", |
| 1122 | data->usb_dev->descriptor.idVendor, | 1122 | le16_to_cpu(data->usb_dev->descriptor.idVendor), |
| 1123 | data->usb_dev->descriptor.idProduct); | 1123 | le16_to_cpu(data->usb_dev->descriptor.idProduct)); |
| 1124 | for(n = 0; usbtmc_id_quirk[n].idVendor > 0; n++) { | 1124 | for(n = 0; usbtmc_id_quirk[n].idVendor > 0; n++) { |
| 1125 | if ((usbtmc_id_quirk[n].idVendor == data->usb_dev->descriptor.idVendor) && | 1125 | if ((usbtmc_id_quirk[n].idVendor == le16_to_cpu(data->usb_dev->descriptor.idVendor)) && |
| 1126 | (usbtmc_id_quirk[n].idProduct == data->usb_dev->descriptor.idProduct)) { | 1126 | (usbtmc_id_quirk[n].idProduct == le16_to_cpu(data->usb_dev->descriptor.idProduct))) { |
| 1127 | dev_dbg(&intf->dev, "Setting this device as having the RIGOL quirk\n"); | 1127 | dev_dbg(&intf->dev, "Setting this device as having the RIGOL quirk\n"); |
| 1128 | data->rigol_quirk = 1; | 1128 | data->rigol_quirk = 1; |
| 1129 | break; | 1129 | break; |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index a63598895077..5b44cd47da5b 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -78,6 +78,12 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 78 | { USB_DEVICE(0x04d8, 0x000c), .driver_info = | 78 | { USB_DEVICE(0x04d8, 0x000c), .driver_info = |
| 79 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 79 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
| 80 | 80 | ||
| 81 | /* CarrolTouch 4000U */ | ||
| 82 | { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 83 | |||
| 84 | /* CarrolTouch 4500U */ | ||
| 85 | { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 86 | |||
| 81 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ | 87 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ |
| 82 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = | 88 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = |
| 83 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 89 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index f80d0330d548..8e3c878f38cf 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -1391,21 +1391,20 @@ iso_stream_schedule ( | |||
| 1391 | 1391 | ||
| 1392 | /* Behind the scheduling threshold? */ | 1392 | /* Behind the scheduling threshold? */ |
| 1393 | if (unlikely(start < next)) { | 1393 | if (unlikely(start < next)) { |
| 1394 | unsigned now2 = (now - base) & (mod - 1); | ||
| 1394 | 1395 | ||
| 1395 | /* USB_ISO_ASAP: Round up to the first available slot */ | 1396 | /* USB_ISO_ASAP: Round up to the first available slot */ |
| 1396 | if (urb->transfer_flags & URB_ISO_ASAP) | 1397 | if (urb->transfer_flags & URB_ISO_ASAP) |
| 1397 | start += (next - start + period - 1) & -period; | 1398 | start += (next - start + period - 1) & -period; |
| 1398 | 1399 | ||
| 1399 | /* | 1400 | /* |
| 1400 | * Not ASAP: Use the next slot in the stream. If | 1401 | * Not ASAP: Use the next slot in the stream, |
| 1401 | * the entire URB falls before the threshold, fail. | 1402 | * no matter what. |
| 1402 | */ | 1403 | */ |
| 1403 | else if (start + span - period < next) { | 1404 | else if (start + span - period < now2) { |
| 1404 | ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n", | 1405 | ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n", |
| 1405 | urb, start + base, | 1406 | urb, start + base, |
| 1406 | span - period, next + base); | 1407 | span - period, now2 + base); |
| 1407 | status = -EXDEV; | ||
| 1408 | goto fail; | ||
| 1409 | } | 1408 | } |
| 1410 | } | 1409 | } |
| 1411 | 1410 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index eb3c8c142fa9..eeb27208c0d1 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
| @@ -830,7 +830,7 @@ static int adu_probe(struct usb_interface *interface, | |||
| 830 | 830 | ||
| 831 | /* let the user know what node this device is now attached to */ | 831 | /* let the user know what node this device is now attached to */ |
| 832 | dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n", | 832 | dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n", |
| 833 | udev->descriptor.idProduct, dev->serial_number, | 833 | le16_to_cpu(udev->descriptor.idProduct), dev->serial_number, |
| 834 | (dev->minor - ADU_MINOR_BASE)); | 834 | (dev->minor - ADU_MINOR_BASE)); |
| 835 | exit: | 835 | exit: |
| 836 | dbg(2, " %s : leave, return value %p (dev)", __func__, dev); | 836 | dbg(2, " %s : leave, return value %p (dev)", __func__, dev); |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 5a979729f8ec..58c17fdc85eb 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
| @@ -2303,7 +2303,7 @@ static int keyspan_startup(struct usb_serial *serial) | |||
| 2303 | if (d_details == NULL) { | 2303 | if (d_details == NULL) { |
| 2304 | dev_err(&serial->dev->dev, "%s - unknown product id %x\n", | 2304 | dev_err(&serial->dev->dev, "%s - unknown product id %x\n", |
| 2305 | __func__, le16_to_cpu(serial->dev->descriptor.idProduct)); | 2305 | __func__, le16_to_cpu(serial->dev->descriptor.idProduct)); |
| 2306 | return 1; | 2306 | return -ENODEV; |
| 2307 | } | 2307 | } |
| 2308 | 2308 | ||
| 2309 | /* Setup private data for serial driver */ | 2309 | /* Setup private data for serial driver */ |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 51da424327b0..b01300164fc0 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
| @@ -90,6 +90,7 @@ struct urbtracker { | |||
| 90 | struct list_head urblist_entry; | 90 | struct list_head urblist_entry; |
| 91 | struct kref ref_count; | 91 | struct kref ref_count; |
| 92 | struct urb *urb; | 92 | struct urb *urb; |
| 93 | struct usb_ctrlrequest *setup; | ||
| 93 | }; | 94 | }; |
| 94 | 95 | ||
| 95 | enum mos7715_pp_modes { | 96 | enum mos7715_pp_modes { |
| @@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref) | |||
| 271 | struct mos7715_parport *mos_parport = urbtrack->mos_parport; | 272 | struct mos7715_parport *mos_parport = urbtrack->mos_parport; |
| 272 | 273 | ||
| 273 | usb_free_urb(urbtrack->urb); | 274 | usb_free_urb(urbtrack->urb); |
| 275 | kfree(urbtrack->setup); | ||
| 274 | kfree(urbtrack); | 276 | kfree(urbtrack); |
| 275 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | 277 | kref_put(&mos_parport->ref_count, destroy_mos_parport); |
| 276 | } | 278 | } |
| @@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | |||
| 355 | struct urbtracker *urbtrack; | 357 | struct urbtracker *urbtrack; |
| 356 | int ret_val; | 358 | int ret_val; |
| 357 | unsigned long flags; | 359 | unsigned long flags; |
| 358 | struct usb_ctrlrequest setup; | ||
| 359 | struct usb_serial *serial = mos_parport->serial; | 360 | struct usb_serial *serial = mos_parport->serial; |
| 360 | struct usb_device *usbdev = serial->dev; | 361 | struct usb_device *usbdev = serial->dev; |
| 361 | 362 | ||
| @@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | |||
| 373 | kfree(urbtrack); | 374 | kfree(urbtrack); |
| 374 | return -ENOMEM; | 375 | return -ENOMEM; |
| 375 | } | 376 | } |
| 376 | setup.bRequestType = (__u8)0x40; | 377 | urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); |
| 377 | setup.bRequest = (__u8)0x0e; | 378 | if (!urbtrack->setup) { |
| 378 | setup.wValue = get_reg_value(reg, dummy); | 379 | usb_free_urb(urbtrack->urb); |
| 379 | setup.wIndex = get_reg_index(reg); | 380 | kfree(urbtrack); |
| 380 | setup.wLength = 0; | 381 | return -ENOMEM; |
| 382 | } | ||
| 383 | urbtrack->setup->bRequestType = (__u8)0x40; | ||
| 384 | urbtrack->setup->bRequest = (__u8)0x0e; | ||
| 385 | urbtrack->setup->wValue = get_reg_value(reg, dummy); | ||
| 386 | urbtrack->setup->wIndex = get_reg_index(reg); | ||
| 387 | urbtrack->setup->wLength = 0; | ||
| 381 | usb_fill_control_urb(urbtrack->urb, usbdev, | 388 | usb_fill_control_urb(urbtrack->urb, usbdev, |
| 382 | usb_sndctrlpipe(usbdev, 0), | 389 | usb_sndctrlpipe(usbdev, 0), |
| 383 | (unsigned char *)&setup, | 390 | (unsigned char *)urbtrack->setup, |
| 384 | NULL, 0, async_complete, urbtrack); | 391 | NULL, 0, async_complete, urbtrack); |
| 385 | kref_init(&urbtrack->ref_count); | 392 | kref_init(&urbtrack->ref_count); |
| 386 | INIT_LIST_HEAD(&urbtrack->urblist_entry); | 393 | INIT_LIST_HEAD(&urbtrack->urblist_entry); |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index d953d674f222..3bac4693c038 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -2193,7 +2193,7 @@ static int mos7810_check(struct usb_serial *serial) | |||
| 2193 | static int mos7840_probe(struct usb_serial *serial, | 2193 | static int mos7840_probe(struct usb_serial *serial, |
| 2194 | const struct usb_device_id *id) | 2194 | const struct usb_device_id *id) |
| 2195 | { | 2195 | { |
| 2196 | u16 product = serial->dev->descriptor.idProduct; | 2196 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); |
| 2197 | u8 *buf; | 2197 | u8 *buf; |
| 2198 | int device_type; | 2198 | int device_type; |
| 2199 | 2199 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 375b5a400b6f..5c9f9b1d7736 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -1536,14 +1536,15 @@ static int ti_download_firmware(struct ti_device *tdev) | |||
| 1536 | char buf[32]; | 1536 | char buf[32]; |
| 1537 | 1537 | ||
| 1538 | /* try ID specific firmware first, then try generic firmware */ | 1538 | /* try ID specific firmware first, then try generic firmware */ |
| 1539 | sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor, | 1539 | sprintf(buf, "ti_usb-v%04x-p%04x.fw", |
| 1540 | dev->descriptor.idProduct); | 1540 | le16_to_cpu(dev->descriptor.idVendor), |
| 1541 | le16_to_cpu(dev->descriptor.idProduct)); | ||
| 1541 | status = request_firmware(&fw_p, buf, &dev->dev); | 1542 | status = request_firmware(&fw_p, buf, &dev->dev); |
| 1542 | 1543 | ||
| 1543 | if (status != 0) { | 1544 | if (status != 0) { |
| 1544 | buf[0] = '\0'; | 1545 | buf[0] = '\0'; |
| 1545 | if (dev->descriptor.idVendor == MTS_VENDOR_ID) { | 1546 | if (le16_to_cpu(dev->descriptor.idVendor) == MTS_VENDOR_ID) { |
| 1546 | switch (dev->descriptor.idProduct) { | 1547 | switch (le16_to_cpu(dev->descriptor.idProduct)) { |
| 1547 | case MTS_CDMA_PRODUCT_ID: | 1548 | case MTS_CDMA_PRODUCT_ID: |
| 1548 | strcpy(buf, "mts_cdma.fw"); | 1549 | strcpy(buf, "mts_cdma.fw"); |
| 1549 | break; | 1550 | break; |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 8257d30c4072..85365784040b 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
| @@ -291,18 +291,18 @@ static void usb_wwan_indat_callback(struct urb *urb) | |||
| 291 | tty_flip_buffer_push(&port->port); | 291 | tty_flip_buffer_push(&port->port); |
| 292 | } else | 292 | } else |
| 293 | dev_dbg(dev, "%s: empty read urb received\n", __func__); | 293 | dev_dbg(dev, "%s: empty read urb received\n", __func__); |
| 294 | 294 | } | |
| 295 | /* Resubmit urb so we continue receiving */ | 295 | /* Resubmit urb so we continue receiving */ |
| 296 | err = usb_submit_urb(urb, GFP_ATOMIC); | 296 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 297 | if (err) { | 297 | if (err) { |
| 298 | if (err != -EPERM) { | 298 | if (err != -EPERM) { |
| 299 | dev_err(dev, "%s: resubmit read urb failed. (%d)\n", __func__, err); | 299 | dev_err(dev, "%s: resubmit read urb failed. (%d)\n", |
| 300 | /* busy also in error unless we are killed */ | 300 | __func__, err); |
| 301 | usb_mark_last_busy(port->serial->dev); | 301 | /* busy also in error unless we are killed */ |
| 302 | } | ||
| 303 | } else { | ||
| 304 | usb_mark_last_busy(port->serial->dev); | 302 | usb_mark_last_busy(port->serial->dev); |
| 305 | } | 303 | } |
| 304 | } else { | ||
| 305 | usb_mark_last_busy(port->serial->dev); | ||
| 306 | } | 306 | } |
| 307 | } | 307 | } |
| 308 | 308 | ||
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 16968c899493..d3493ca0525d 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
| @@ -1226,6 +1226,12 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
| 1226 | } | 1226 | } |
| 1227 | spin_lock_irqsave(&xfer->lock, flags); | 1227 | spin_lock_irqsave(&xfer->lock, flags); |
| 1228 | rpipe = xfer->ep->hcpriv; | 1228 | rpipe = xfer->ep->hcpriv; |
| 1229 | if (rpipe == NULL) { | ||
| 1230 | pr_debug("%s: xfer id 0x%08X has no RPIPE. %s", | ||
| 1231 | __func__, wa_xfer_id(xfer), | ||
| 1232 | "Probably already aborted.\n" ); | ||
| 1233 | goto out_unlock; | ||
| 1234 | } | ||
| 1229 | /* Check the delayed list -> if there, release and complete */ | 1235 | /* Check the delayed list -> if there, release and complete */ |
| 1230 | spin_lock_irqsave(&wa->xfer_list_lock, flags2); | 1236 | spin_lock_irqsave(&wa->xfer_list_lock, flags2); |
| 1231 | if (!list_empty(&xfer->list_node) && xfer->seg == NULL) | 1237 | if (!list_empty(&xfer->list_node) && xfer->seg == NULL) |
| @@ -1644,8 +1650,7 @@ static void wa_xfer_result_cb(struct urb *urb) | |||
| 1644 | break; | 1650 | break; |
| 1645 | } | 1651 | } |
| 1646 | usb_status = xfer_result->bTransferStatus & 0x3f; | 1652 | usb_status = xfer_result->bTransferStatus & 0x3f; |
| 1647 | if (usb_status == WA_XFER_STATUS_ABORTED | 1653 | if (usb_status == WA_XFER_STATUS_NOT_FOUND) |
| 1648 | || usb_status == WA_XFER_STATUS_NOT_FOUND) | ||
| 1649 | /* taken care of already */ | 1654 | /* taken care of already */ |
| 1650 | break; | 1655 | break; |
| 1651 | xfer_id = xfer_result->dwTransferID; | 1656 | xfer_id = xfer_result->dwTransferID; |
