Skip to content

Commit

Permalink
Merge tag 'usb-4.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/gregkh/usb

Pull USB driver fixes from Greg KH:
 "Here are a number of small USB fixes for 4.4-rc5.  All of them have
  been in linux-next.  The majority are gadget and phy issues, with a
  few new quirks and device ids added as well"

* tag 'usb-4.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (32 commits)
  USB: add quirk for devices with broken LPM
  xhci: fix usb2 resume timing and races.
  usb: musb: fail with error when no DMA controller set
  usb: gadget: uvc: fix permissions of configfs attributes
  usb: musb: core: Fix pm runtime for deferred probe
  usb: phy: msm: fix a possible NULL dereference
  USB: host: ohci-at91: fix a crash in ohci_hcd_at91_overcurrent_irq
  usb: Quiet down false peer failure messages
  usb: xhci: fix config fail of FS hub behind a HS hub with MTT
  xhci: Fix memory leak in xhci_pme_acpi_rtd3_enable()
  usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message
  USB: whci-hcd: add check for dma mapping error
  usb: core : hub: Fix BOS 'NULL pointer' kernel panic
  USB: quirks: Apply ALWAYS_POLL to all ELAN devices
  usb-storage: Fix scsi-sd failure "Invalid field in cdb" for USB adapter JMicron
  USB: quirks: Fix another ELAN touchscreen
  usb: dwc3: gadget: don't prestart interrupt endpoints
  USB: serial: Another Infineon flash loader USB ID
  USB: cdc_acm: Ignore Infineon Flash Loader utility
  USB: cp210x: Remove CP2110 ID from compatibility list
  ...
  • Loading branch information
Linus Torvalds committed Dec 13, 2015
2 parents 097b285 + ad87e03 commit c474009
Show file tree
Hide file tree
Showing 30 changed files with 200 additions and 79 deletions.
5 changes: 0 additions & 5 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,6 @@
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001

#define USB_VENDOR_ID_ELAN 0x04f3
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103 0x0103
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c 0x010c
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f

#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
Expand Down
9 changes: 3 additions & 6 deletions drivers/hid/usbhid/hid-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
Expand Down Expand Up @@ -340,7 +336,8 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,

for (; hid_blacklist[n].idVendor; n++)
if (hid_blacklist[n].idVendor == idVendor &&
hid_blacklist[n].idProduct == idProduct)
(hid_blacklist[n].idProduct == (__u16) HID_ANY_ID ||
hid_blacklist[n].idProduct == idProduct))
bl_entry = &hid_blacklist[n];

if (bl_entry != NULL)
Expand Down
5 changes: 5 additions & 0 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,11 @@ static const struct usb_device_id acm_ids[] = {
},
#endif

/* Exclude Infineon Flash Loader utility */
{ USB_DEVICE(0x058b, 0x0041),
.driver_info = IGNORE_DEVICE,
},

/* control interfaces without any protocol set */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_PROTO_NONE) },
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/core/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
USB_SS_MULT(desc->bmAttributes) > 3) {
dev_warn(ddev, "Isoc endpoint has Mult of %d in "
"config %d interface %d altsetting %d ep %d: "
"setting to 3\n", desc->bmAttributes + 1,
"setting to 3\n",
USB_SS_MULT(desc->bmAttributes),
cfgno, inum, asnum, ep->desc.bEndpointAddress);
ep->ss_ep_comp.bmAttributes = 2;
}
Expand Down
22 changes: 14 additions & 8 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)

int usb_device_supports_lpm(struct usb_device *udev)
{
/* Some devices have trouble with LPM */
if (udev->quirks & USB_QUIRK_NO_LPM)
return 0;

/* USB 2.1 (and greater) devices indicate LPM support through
* their USB 2.0 Extended Capabilities BOS descriptor.
*/
Expand Down Expand Up @@ -4512,6 +4516,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
goto fail;
}

usb_detect_quirks(udev);

if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
retval = usb_get_bos_descriptor(udev);
if (!retval) {
Expand Down Expand Up @@ -4710,7 +4716,6 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
if (status < 0)
goto loop;

usb_detect_quirks(udev);
if (udev->quirks & USB_QUIRK_DELAY_INIT)
msleep(1000);

Expand Down Expand Up @@ -5326,9 +5331,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
if (udev->usb2_hw_lpm_enabled == 1)
usb_set_usb2_hardware_lpm(udev, 0);

bos = udev->bos;
udev->bos = NULL;

/* Disable LPM and LTM while we reset the device and reinstall the alt
* settings. Device-initiated LPM settings, and system exit latency
* settings are cleared when the device is reset, so we have to set
Expand All @@ -5337,15 +5339,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
ret = usb_unlocked_disable_lpm(udev);
if (ret) {
dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__);
goto re_enumerate;
goto re_enumerate_no_bos;
}
ret = usb_disable_ltm(udev);
if (ret) {
dev_err(&udev->dev, "%s Failed to disable LTM\n.",
__func__);
goto re_enumerate;
goto re_enumerate_no_bos;
}

bos = udev->bos;
udev->bos = NULL;

for (i = 0; i < SET_CONFIG_TRIES; ++i) {

/* ep0 maxpacket size may change; let the HCD know about it.
Expand Down Expand Up @@ -5442,10 +5447,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
return 0;

re_enumerate:
/* LPM state doesn't matter when we're about to destroy the device. */
hub_port_logical_disconnect(parent_hub, port1);
usb_release_bos_descriptor(udev);
udev->bos = bos;
re_enumerate_no_bos:
/* LPM state doesn't matter when we're about to destroy the device. */
hub_port_logical_disconnect(parent_hub, port1);
return -ENODEV;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/core/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static int link_peers(struct usb_port *left, struct usb_port *right)
else
method = "default";

pr_warn("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
pr_debug("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
dev_name(&left->dev), dev_name(&right->dev), method,
dev_name(&left->dev),
lpeer ? dev_name(&lpeer->dev) : "none",
Expand Down Expand Up @@ -265,7 +265,7 @@ static void link_peers_report(struct usb_port *left, struct usb_port *right)
if (rc == 0) {
dev_dbg(&left->dev, "peered to %s\n", dev_name(&right->dev));
} else {
dev_warn(&left->dev, "failed to peer to %s (%d)\n",
dev_dbg(&left->dev, "failed to peer to %s (%d)\n",
dev_name(&right->dev), rc);
pr_warn_once("usb: port power management may be unreliable\n");
usb_port_block_power_off = 1;
Expand Down
9 changes: 9 additions & 0 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x04f3, 0x016f), .driver_info =
USB_QUIRK_DEVICE_QUALIFIER },

{ USB_DEVICE(0x04f3, 0x21b8), .driver_info =
USB_QUIRK_DEVICE_QUALIFIER },

/* Roland SC-8820 */
{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },

Expand Down Expand Up @@ -199,6 +202,12 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },

/* Blackmagic Design Intensity Shuttle */
{ USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },

/* Blackmagic Design UltraStudio SDI */
{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },

{ } /* terminating entry must be last */
};

Expand Down
81 changes: 53 additions & 28 deletions drivers/usb/dwc2/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
if (ret)
return ret;

ret = clk_prepare_enable(hsotg->clk);
if (ret)
return ret;
if (hsotg->clk) {
ret = clk_prepare_enable(hsotg->clk);
if (ret)
return ret;
}

if (hsotg->uphy)
ret = usb_phy_init(hsotg->uphy);
Expand Down Expand Up @@ -175,7 +177,8 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
if (ret)
return ret;

clk_disable_unprepare(hsotg->clk);
if (hsotg->clk)
clk_disable_unprepare(hsotg->clk);

ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
hsotg->supplies);
Expand Down Expand Up @@ -212,14 +215,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
*/
hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
if (IS_ERR(hsotg->phy)) {
hsotg->phy = NULL;
ret = PTR_ERR(hsotg->phy);
switch (ret) {
case -ENODEV:
case -ENOSYS:
hsotg->phy = NULL;
break;
case -EPROBE_DEFER:
return ret;
default:
dev_err(hsotg->dev, "error getting phy %d\n", ret);
return ret;
}
}

if (!hsotg->phy) {
hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
if (IS_ERR(hsotg->uphy))
hsotg->uphy = NULL;
else
hsotg->plat = dev_get_platdata(hsotg->dev);
if (IS_ERR(hsotg->uphy)) {
ret = PTR_ERR(hsotg->uphy);
switch (ret) {
case -ENODEV:
case -ENXIO:
hsotg->uphy = NULL;
break;
case -EPROBE_DEFER:
return ret;
default:
dev_err(hsotg->dev, "error getting usb phy %d\n",
ret);
return ret;
}
}
}

hsotg->plat = dev_get_platdata(hsotg->dev);

if (hsotg->phy) {
/*
* If using the generic PHY framework, check if the PHY bus
Expand All @@ -229,11 +259,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
hsotg->phyif = GUSBCFG_PHYIF8;
}

if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) {
dev_err(hsotg->dev, "no platform data or transceiver defined\n");
return -EPROBE_DEFER;
}

/* Clock */
hsotg->clk = devm_clk_get(hsotg->dev, "otg");
if (IS_ERR(hsotg->clk)) {
Expand Down Expand Up @@ -342,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
if (retval)
return retval;

irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "missing IRQ resource\n");
return irq;
}

dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
irq);
retval = devm_request_irq(hsotg->dev, irq,
dwc2_handle_common_intr, IRQF_SHARED,
dev_name(hsotg->dev), hsotg);
if (retval)
return retval;

res = platform_get_resource(dev, IORESOURCE_MEM, 0);
hsotg->regs = devm_ioremap_resource(&dev->dev, res);
if (IS_ERR(hsotg->regs))
Expand Down Expand Up @@ -390,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev)

dwc2_set_all_params(hsotg->core_params, -1);

irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "missing IRQ resource\n");
return irq;
}

dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
irq);
retval = devm_request_irq(hsotg->dev, irq,
dwc2_handle_common_intr, IRQF_SHARED,
dev_name(hsotg->dev), hsotg);
if (retval)
return retval;

retval = dwc2_lowlevel_hw_enable(hsotg);
if (retval)
return retval;
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
* little bit faster.
*/
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
!usb_endpoint_xfer_int(dep->endpoint.desc) &&
!(dep->flags & DWC3_EP_BUSY)) {
ret = __dwc3_gadget_kick_transfer(dep, 0, true);
goto out;
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/function/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf,
spin_unlock_irq(&ffs->ev.waitq.lock);
mutex_unlock(&ffs->mutex);

return unlikely(__copy_to_user(buf, events, size)) ? -EFAULT : size;
return unlikely(copy_to_user(buf, events, size)) ? -EFAULT : size;
}

static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
Expand Down Expand Up @@ -513,7 +513,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,

/* unlocks spinlock */
ret = __ffs_ep0_queue_wait(ffs, data, len);
if (likely(ret > 0) && unlikely(__copy_to_user(buf, data, len)))
if (likely(ret > 0) && unlikely(copy_to_user(buf, data, len)))
ret = -EFAULT;
goto done_mutex;

Expand Down Expand Up @@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len)
if (unlikely(!data))
return ERR_PTR(-ENOMEM);

if (unlikely(__copy_from_user(data, buf, len))) {
if (unlikely(copy_from_user(data, buf, len))) {
kfree(data);
return ERR_PTR(-EFAULT);
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/gadget/function/f_midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
if (err) {
ERROR(midi, "%s queue req: %d\n",
midi->out_ep->name, err);
free_ep_req(midi->out_ep, req);
}
}

Expand Down Expand Up @@ -545,7 +546,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
}
}

if (req->length > 0) {
if (req->length > 0 && ep->enabled) {
int err;

err = usb_ep_queue(ep, req, GFP_ATOMIC);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/gadget/function/uvc_configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define UVC_ATTR(prefix, cname, aname) \
static struct configfs_attribute prefix##attr_##cname = { \
.ca_name = __stringify(aname), \
.ca_mode = S_IRUGO, \
.ca_mode = S_IRUGO | S_IWUGO, \
.ca_owner = THIS_MODULE, \
.show = prefix##cname##_show, \
.store = prefix##cname##_store, \
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/gadget/udc/pxa27x_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
udc->pullup_resume = udc->pullup_on;
dplus_pullup(udc, 0);

if (udc->driver)
udc->driver->disconnect(&udc->gadget);

return 0;
}

Expand Down
Loading

0 comments on commit c474009

Please sign in to comment.