USB fixes for 3.11-rc6
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (GNU/Linux) iEYEABECAAYFAlINiREACgkQMUfUDdst+ynMkACgvH7Xfb6U27cAsf+Pf03lhWyg 4+sAnjKq3kD+UXwIaaSIeod5xEKLZLLk =+24N -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
89cb9ae238
@ -1119,11 +1119,11 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
/* Determine if it is a Rigol or not */
|
||||
data->rigol_quirk = 0;
|
||||
dev_dbg(&intf->dev, "Trying to find if device Vendor 0x%04X Product 0x%04X has the RIGOL quirk\n",
|
||||
data->usb_dev->descriptor.idVendor,
|
||||
data->usb_dev->descriptor.idProduct);
|
||||
le16_to_cpu(data->usb_dev->descriptor.idVendor),
|
||||
le16_to_cpu(data->usb_dev->descriptor.idProduct));
|
||||
for(n = 0; usbtmc_id_quirk[n].idVendor > 0; n++) {
|
||||
if ((usbtmc_id_quirk[n].idVendor == data->usb_dev->descriptor.idVendor) &&
|
||||
(usbtmc_id_quirk[n].idProduct == data->usb_dev->descriptor.idProduct)) {
|
||||
if ((usbtmc_id_quirk[n].idVendor == le16_to_cpu(data->usb_dev->descriptor.idVendor)) &&
|
||||
(usbtmc_id_quirk[n].idProduct == le16_to_cpu(data->usb_dev->descriptor.idProduct))) {
|
||||
dev_dbg(&intf->dev, "Setting this device as having the RIGOL quirk\n");
|
||||
data->rigol_quirk = 1;
|
||||
break;
|
||||
|
@ -78,6 +78,12 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x04d8, 0x000c), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* CarrolTouch 4000U */
|
||||
{ USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* CarrolTouch 4500U */
|
||||
{ USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Samsung Android phone modem - ID conflict with SPH-I500 */
|
||||
{ USB_DEVICE(0x04e8, 0x6601), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
@ -1391,21 +1391,20 @@ iso_stream_schedule (
|
||||
|
||||
/* Behind the scheduling threshold? */
|
||||
if (unlikely(start < next)) {
|
||||
unsigned now2 = (now - base) & (mod - 1);
|
||||
|
||||
/* USB_ISO_ASAP: Round up to the first available slot */
|
||||
if (urb->transfer_flags & URB_ISO_ASAP)
|
||||
start += (next - start + period - 1) & -period;
|
||||
|
||||
/*
|
||||
* Not ASAP: Use the next slot in the stream. If
|
||||
* the entire URB falls before the threshold, fail.
|
||||
* Not ASAP: Use the next slot in the stream,
|
||||
* no matter what.
|
||||
*/
|
||||
else if (start + span - period < next) {
|
||||
ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
|
||||
else if (start + span - period < now2) {
|
||||
ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n",
|
||||
urb, start + base,
|
||||
span - period, next + base);
|
||||
status = -EXDEV;
|
||||
goto fail;
|
||||
span - period, now2 + base);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,7 +830,7 @@ static int adu_probe(struct usb_interface *interface,
|
||||
|
||||
/* let the user know what node this device is now attached to */
|
||||
dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n",
|
||||
udev->descriptor.idProduct, dev->serial_number,
|
||||
le16_to_cpu(udev->descriptor.idProduct), dev->serial_number,
|
||||
(dev->minor - ADU_MINOR_BASE));
|
||||
exit:
|
||||
dbg(2, " %s : leave, return value %p (dev)", __func__, dev);
|
||||
|
@ -2303,7 +2303,7 @@ static int keyspan_startup(struct usb_serial *serial)
|
||||
if (d_details == NULL) {
|
||||
dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
|
||||
__func__, le16_to_cpu(serial->dev->descriptor.idProduct));
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Setup private data for serial driver */
|
||||
|
@ -90,6 +90,7 @@ struct urbtracker {
|
||||
struct list_head urblist_entry;
|
||||
struct kref ref_count;
|
||||
struct urb *urb;
|
||||
struct usb_ctrlrequest *setup;
|
||||
};
|
||||
|
||||
enum mos7715_pp_modes {
|
||||
@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref)
|
||||
struct mos7715_parport *mos_parport = urbtrack->mos_parport;
|
||||
|
||||
usb_free_urb(urbtrack->urb);
|
||||
kfree(urbtrack->setup);
|
||||
kfree(urbtrack);
|
||||
kref_put(&mos_parport->ref_count, destroy_mos_parport);
|
||||
}
|
||||
@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
||||
struct urbtracker *urbtrack;
|
||||
int ret_val;
|
||||
unsigned long flags;
|
||||
struct usb_ctrlrequest setup;
|
||||
struct usb_serial *serial = mos_parport->serial;
|
||||
struct usb_device *usbdev = serial->dev;
|
||||
|
||||
@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
||||
kfree(urbtrack);
|
||||
return -ENOMEM;
|
||||
}
|
||||
setup.bRequestType = (__u8)0x40;
|
||||
setup.bRequest = (__u8)0x0e;
|
||||
setup.wValue = get_reg_value(reg, dummy);
|
||||
setup.wIndex = get_reg_index(reg);
|
||||
setup.wLength = 0;
|
||||
urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
|
||||
if (!urbtrack->setup) {
|
||||
usb_free_urb(urbtrack->urb);
|
||||
kfree(urbtrack);
|
||||
return -ENOMEM;
|
||||
}
|
||||
urbtrack->setup->bRequestType = (__u8)0x40;
|
||||
urbtrack->setup->bRequest = (__u8)0x0e;
|
||||
urbtrack->setup->wValue = get_reg_value(reg, dummy);
|
||||
urbtrack->setup->wIndex = get_reg_index(reg);
|
||||
urbtrack->setup->wLength = 0;
|
||||
usb_fill_control_urb(urbtrack->urb, usbdev,
|
||||
usb_sndctrlpipe(usbdev, 0),
|
||||
(unsigned char *)&setup,
|
||||
(unsigned char *)urbtrack->setup,
|
||||
NULL, 0, async_complete, urbtrack);
|
||||
kref_init(&urbtrack->ref_count);
|
||||
INIT_LIST_HEAD(&urbtrack->urblist_entry);
|
||||
|
@ -2193,7 +2193,7 @@ static int mos7810_check(struct usb_serial *serial)
|
||||
static int mos7840_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
u16 product = serial->dev->descriptor.idProduct;
|
||||
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
|
||||
u8 *buf;
|
||||
int device_type;
|
||||
|
||||
|
@ -1536,14 +1536,15 @@ static int ti_download_firmware(struct ti_device *tdev)
|
||||
char buf[32];
|
||||
|
||||
/* try ID specific firmware first, then try generic firmware */
|
||||
sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
|
||||
dev->descriptor.idProduct);
|
||||
sprintf(buf, "ti_usb-v%04x-p%04x.fw",
|
||||
le16_to_cpu(dev->descriptor.idVendor),
|
||||
le16_to_cpu(dev->descriptor.idProduct));
|
||||
status = request_firmware(&fw_p, buf, &dev->dev);
|
||||
|
||||
if (status != 0) {
|
||||
buf[0] = '\0';
|
||||
if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
|
||||
switch (dev->descriptor.idProduct) {
|
||||
if (le16_to_cpu(dev->descriptor.idVendor) == MTS_VENDOR_ID) {
|
||||
switch (le16_to_cpu(dev->descriptor.idProduct)) {
|
||||
case MTS_CDMA_PRODUCT_ID:
|
||||
strcpy(buf, "mts_cdma.fw");
|
||||
break;
|
||||
|
@ -291,19 +291,19 @@ static void usb_wwan_indat_callback(struct urb *urb)
|
||||
tty_flip_buffer_push(&port->port);
|
||||
} else
|
||||
dev_dbg(dev, "%s: empty read urb received\n", __func__);
|
||||
|
||||
}
|
||||
/* Resubmit urb so we continue receiving */
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
if (err != -EPERM) {
|
||||
dev_err(dev, "%s: resubmit read urb failed. (%d)\n", __func__, err);
|
||||
dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
|
||||
__func__, err);
|
||||
/* busy also in error unless we are killed */
|
||||
usb_mark_last_busy(port->serial->dev);
|
||||
}
|
||||
} else {
|
||||
usb_mark_last_busy(port->serial->dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_wwan_outdat_callback(struct urb *urb)
|
||||
|
@ -1226,6 +1226,12 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
|
||||
}
|
||||
spin_lock_irqsave(&xfer->lock, flags);
|
||||
rpipe = xfer->ep->hcpriv;
|
||||
if (rpipe == NULL) {
|
||||
pr_debug("%s: xfer id 0x%08X has no RPIPE. %s",
|
||||
__func__, wa_xfer_id(xfer),
|
||||
"Probably already aborted.\n" );
|
||||
goto out_unlock;
|
||||
}
|
||||
/* Check the delayed list -> if there, release and complete */
|
||||
spin_lock_irqsave(&wa->xfer_list_lock, flags2);
|
||||
if (!list_empty(&xfer->list_node) && xfer->seg == NULL)
|
||||
@ -1644,8 +1650,7 @@ static void wa_xfer_result_cb(struct urb *urb)
|
||||
break;
|
||||
}
|
||||
usb_status = xfer_result->bTransferStatus & 0x3f;
|
||||
if (usb_status == WA_XFER_STATUS_ABORTED
|
||||
|| usb_status == WA_XFER_STATUS_NOT_FOUND)
|
||||
if (usb_status == WA_XFER_STATUS_NOT_FOUND)
|
||||
/* taken care of already */
|
||||
break;
|
||||
xfer_id = xfer_result->dwTransferID;
|
||||
|
Loading…
Reference in New Issue
Block a user