From: Greg Kroah-Hartman Date: Fri, 2 Sep 2016 14:23:04 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.14.78~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d7b0572a9a9098d75df0f2c86a57baae927b7777;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: usb-define-usb_speed_super_plus-speed-for-superspeedplus-usb3.1-devices.patch usb-dwc3-gadget-increment-request-actual-once.patch usb-dwc3-pci-add-intel-kabylake-pci-id.patch usb-ehci-change-order-of-register-cleanup-during-shutdown.patch usb-gadget-fix-gadgetfs-aio-support.patch usb-gadget-fsl_qe_udc-off-by-one-in-setup_received_handle.patch usb-hub-change-the-locking-in-hub_activate.patch usb-hub-fix-unbalanced-reference-count-memory-leak-deadlocks.patch usb-hub-fix-up-early-exit-pathway-in-hub_activate.patch usb-misc-usbtest-add-fix-for-driver-hang.patch usb-renesas_usbhs-clear-the-brdysts-in-usbhsg_ep_enable.patch usb-renesas_usbhs-use-dmac-only-if-the-pipe-type-is-bulk.patch usb-serial-fix-memleak-in-driver-registration-error-path.patch usb-serial-ftdi_sio-add-device-id-for-wiced-usb-uart-dev-board.patch usb-serial-ftdi_sio-add-pids-for-ivium-technologies-devices.patch usb-serial-option-add-d-link-dwm-156-a3.patch usb-serial-option-add-support-for-telit-le920a4.patch usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch usb-xhci-fix-panic-if-disconnect.patch xhci-always-handle-command-ring-stopped-events.patch xhci-don-t-dereference-a-xhci-member-after-removing-xhci.patch --- diff --git a/queue-4.4/series b/queue-4.4/series index 545a652ae44..d33e70824af 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -29,3 +29,24 @@ genirq-msi-make-sure-pci-msis-are-activated-early.patch crypto-caam-fix-non-hmac-hashes.patch crypto-caam-fix-echainiv-authenc-encrypt-shared-descriptor.patch crypto-caam-defer-aead_set_sh_desc-in-case-of-zero-authsize.patch +usb-ehci-change-order-of-register-cleanup-during-shutdown.patch +usb-misc-usbtest-add-fix-for-driver-hang.patch +usb-dwc3-pci-add-intel-kabylake-pci-id.patch +usb-dwc3-gadget-increment-request-actual-once.patch +usb-define-usb_speed_super_plus-speed-for-superspeedplus-usb3.1-devices.patch +usb-hub-fix-unbalanced-reference-count-memory-leak-deadlocks.patch +usb-hub-fix-up-early-exit-pathway-in-hub_activate.patch +usb-hub-change-the-locking-in-hub_activate.patch +usb-renesas_usbhs-clear-the-brdysts-in-usbhsg_ep_enable.patch +usb-renesas_usbhs-use-dmac-only-if-the-pipe-type-is-bulk.patch +usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch +usb-gadget-fsl_qe_udc-off-by-one-in-setup_received_handle.patch +usb-gadget-fix-gadgetfs-aio-support.patch +xhci-always-handle-command-ring-stopped-events.patch +usb-xhci-fix-panic-if-disconnect.patch +xhci-don-t-dereference-a-xhci-member-after-removing-xhci.patch +usb-serial-fix-memleak-in-driver-registration-error-path.patch +usb-serial-option-add-d-link-dwm-156-a3.patch +usb-serial-option-add-support-for-telit-le920a4.patch +usb-serial-ftdi_sio-add-device-id-for-wiced-usb-uart-dev-board.patch +usb-serial-ftdi_sio-add-pids-for-ivium-technologies-devices.patch diff --git a/queue-4.4/usb-define-usb_speed_super_plus-speed-for-superspeedplus-usb3.1-devices.patch b/queue-4.4/usb-define-usb_speed_super_plus-speed-for-superspeedplus-usb3.1-devices.patch new file mode 100644 index 00000000000..dc1c386000f --- /dev/null +++ b/queue-4.4/usb-define-usb_speed_super_plus-speed-for-superspeedplus-usb3.1-devices.patch @@ -0,0 +1,294 @@ +From 8a1b2725a60d3267135c15e80984b4406054f650 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 10 Dec 2015 09:59:25 +0200 +Subject: usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices + +From: Mathias Nyman + +commit 8a1b2725a60d3267135c15e80984b4406054f650 upstream. + +Add a new USB_SPEED_SUPER_PLUS device speed, and make sure usb core can +handle the new speed. +In most cases the behaviour is the same as with USB_SPEED_SUPER SuperSpeed +devices. In a few places we add a "Plus" string to inform the user of the +new speed. + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/common/common.c | 1 + + drivers/usb/core/config.c | 3 ++- + drivers/usb/core/devices.c | 10 ++++++---- + drivers/usb/core/hcd-pci.c | 2 +- + drivers/usb/core/hcd.c | 6 +++--- + drivers/usb/core/hub.c | 26 +++++++++++++++----------- + drivers/usb/core/urb.c | 3 ++- + drivers/usb/core/usb.h | 2 +- + include/uapi/linux/usb/ch9.h | 1 + + 9 files changed, 32 insertions(+), 22 deletions(-) + +--- a/drivers/usb/common/common.c ++++ b/drivers/usb/common/common.c +@@ -50,6 +50,7 @@ static const char *const speed_names[] = + [USB_SPEED_HIGH] = "high-speed", + [USB_SPEED_WIRELESS] = "wireless", + [USB_SPEED_SUPER] = "super-speed", ++ [USB_SPEED_SUPER_PLUS] = "super-speed-plus", + }; + + const char *usb_speed_string(enum usb_device_speed speed) +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -191,6 +191,7 @@ static int usb_parse_endpoint(struct dev + if (usb_endpoint_xfer_int(d)) { + i = 1; + switch (to_usb_device(ddev)->speed) { ++ case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: + case USB_SPEED_HIGH: + /* Many device manufacturers are using full-speed +@@ -274,7 +275,7 @@ static int usb_parse_endpoint(struct dev + } + + /* Parse a possible SuperSpeed endpoint companion descriptor */ +- if (to_usb_device(ddev)->speed == USB_SPEED_SUPER) ++ if (to_usb_device(ddev)->speed >= USB_SPEED_SUPER) + usb_parse_ss_endpoint_companion(ddev, cfgno, + inum, asnum, endpoint, buffer, size); + +--- a/drivers/usb/core/devices.c ++++ b/drivers/usb/core/devices.c +@@ -221,7 +221,7 @@ static char *usb_dump_endpoint_descripto + break; + case USB_ENDPOINT_XFER_INT: + type = "Int."; +- if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER) ++ if (speed == USB_SPEED_HIGH || speed >= USB_SPEED_SUPER) + interval = 1 << (desc->bInterval - 1); + else + interval = desc->bInterval; +@@ -230,7 +230,7 @@ static char *usb_dump_endpoint_descripto + return start; + } + interval *= (speed == USB_SPEED_HIGH || +- speed == USB_SPEED_SUPER) ? 125 : 1000; ++ speed >= USB_SPEED_SUPER) ? 125 : 1000; + if (interval % 1000) + unit = 'u'; + else { +@@ -322,7 +322,7 @@ static char *usb_dump_config_descriptor( + + if (start > end) + return start; +- if (speed == USB_SPEED_SUPER) ++ if (speed >= USB_SPEED_SUPER) + mul = 8; + else + mul = 2; +@@ -534,6 +534,8 @@ static ssize_t usb_device_dump(char __us + speed = "480"; break; + case USB_SPEED_SUPER: + speed = "5000"; break; ++ case USB_SPEED_SUPER_PLUS: ++ speed = "10000"; break; + default: + speed = "??"; + } +@@ -553,7 +555,7 @@ static ssize_t usb_device_dump(char __us + + /* super/high speed reserves 80%, full/low reserves 90% */ + if (usbdev->speed == USB_SPEED_HIGH || +- usbdev->speed == USB_SPEED_SUPER) ++ usbdev->speed >= USB_SPEED_SUPER) + max = 800; + else + max = FRAME_TIME_MAX_USECS_ALLOC; +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -206,7 +206,7 @@ int usb_hcd_pci_probe(struct pci_dev *de + * The xHCI driver has its own irq management + * make sure irq setup is not touched for xhci in generic hcd code + */ +- if ((driver->flags & HCD_MASK) != HCD_USB3) { ++ if ((driver->flags & HCD_MASK) < HCD_USB3) { + if (!dev->irq) { + dev_err(&dev->dev, + "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1078,7 +1078,7 @@ static int register_root_hub(struct usb_ + retval = usb_get_bos_descriptor(usb_dev); + if (!retval) { + usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev); +- } else if (usb_dev->speed == USB_SPEED_SUPER) { ++ } else if (usb_dev->speed >= USB_SPEED_SUPER) { + mutex_unlock(&usb_bus_list_lock); + dev_dbg(parent_dev, "can't read %s bos descriptor %d\n", + dev_name(&usb_dev->dev), retval); +@@ -2112,7 +2112,7 @@ int usb_alloc_streams(struct usb_interfa + hcd = bus_to_hcd(dev->bus); + if (!hcd->driver->alloc_streams || !hcd->driver->free_streams) + return -EINVAL; +- if (dev->speed != USB_SPEED_SUPER) ++ if (dev->speed < USB_SPEED_SUPER) + return -EINVAL; + if (dev->state < USB_STATE_CONFIGURED) + return -ENODEV; +@@ -2160,7 +2160,7 @@ int usb_free_streams(struct usb_interfac + + dev = interface_to_usbdev(interface); + hcd = bus_to_hcd(dev->bus); +- if (dev->speed != USB_SPEED_SUPER) ++ if (dev->speed < USB_SPEED_SUPER) + return -EINVAL; + + /* Double-free is not allowed */ +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -298,7 +298,7 @@ static void usb_set_lpm_parameters(struc + unsigned int hub_u1_del; + unsigned int hub_u2_del; + +- if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER) ++ if (!udev->lpm_capable || udev->speed < USB_SPEED_SUPER) + return; + + hub = usb_hub_to_struct_hub(udev->parent); +@@ -2645,7 +2645,7 @@ static unsigned hub_is_wusb(struct usb_h + */ + static bool use_new_scheme(struct usb_device *udev, int retry) + { +- if (udev->speed == USB_SPEED_SUPER) ++ if (udev->speed >= USB_SPEED_SUPER) + return false; + + return USE_NEW_SCHEME(retry); +@@ -3985,7 +3985,7 @@ int usb_disable_lpm(struct usb_device *u + struct usb_hcd *hcd; + + if (!udev || !udev->parent || +- udev->speed != USB_SPEED_SUPER || ++ udev->speed < USB_SPEED_SUPER || + !udev->lpm_capable || + udev->state < USB_STATE_DEFAULT) + return 0; +@@ -4042,7 +4042,7 @@ void usb_enable_lpm(struct usb_device *u + struct usb_hcd *hcd; + + if (!udev || !udev->parent || +- udev->speed != USB_SPEED_SUPER || ++ udev->speed < USB_SPEED_SUPER || + !udev->lpm_capable || + udev->state < USB_STATE_DEFAULT) + return; +@@ -4308,7 +4308,9 @@ hub_port_init(struct usb_hub *hub, struc + + retval = -ENODEV; + +- if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { ++ /* Don't allow speed changes at reset, except usb 3.0 to faster */ ++ if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed && ++ !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) { + dev_dbg(&udev->dev, "device reset changed speed!\n"); + goto fail; + } +@@ -4320,6 +4322,7 @@ hub_port_init(struct usb_hub *hub, struc + * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. + */ + switch (udev->speed) { ++ case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: + case USB_SPEED_WIRELESS: /* fixed at 512 */ + udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); +@@ -4346,7 +4349,7 @@ hub_port_init(struct usb_hub *hub, struc + else + speed = usb_speed_string(udev->speed); + +- if (udev->speed != USB_SPEED_SUPER) ++ if (udev->speed < USB_SPEED_SUPER) + dev_info(&udev->dev, + "%s %s USB device number %d using %s\n", + (udev->config) ? "reset" : "new", speed, +@@ -4476,11 +4479,12 @@ hub_port_init(struct usb_hub *hub, struc + devnum, retval); + goto fail; + } +- if (udev->speed == USB_SPEED_SUPER) { ++ if (udev->speed >= USB_SPEED_SUPER) { + devnum = udev->devnum; + dev_info(&udev->dev, +- "%s SuperSpeed USB device number %d using %s\n", ++ "%s SuperSpeed%s USB device number %d using %s\n", + (udev->config) ? "reset" : "new", ++ (udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "", + devnum, udev->bus->controller->driver->name); + } + +@@ -4519,7 +4523,7 @@ hub_port_init(struct usb_hub *hub, struc + * got from those devices show they aren't superspeed devices. Warm + * reset the port attached by the devices can fix them. + */ +- if ((udev->speed == USB_SPEED_SUPER) && ++ if ((udev->speed >= USB_SPEED_SUPER) && + (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { + dev_err(&udev->dev, "got a wrong device descriptor, " + "warm reset device\n"); +@@ -4530,7 +4534,7 @@ hub_port_init(struct usb_hub *hub, struc + } + + if (udev->descriptor.bMaxPacketSize0 == 0xff || +- udev->speed == USB_SPEED_SUPER) ++ udev->speed >= USB_SPEED_SUPER) + i = 512; + else + i = udev->descriptor.bMaxPacketSize0; +@@ -4740,7 +4744,7 @@ static void hub_port_connect(struct usb_ + udev->level = hdev->level + 1; + udev->wusb = hub_is_wusb(hub); + +- /* Only USB 3.0 devices are connected to SuperSpeed hubs. */ ++ /* Devices connected to SuperSpeed hubs are USB 3.0 or later */ + if (hub_is_superspeed(hub->hdev)) + udev->speed = USB_SPEED_SUPER; + else +--- a/drivers/usb/core/urb.c ++++ b/drivers/usb/core/urb.c +@@ -401,7 +401,7 @@ int usb_submit_urb(struct urb *urb, gfp_ + /* SuperSpeed isoc endpoints have up to 16 bursts of up to + * 3 packets each + */ +- if (dev->speed == USB_SPEED_SUPER) { ++ if (dev->speed >= USB_SPEED_SUPER) { + int burst = 1 + ep->ss_ep_comp.bMaxBurst; + int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes); + max *= burst; +@@ -499,6 +499,7 @@ int usb_submit_urb(struct urb *urb, gfp_ + } + /* too big? */ + switch (dev->speed) { ++ case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: /* units are 125us */ + /* Handle up to 2^(16-1) microframes */ + if (urb->interval > (1 << 15)) +--- a/drivers/usb/core/usb.h ++++ b/drivers/usb/core/usb.h +@@ -45,7 +45,7 @@ static inline unsigned usb_get_max_power + struct usb_host_config *c) + { + /* SuperSpeed power is in 8 mA units; others are in 2 mA units */ +- unsigned mul = (udev->speed == USB_SPEED_SUPER ? 8 : 2); ++ unsigned mul = (udev->speed >= USB_SPEED_SUPER ? 8 : 2); + + return c->desc.bMaxPower * mul; + } +--- a/include/uapi/linux/usb/ch9.h ++++ b/include/uapi/linux/usb/ch9.h +@@ -954,6 +954,7 @@ enum usb_device_speed { + USB_SPEED_HIGH, /* usb 2.0 */ + USB_SPEED_WIRELESS, /* wireless (usb 2.5) */ + USB_SPEED_SUPER, /* usb 3.0 */ ++ USB_SPEED_SUPER_PLUS, /* usb 3.1 */ + }; + + diff --git a/queue-4.4/usb-dwc3-gadget-increment-request-actual-once.patch b/queue-4.4/usb-dwc3-gadget-increment-request-actual-once.patch new file mode 100644 index 00000000000..ce629652cbb --- /dev/null +++ b/queue-4.4/usb-dwc3-gadget-increment-request-actual-once.patch @@ -0,0 +1,74 @@ +From c7de573471832dff7d31f0c13b0f143d6f017799 Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Fri, 29 Jul 2016 03:17:58 +0300 +Subject: usb: dwc3: gadget: increment request->actual once + +From: Felipe Balbi + +commit c7de573471832dff7d31f0c13b0f143d6f017799 upstream. + +When using SG lists, we would end up setting +request->actual to: + + num_mapped_sgs * (request->length - count) + +Let's fix that up by incrementing request->actual +only once. + +Reported-by: Brian E Rogers +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/gadget.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1892,14 +1892,6 @@ static int __dwc3_cleanup_done_trbs(stru + s_pkt = 1; + } + +- /* +- * We assume here we will always receive the entire data block +- * which we should receive. Meaning, if we program RX to +- * receive 4K but we receive only 2K, we assume that's all we +- * should receive and we simply bounce the request back to the +- * gadget driver for further processing. +- */ +- req->request.actual += req->request.length - count; + if (s_pkt) + return 1; + if ((event->status & DEPEVT_STATUS_LST) && +@@ -1919,6 +1911,7 @@ static int dwc3_cleanup_done_reqs(struct + struct dwc3_trb *trb; + unsigned int slot; + unsigned int i; ++ int count = 0; + int ret; + + do { +@@ -1935,6 +1928,8 @@ static int dwc3_cleanup_done_reqs(struct + slot++; + slot %= DWC3_TRB_NUM; + trb = &dep->trb_pool[slot]; ++ count += trb->size & DWC3_TRB_SIZE_MASK; ++ + + ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, + event, status); +@@ -1942,6 +1937,14 @@ static int dwc3_cleanup_done_reqs(struct + break; + } while (++i < req->request.num_mapped_sgs); + ++ /* ++ * We assume here we will always receive the entire data block ++ * which we should receive. Meaning, if we program RX to ++ * receive 4K but we receive only 2K, we assume that's all we ++ * should receive and we simply bounce the request back to the ++ * gadget driver for further processing. ++ */ ++ req->request.actual += req->request.length - count; + dwc3_gadget_giveback(dep, req, status); + + if (ret) diff --git a/queue-4.4/usb-dwc3-pci-add-intel-kabylake-pci-id.patch b/queue-4.4/usb-dwc3-pci-add-intel-kabylake-pci-id.patch new file mode 100644 index 00000000000..e29cb850c65 --- /dev/null +++ b/queue-4.4/usb-dwc3-pci-add-intel-kabylake-pci-id.patch @@ -0,0 +1,38 @@ +From 4491ed5042f0419b22a4b08331adb54af31e2caa Mon Sep 17 00:00:00 2001 +From: Heikki Krogerus +Date: Fri, 1 Apr 2016 17:13:11 +0300 +Subject: usb: dwc3: pci: add Intel Kabylake PCI ID + +From: Heikki Krogerus + +commit 4491ed5042f0419b22a4b08331adb54af31e2caa upstream. + +Intel Kabylake PCH has the same DWC3 than Intel +Sunrisepoint. Add the new ID to the supported devices. + +Signed-off-by: Heikki Krogerus +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/dwc3-pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -36,6 +36,7 @@ + #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 + #define PCI_DEVICE_ID_INTEL_BXT 0x0aaa + #define PCI_DEVICE_ID_INTEL_APL 0x5aaa ++#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 + + static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; + static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; +@@ -214,6 +215,7 @@ static const struct pci_device_id dwc3_p + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, + { } /* Terminating Entry */ + }; diff --git a/queue-4.4/usb-ehci-change-order-of-register-cleanup-during-shutdown.patch b/queue-4.4/usb-ehci-change-order-of-register-cleanup-during-shutdown.patch new file mode 100644 index 00000000000..1ac6f5683bc --- /dev/null +++ b/queue-4.4/usb-ehci-change-order-of-register-cleanup-during-shutdown.patch @@ -0,0 +1,42 @@ +From bc337b51508beb2d039aff5074a76cfe1c212030 Mon Sep 17 00:00:00 2001 +From: Marc Ohlf +Date: Wed, 3 Aug 2016 11:51:54 +0200 +Subject: usb: ehci: change order of register cleanup during shutdown + +From: Marc Ohlf + +commit bc337b51508beb2d039aff5074a76cfe1c212030 upstream. + +In ehci_turn_off_all_ports() all EHCI port registers are cleared to zero. +On some hardware, this can lead to an system hang, +when ehci_port_power() accesses the already cleared registers. + +This patch changes the order of cleanup. +First call ehci_port_power() which respects the current bits in +port status registers +and afterwards cleanup the hard way by setting everything to zero. + +Signed-off-by: Marc Ohlf +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-hcd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -332,11 +332,11 @@ static void ehci_turn_off_all_ports(stru + int port = HCS_N_PORTS(ehci->hcs_params); + + while (port--) { +- ehci_writel(ehci, PORT_RWC_BITS, +- &ehci->regs->port_status[port]); + spin_unlock_irq(&ehci->lock); + ehci_port_power(ehci, port, false); + spin_lock_irq(&ehci->lock); ++ ehci_writel(ehci, PORT_RWC_BITS, ++ &ehci->regs->port_status[port]); + } + } + diff --git a/queue-4.4/usb-gadget-fix-gadgetfs-aio-support.patch b/queue-4.4/usb-gadget-fix-gadgetfs-aio-support.patch new file mode 100644 index 00000000000..51e4607fa7f --- /dev/null +++ b/queue-4.4/usb-gadget-fix-gadgetfs-aio-support.patch @@ -0,0 +1,31 @@ +From 327b21da884fe1a29f733e41792ddd53e4a30379 Mon Sep 17 00:00:00 2001 +From: Mathieu Laurendeau +Date: Fri, 15 Jul 2016 14:58:41 +0200 +Subject: usb/gadget: fix gadgetfs aio support. + +From: Mathieu Laurendeau + +commit 327b21da884fe1a29f733e41792ddd53e4a30379 upstream. + +Fix io submissions failing with ENODEV. + +Signed-off-by: Mathieu Laurendeau +Fixes: 7fe3976e0f3a ("gadget: switch ep_io_operations to ->read_iter/->write_iter") +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -541,7 +541,7 @@ static ssize_t ep_aio(struct kiocb *iocb + */ + spin_lock_irq(&epdata->dev->lock); + value = -ENODEV; +- if (unlikely(epdata->ep)) ++ if (unlikely(epdata->ep == NULL)) + goto fail; + + req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC); diff --git a/queue-4.4/usb-gadget-fsl_qe_udc-off-by-one-in-setup_received_handle.patch b/queue-4.4/usb-gadget-fsl_qe_udc-off-by-one-in-setup_received_handle.patch new file mode 100644 index 00000000000..88d3171350b --- /dev/null +++ b/queue-4.4/usb-gadget-fsl_qe_udc-off-by-one-in-setup_received_handle.patch @@ -0,0 +1,32 @@ +From 7442e6db5bdd0dce4615205508301f9b22e502d6 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 13 Jul 2016 13:14:33 +0300 +Subject: usb: gadget: fsl_qe_udc: off by one in setup_received_handle() + +From: Dan Carpenter + +commit 7442e6db5bdd0dce4615205508301f9b22e502d6 upstream. + +The udc->eps[] array has USB_MAX_ENDPOINTS elements so > should be >=. + +Fixes: 3948f0e0c999 ('usb: add Freescale QE/CPM USB peripheral controller driver') +Acked-by: Peter Chen +Signed-off-by: Dan Carpenter +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/fsl_qe_udc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/fsl_qe_udc.c ++++ b/drivers/usb/gadget/udc/fsl_qe_udc.c +@@ -2053,7 +2053,7 @@ static void setup_received_handle(struct + struct qe_ep *ep; + + if (wValue != 0 || wLength != 0 +- || pipe > USB_MAX_ENDPOINTS) ++ || pipe >= USB_MAX_ENDPOINTS) + break; + ep = &udc->eps[pipe]; + diff --git a/queue-4.4/usb-hub-change-the-locking-in-hub_activate.patch b/queue-4.4/usb-hub-change-the-locking-in-hub_activate.patch new file mode 100644 index 00000000000..d4fbfe3ced7 --- /dev/null +++ b/queue-4.4/usb-hub-change-the-locking-in-hub_activate.patch @@ -0,0 +1,54 @@ +From 07d316a22e119fa301fd7dba7f1e1adfd4f72c05 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 5 Aug 2016 11:51:30 -0400 +Subject: USB: hub: change the locking in hub_activate + +From: Alan Stern + +commit 07d316a22e119fa301fd7dba7f1e1adfd4f72c05 upstream. + +The locking in hub_activate() is not adequate to provide full mutual +exclusion with hub_quiesce(). The subroutine locks the hub's +usb_interface, but the callers of hub_quiesce() (such as +hub_pre_reset() and hub_event()) hold the lock to the hub's +usb_device. + +This patch changes hub_activate() to make it acquire the same lock as +those other routines. + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1036,7 +1036,7 @@ static void hub_activate(struct usb_hub + + /* Continue a partial initialization */ + if (type == HUB_INIT2 || type == HUB_INIT3) { +- device_lock(hub->intfdev); ++ device_lock(&hdev->dev); + + /* Was the hub disconnected while we were waiting? */ + if (hub->disconnected) +@@ -1243,7 +1243,7 @@ static void hub_activate(struct usb_hub + queue_delayed_work(system_power_efficient_wq, + &hub->init_work, + msecs_to_jiffies(delay)); +- device_unlock(hub->intfdev); ++ device_unlock(&hdev->dev); + return; /* Continues at init3: below */ + } else { + msleep(delay); +@@ -1266,7 +1266,7 @@ static void hub_activate(struct usb_hub + /* Allow autosuspend if it was suppressed */ + disconnected: + usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); +- device_unlock(hub->intfdev); ++ device_unlock(&hdev->dev); + } + + kref_put(&hub->kref, hub_release); diff --git a/queue-4.4/usb-hub-fix-unbalanced-reference-count-memory-leak-deadlocks.patch b/queue-4.4/usb-hub-fix-unbalanced-reference-count-memory-leak-deadlocks.patch new file mode 100644 index 00000000000..9206a8754ee --- /dev/null +++ b/queue-4.4/usb-hub-fix-unbalanced-reference-count-memory-leak-deadlocks.patch @@ -0,0 +1,79 @@ +From 6bb47e8ab98accb1319bd43c64966340ba3bba9a Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Thu, 4 Aug 2016 13:32:22 -0700 +Subject: usb: hub: Fix unbalanced reference count/memory leak/deadlocks + +From: Viresh Kumar + +commit 6bb47e8ab98accb1319bd43c64966340ba3bba9a upstream. + +Memory leak and unbalanced reference count: + +If the hub gets disconnected while the core is still activating it, this +can result in leaking memory of few USB structures. + +This will happen if we have done a kref_get() from hub_activate() and +scheduled a delayed work item for HUB_INIT2/3. Now if hub_disconnect() +gets called before the delayed work expires, then we will cancel the +work from hub_quiesce(), but wouldn't do a kref_put(). And so the +unbalance. + +kmemleak reports this as (with the commit e50293ef9775 backported to +3.10 kernel with other changes, though the same is true for mainline as +well): + +unreferenced object 0xffffffc08af5b800 (size 1024): + comm "khubd", pid 73, jiffies 4295051211 (age 6482.350s) + hex dump (first 32 bytes): + 30 68 f3 8c c0 ff ff ff 00 a0 b2 2e c0 ff ff ff 0h.............. + 01 00 00 00 00 00 00 00 00 94 7d 40 c0 ff ff ff ..........}@.... + backtrace: + [] create_object+0x148/0x2a0 + [] kmemleak_alloc+0x80/0xbc + [] kmem_cache_alloc_trace+0x120/0x1ac + [] hub_probe+0x120/0xb84 + [] usb_probe_interface+0x1ec/0x298 + [] driver_probe_device+0x160/0x374 + [] __device_attach+0x28/0x4c + [] bus_for_each_drv+0x78/0xac + [] device_attach+0x6c/0x9c + [] bus_probe_device+0x28/0xa0 + [] device_add+0x324/0x604 + [] usb_set_configuration+0x660/0x6cc + [] generic_probe+0x44/0x84 + [] usb_probe_device+0x54/0x74 + [] driver_probe_device+0x160/0x374 + [] __device_attach+0x28/0x4c + +Deadlocks: + +If the hub gets disconnected early enough (i.e. before INIT2/INIT3 are +finished and the init_work is still queued), the core may call +hub_quiesce() after acquiring interface device locks and it will wait +for the work to be cancelled synchronously. But if the work handler is +already running in parallel, it may try to acquire the same interface +device lock and this may result in deadlock. + +Fix both the issues by removing the call to cancel_delayed_work_sync(). + +Fixes: e50293ef9775 ("USB: fix invalid memory access in hub_activate()") +Reported-by: Manu Gautam +Signed-off-by: Viresh Kumar +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1299,8 +1299,6 @@ static void hub_quiesce(struct usb_hub * + struct usb_device *hdev = hub->hdev; + int i; + +- cancel_delayed_work_sync(&hub->init_work); +- + /* hub_wq and related activity won't re-trigger */ + hub->quiescing = 1; + diff --git a/queue-4.4/usb-hub-fix-up-early-exit-pathway-in-hub_activate.patch b/queue-4.4/usb-hub-fix-up-early-exit-pathway-in-hub_activate.patch new file mode 100644 index 00000000000..32e70832a63 --- /dev/null +++ b/queue-4.4/usb-hub-fix-up-early-exit-pathway-in-hub_activate.patch @@ -0,0 +1,64 @@ +From ca5cbc8b02f9b21cc8cd1ab36668763ec34f9ee8 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 5 Aug 2016 11:49:45 -0400 +Subject: USB: hub: fix up early-exit pathway in hub_activate + +From: Alan Stern + +commit ca5cbc8b02f9b21cc8cd1ab36668763ec34f9ee8 upstream. + +The early-exit pathway in hub_activate, added by commit e50293ef9775 +("USB: fix invalid memory access in hub_activate()") needs +improvement. It duplicates code that is already present at the end of +the subroutine, and it neglects to undo the effect of a +usb_autopm_get_interface_no_resume() call. + +This patch fixes both problems by making the early-exit pathway jump +directly to the end of the subroutine. It simplifies the code at the +end by merging two conditionals that actually test the same condition +although they appear different: If type < HUB_INIT3 then type must be +either HUB_INIT2 or HUB_INIT, and it can't be HUB_INIT because in that +case the subroutine would have exited earlier. + +Signed-off-by: Alan Stern +Reviewed-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1039,11 +1039,8 @@ static void hub_activate(struct usb_hub + device_lock(hub->intfdev); + + /* Was the hub disconnected while we were waiting? */ +- if (hub->disconnected) { +- device_unlock(hub->intfdev); +- kref_put(&hub->kref, hub_release); +- return; +- } ++ if (hub->disconnected) ++ goto disconnected; + if (type == HUB_INIT2) + goto init2; + goto init3; +@@ -1265,12 +1262,12 @@ static void hub_activate(struct usb_hub + /* Scan all ports that need attention */ + kick_hub_wq(hub); + +- /* Allow autosuspend if it was suppressed */ +- if (type <= HUB_INIT3) ++ if (type == HUB_INIT2 || type == HUB_INIT3) { ++ /* Allow autosuspend if it was suppressed */ ++ disconnected: + usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); +- +- if (type == HUB_INIT2 || type == HUB_INIT3) + device_unlock(hub->intfdev); ++ } + + kref_put(&hub->kref, hub_release); + } diff --git a/queue-4.4/usb-misc-usbtest-add-fix-for-driver-hang.patch b/queue-4.4/usb-misc-usbtest-add-fix-for-driver-hang.patch new file mode 100644 index 00000000000..035ed43142d --- /dev/null +++ b/queue-4.4/usb-misc-usbtest-add-fix-for-driver-hang.patch @@ -0,0 +1,50 @@ +From 539587511835ea12d8daa444cbed766cf2bc3612 Mon Sep 17 00:00:00 2001 +From: Lu Baolu +Date: Thu, 11 Aug 2016 10:31:14 +0800 +Subject: usb: misc: usbtest: add fix for driver hang + +From: Lu Baolu + +commit 539587511835ea12d8daa444cbed766cf2bc3612 upstream. + +In sg_timeout(), req->status is set to "-ETIMEDOUT" before calling +into usb_sg_cancel(). usb_sg_cancel() will do nothing and return +directly if req->status has been set to a non-zero value. This will +cause driver hang whenever transfer time out is triggered. + +This patch fixes this issue. It could be backported to stable kernel +with version later than v3.15. + +Cc: Alan Stern +Signed-off-by: Lu Baolu +Suggested-by: Alan Stern +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/usbtest.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/misc/usbtest.c ++++ b/drivers/usb/misc/usbtest.c +@@ -558,7 +558,6 @@ static void sg_timeout(unsigned long _re + { + struct usb_sg_request *req = (struct usb_sg_request *) _req; + +- req->status = -ETIMEDOUT; + usb_sg_cancel(req); + } + +@@ -589,8 +588,10 @@ static int perform_sglist( + mod_timer(&sg_timer, jiffies + + msecs_to_jiffies(SIMPLE_IO_TIMEOUT)); + usb_sg_wait(req); +- del_timer_sync(&sg_timer); +- retval = req->status; ++ if (!del_timer_sync(&sg_timer)) ++ retval = -ETIMEDOUT; ++ else ++ retval = req->status; + + /* FIXME check resulting data pattern */ + diff --git a/queue-4.4/usb-renesas_usbhs-clear-the-brdysts-in-usbhsg_ep_enable.patch b/queue-4.4/usb-renesas_usbhs-clear-the-brdysts-in-usbhsg_ep_enable.patch new file mode 100644 index 00000000000..2de82a6cbc7 --- /dev/null +++ b/queue-4.4/usb-renesas_usbhs-clear-the-brdysts-in-usbhsg_ep_enable.patch @@ -0,0 +1,52 @@ +From 9ab967e6db7412b675ecbff80d5371d53c82cb2e Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 8 Aug 2016 21:50:52 +0900 +Subject: usb: renesas_usbhs: clear the BRDYSTS in usbhsg_ep_enable() + +From: Yoshihiro Shimoda + +commit 9ab967e6db7412b675ecbff80d5371d53c82cb2e upstream. + +This patch fixes an issue that unexpected BRDY interruption happens +when the usb_ep_{enable,disable}() are called with different direction. +In this case, the driver will cause the following message: + + renesas_usbhs e6590000.usb: irq_ready run_error 1 : -16 + +This issue causes the followings: + 1) A pipe is enabled as transmission + 2) The pipe sent a data + 3) The pipe is disabled and re-enabled as reception. + 4) The pipe got a queue + +Since the driver doesn't clear the BRDYSTS flags after 2) above, the issue +happens. If we add such clearing the flags into the driver, the code will +become complicate. So, this patch clears the BRDYSTS flag of reception in +usbhsg_ep_enable() to avoid complicate. + +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/renesas_usbhs/mod_gadget.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/usb/renesas_usbhs/mod_gadget.c ++++ b/drivers/usb/renesas_usbhs/mod_gadget.c +@@ -618,10 +618,13 @@ static int usbhsg_ep_enable(struct usb_e + * use dmaengine if possible. + * It will use pio handler if impossible. + */ +- if (usb_endpoint_dir_in(desc)) ++ if (usb_endpoint_dir_in(desc)) { + pipe->handler = &usbhs_fifo_dma_push_handler; +- else ++ } else { + pipe->handler = &usbhs_fifo_dma_pop_handler; ++ usbhs_xxxsts_clear(priv, BRDYSTS, ++ usbhs_pipe_number(pipe)); ++ } + + ret = 0; + } diff --git a/queue-4.4/usb-renesas_usbhs-use-dmac-only-if-the-pipe-type-is-bulk.patch b/queue-4.4/usb-renesas_usbhs-use-dmac-only-if-the-pipe-type-is-bulk.patch new file mode 100644 index 00000000000..934aca296d3 --- /dev/null +++ b/queue-4.4/usb-renesas_usbhs-use-dmac-only-if-the-pipe-type-is-bulk.patch @@ -0,0 +1,42 @@ +From 700aa7ff8d2c2b9cc669c99375e2ccd06d3cd38d Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 8 Aug 2016 21:50:53 +0900 +Subject: usb: renesas_usbhs: Use dmac only if the pipe type is bulk + +From: Yoshihiro Shimoda + +commit 700aa7ff8d2c2b9cc669c99375e2ccd06d3cd38d upstream. + +This patch fixes an issue that isochronous transfer's data is possible to +be lost as a workaround. Since this driver uses a workqueue to start +the dmac, the transfer is possible to be delayed when system load is high. + +Fixes: 6e4b74e4690d ("usb: renesas: fix scheduling in atomic context bug") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/renesas_usbhs/fifo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -869,7 +869,7 @@ static int usbhsf_dma_prepare_push(struc + + /* use PIO if packet is less than pio_dma_border or pipe is DCP */ + if ((len < usbhs_get_dparam(priv, pio_dma_border)) || +- usbhs_pipe_is_dcp(pipe)) ++ usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) + goto usbhsf_pio_prepare_push; + + /* check data length if this driver don't use USB-DMAC */ +@@ -974,7 +974,7 @@ static int usbhsf_dma_prepare_pop_with_u + + /* use PIO if packet is less than pio_dma_border or pipe is DCP */ + if ((pkt->length < usbhs_get_dparam(priv, pio_dma_border)) || +- usbhs_pipe_is_dcp(pipe)) ++ usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) + goto usbhsf_pio_prepare_pop; + + fifo = usbhsf_get_dma_fifo(priv, pkt); diff --git a/queue-4.4/usb-serial-fix-memleak-in-driver-registration-error-path.patch b/queue-4.4/usb-serial-fix-memleak-in-driver-registration-error-path.patch new file mode 100644 index 00000000000..d38367e7338 --- /dev/null +++ b/queue-4.4/usb-serial-fix-memleak-in-driver-registration-error-path.patch @@ -0,0 +1,42 @@ +From 647024a7df36014bbc4479d92d88e6b77c0afcf6 Mon Sep 17 00:00:00 2001 +From: Alexey Klimov +Date: Mon, 8 Aug 2016 02:34:46 +0100 +Subject: USB: serial: fix memleak in driver-registration error path + +From: Alexey Klimov + +commit 647024a7df36014bbc4479d92d88e6b77c0afcf6 upstream. + +udriver struct allocated by kzalloc() will not be freed +if usb_register() and next calls fail. This patch fixes this +by adding one more step with kfree(udriver) in error path. + +Signed-off-by: Alexey Klimov +Acked-by: Alan Stern +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/usb-serial.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -1432,7 +1432,7 @@ int usb_serial_register_drivers(struct u + + rc = usb_register(udriver); + if (rc) +- return rc; ++ goto failed_usb_register; + + for (sd = serial_drivers; *sd; ++sd) { + (*sd)->usb_driver = udriver; +@@ -1450,6 +1450,8 @@ int usb_serial_register_drivers(struct u + while (sd-- > serial_drivers) + usb_serial_deregister(*sd); + usb_deregister(udriver); ++failed_usb_register: ++ kfree(udriver); + return rc; + } + EXPORT_SYMBOL_GPL(usb_serial_register_drivers); diff --git a/queue-4.4/usb-serial-ftdi_sio-add-device-id-for-wiced-usb-uart-dev-board.patch b/queue-4.4/usb-serial-ftdi_sio-add-device-id-for-wiced-usb-uart-dev-board.patch new file mode 100644 index 00000000000..c5886a9f9ee --- /dev/null +++ b/queue-4.4/usb-serial-ftdi_sio-add-device-id-for-wiced-usb-uart-dev-board.patch @@ -0,0 +1,50 @@ +From ae34d12cc1e212ffcd92e069030e54dae69c832f Mon Sep 17 00:00:00 2001 +From: "Sheng-Hui J. Chu" +Date: Thu, 28 Jul 2016 17:01:45 -0400 +Subject: USB: serial: ftdi_sio: add device ID for WICED USB UART dev board + +From: Sheng-Hui J. Chu + +commit ae34d12cc1e212ffcd92e069030e54dae69c832f upstream. + +BCM20706V2_EVAL is a WICED dev board designed with FT2232H USB 2.0 +UART/FIFO IC. + +To support BCM920706V2_EVAL dev board for WICED development on Linux. +Add the VID(0a5c) and PID(6422) to ftdi_sio driver to allow loading +ftdi_sio for this board. + +Signed-off-by: Sheng-Hui J. Chu +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 1 + + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ + 2 files changed, 7 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1008,6 +1008,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) }, + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, ++ { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, + { } /* Terminating entry */ + }; + +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -673,6 +673,12 @@ + #define INTREPID_NEOVI_PID 0x0701 + + /* ++ * WICED USB UART ++ */ ++#define WICED_VID 0x0A5C ++#define WICED_USB20706V2_PID 0x6422 ++ ++/* + * Definitions for ID TECH (www.idt-net.com) devices + */ + #define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ diff --git a/queue-4.4/usb-serial-ftdi_sio-add-pids-for-ivium-technologies-devices.patch b/queue-4.4/usb-serial-ftdi_sio-add-pids-for-ivium-technologies-devices.patch new file mode 100644 index 00000000000..98ec4cc2000 --- /dev/null +++ b/queue-4.4/usb-serial-ftdi_sio-add-pids-for-ivium-technologies-devices.patch @@ -0,0 +1,48 @@ +From 6977495c06f7f47636a076ee5a0ca571279d9697 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20Deli=C3=ABn?= +Date: Thu, 28 Jul 2016 18:52:55 +0000 +Subject: USB: serial: ftdi_sio: add PIDs for Ivium Technologies devices + +From: Robert Deliën + +commit 6977495c06f7f47636a076ee5a0ca571279d9697 upstream. + +Ivium Technologies uses the FTDI VID with custom PIDs for their line of +electrochemical interfaces and the PalmSens they developed for PalmSens +BV. + +Signed-off-by: Robert Delien +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 2 ++ + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ + 2 files changed, 8 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -648,6 +648,8 @@ static const struct usb_device_id id_tab + { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_PALMSENS_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_IVIUM_XSTAT_PID) }, + { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, + { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, + { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -406,6 +406,12 @@ + #define FTDI_4N_GALAXY_DE_3_PID 0xF3C2 + + /* ++ * Ivium Technologies product IDs ++ */ ++#define FTDI_PALMSENS_PID 0xf440 ++#define FTDI_IVIUM_XSTAT_PID 0xf441 ++ ++/* + * Linx Technologies product ids + */ + #define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ diff --git a/queue-4.4/usb-serial-option-add-d-link-dwm-156-a3.patch b/queue-4.4/usb-serial-option-add-d-link-dwm-156-a3.patch new file mode 100644 index 00000000000..629a4c6373d --- /dev/null +++ b/queue-4.4/usb-serial-option-add-d-link-dwm-156-a3.patch @@ -0,0 +1,37 @@ +From cf1b18030de29e4e5b0a57695ae5db4a89da0ff7 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Sun, 24 Jul 2016 13:53:30 +0200 +Subject: USB: serial: option: add D-Link DWM-156/A3 + +From: Lubomir Rintel + +commit cf1b18030de29e4e5b0a57695ae5db4a89da0ff7 upstream. + +The device has four interfaces; the three serial ports ought to be +handled by this driver: + +00 Diagnostic interface serial port +01 NMEA device serial port +02 Mass storage (sd card) +03 Modem serial port + +The other product ids listed in the Windows driver are present already. + +Signed-off-by: Lubomir Rintel +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1966,6 +1966,7 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ + { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ + { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, + { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, diff --git a/queue-4.4/usb-serial-option-add-support-for-telit-le920a4.patch b/queue-4.4/usb-serial-option-add-support-for-telit-le920a4.patch new file mode 100644 index 00000000000..08631885207 --- /dev/null +++ b/queue-4.4/usb-serial-option-add-support-for-telit-le920a4.patch @@ -0,0 +1,75 @@ +From 01d7956b58e644ea0d2e8d9340c5727a8fc39d70 Mon Sep 17 00:00:00 2001 +From: Daniele Palmas +Date: Tue, 2 Aug 2016 11:29:25 +0200 +Subject: USB: serial: option: add support for Telit LE920A4 + +From: Daniele Palmas + +commit 01d7956b58e644ea0d2e8d9340c5727a8fc39d70 upstream. + +This patch adds a set of compositions for Telit LE920A4. + +Compositions in short are: + +0x1207: tty + tty +0x1208: tty + adb + tty + tty +0x1211: tty + adb + ecm +0x1212: tty + adb +0x1213: ecm + tty +0x1214: tty + adb + ecm + tty + +telit_le922_blacklist_usbcfg3 is reused for compositions 0x1211 +and 0x1214 due to the same interfaces positions. + +Signed-off-by: Daniele Palmas +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -274,6 +274,12 @@ static void option_instat_callback(struc + #define TELIT_PRODUCT_LE920 0x1200 + #define TELIT_PRODUCT_LE910 0x1201 + #define TELIT_PRODUCT_LE910_USBCFG4 0x1206 ++#define TELIT_PRODUCT_LE920A4_1207 0x1207 ++#define TELIT_PRODUCT_LE920A4_1208 0x1208 ++#define TELIT_PRODUCT_LE920A4_1211 0x1211 ++#define TELIT_PRODUCT_LE920A4_1212 0x1212 ++#define TELIT_PRODUCT_LE920A4_1213 0x1213 ++#define TELIT_PRODUCT_LE920A4_1214 0x1214 + + /* ZTE PRODUCTS */ + #define ZTE_VENDOR_ID 0x19d2 +@@ -628,6 +634,11 @@ static const struct option_blacklist_inf + .reserved = BIT(1) | BIT(5), + }; + ++static const struct option_blacklist_info telit_le920a4_blacklist_1 = { ++ .sendsetup = BIT(0), ++ .reserved = BIT(1), ++}; ++ + static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = { + .sendsetup = BIT(2), + .reserved = BIT(0) | BIT(1) | BIT(3), +@@ -1203,6 +1214,16 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), + .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208), ++ .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211), ++ .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212), ++ .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214), ++ .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, diff --git a/queue-4.4/usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch b/queue-4.4/usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch new file mode 100644 index 00000000000..9ee6516f1b0 --- /dev/null +++ b/queue-4.4/usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch @@ -0,0 +1,123 @@ +From aed9d65ac3278d4febd8665bd7db59ef53e825fe Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 1 Aug 2016 15:25:56 -0400 +Subject: USB: validate wMaxPacketValue entries in endpoint descriptors + +From: Alan Stern + +commit aed9d65ac3278d4febd8665bd7db59ef53e825fe upstream. + +Erroneous or malicious endpoint descriptors may have non-zero bits in +reserved positions, or out-of-bounds values. This patch helps prevent +these from causing problems by bounds-checking the wMaxPacketValue +entries in endpoint descriptors and capping the values at the maximum +allowed. + +This issue was first discovered and tests were conducted by Jake Lamberson +, an intern working for Rosie Hall. + +Signed-off-by: Alan Stern +Reported-by: roswest +Tested-by: roswest +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 66 +++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 63 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -142,6 +142,31 @@ static void usb_parse_ss_endpoint_compan + } + } + ++static const unsigned short low_speed_maxpacket_maxes[4] = { ++ [USB_ENDPOINT_XFER_CONTROL] = 8, ++ [USB_ENDPOINT_XFER_ISOC] = 0, ++ [USB_ENDPOINT_XFER_BULK] = 0, ++ [USB_ENDPOINT_XFER_INT] = 8, ++}; ++static const unsigned short full_speed_maxpacket_maxes[4] = { ++ [USB_ENDPOINT_XFER_CONTROL] = 64, ++ [USB_ENDPOINT_XFER_ISOC] = 1023, ++ [USB_ENDPOINT_XFER_BULK] = 64, ++ [USB_ENDPOINT_XFER_INT] = 64, ++}; ++static const unsigned short high_speed_maxpacket_maxes[4] = { ++ [USB_ENDPOINT_XFER_CONTROL] = 64, ++ [USB_ENDPOINT_XFER_ISOC] = 1024, ++ [USB_ENDPOINT_XFER_BULK] = 512, ++ [USB_ENDPOINT_XFER_INT] = 1023, ++}; ++static const unsigned short super_speed_maxpacket_maxes[4] = { ++ [USB_ENDPOINT_XFER_CONTROL] = 512, ++ [USB_ENDPOINT_XFER_ISOC] = 1024, ++ [USB_ENDPOINT_XFER_BULK] = 1024, ++ [USB_ENDPOINT_XFER_INT] = 1024, ++}; ++ + static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, + int asnum, struct usb_host_interface *ifp, int num_ep, + unsigned char *buffer, int size) +@@ -150,6 +175,8 @@ static int usb_parse_endpoint(struct dev + struct usb_endpoint_descriptor *d; + struct usb_host_endpoint *endpoint; + int n, i, j, retval; ++ unsigned int maxp; ++ const unsigned short *maxpacket_maxes; + + d = (struct usb_endpoint_descriptor *) buffer; + buffer += d->bLength; +@@ -257,6 +284,42 @@ static int usb_parse_endpoint(struct dev + endpoint->desc.wMaxPacketSize = cpu_to_le16(8); + } + ++ /* Validate the wMaxPacketSize field */ ++ maxp = usb_endpoint_maxp(&endpoint->desc); ++ ++ /* Find the highest legal maxpacket size for this endpoint */ ++ i = 0; /* additional transactions per microframe */ ++ switch (to_usb_device(ddev)->speed) { ++ case USB_SPEED_LOW: ++ maxpacket_maxes = low_speed_maxpacket_maxes; ++ break; ++ case USB_SPEED_FULL: ++ maxpacket_maxes = full_speed_maxpacket_maxes; ++ break; ++ case USB_SPEED_HIGH: ++ /* Bits 12..11 are allowed only for HS periodic endpoints */ ++ if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) { ++ i = maxp & (BIT(12) | BIT(11)); ++ maxp &= ~i; ++ } ++ /* fallthrough */ ++ default: ++ maxpacket_maxes = high_speed_maxpacket_maxes; ++ break; ++ case USB_SPEED_SUPER: ++ case USB_SPEED_SUPER_PLUS: ++ maxpacket_maxes = super_speed_maxpacket_maxes; ++ break; ++ } ++ j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)]; ++ ++ if (maxp > j) { ++ dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n", ++ cfgno, inum, asnum, d->bEndpointAddress, maxp, j); ++ maxp = j; ++ endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp); ++ } ++ + /* + * Some buggy high speed devices have bulk endpoints using + * maxpacket sizes other than 512. High speed HCDs may not +@@ -264,9 +327,6 @@ static int usb_parse_endpoint(struct dev + */ + if (to_usb_device(ddev)->speed == USB_SPEED_HIGH + && usb_endpoint_xfer_bulk(d)) { +- unsigned maxp; +- +- maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff; + if (maxp != 512) + dev_warn(ddev, "config %d interface %d altsetting %d " + "bulk endpoint 0x%X has invalid maxpacket %d\n", diff --git a/queue-4.4/usb-xhci-fix-panic-if-disconnect.patch b/queue-4.4/usb-xhci-fix-panic-if-disconnect.patch new file mode 100644 index 00000000000..53950785084 --- /dev/null +++ b/queue-4.4/usb-xhci-fix-panic-if-disconnect.patch @@ -0,0 +1,59 @@ +From 88716a93766b8f095cdef37a8e8f2c93aa233b21 Mon Sep 17 00:00:00 2001 +From: Jim Lin +Date: Tue, 16 Aug 2016 10:18:05 +0300 +Subject: usb: xhci: Fix panic if disconnect + +From: Jim Lin + +commit 88716a93766b8f095cdef37a8e8f2c93aa233b21 upstream. + +After a device is disconnected, xhci_stop_device() will be invoked +in xhci_bus_suspend(). +Also the "disconnect" IRQ will have ISR to invoke +xhci_free_virt_device() in this sequence. +xhci_irq -> xhci_handle_event -> handle_cmd_completion -> +xhci_handle_cmd_disable_slot -> xhci_free_virt_device + +If xhci->devs[slot_id] has been assigned to NULL in +xhci_free_virt_device(), then virt_dev->eps[i].ring in +xhci_stop_device() may point to an invlid address to cause kernel +panic. + +virt_dev = xhci->devs[slot_id]; +: +if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) + +[] Unable to handle kernel paging request at virtual address 00001a68 +[] pgd=ffffffc001430000 +[] [00001a68] *pgd=000000013c807003, *pud=000000013c807003, +*pmd=000000013c808003, *pte=0000000000000000 +[] Internal error: Oops: 96000006 [#1] PREEMPT SMP +[] CPU: 0 PID: 39 Comm: kworker/0:1 Tainted: G U +[] Workqueue: pm pm_runtime_work +[] task: ffffffc0bc0e0bc0 ti: ffffffc0bc0ec000 task.ti: +ffffffc0bc0ec000 +[] PC is at xhci_stop_device.constprop.11+0xb4/0x1a4 + +This issue is found when running with realtek ethernet device +(0bda:8153). + +Signed-off-by: Jim Lin +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -377,6 +377,9 @@ static int xhci_stop_device(struct xhci_ + + ret = 0; + virt_dev = xhci->devs[slot_id]; ++ if (!virt_dev) ++ return -ENODEV; ++ + cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); + if (!cmd) { + xhci_dbg(xhci, "Couldn't allocate command structure.\n"); diff --git a/queue-4.4/xhci-always-handle-command-ring-stopped-events.patch b/queue-4.4/xhci-always-handle-command-ring-stopped-events.patch new file mode 100644 index 00000000000..42d9ec7a2ad --- /dev/null +++ b/queue-4.4/xhci-always-handle-command-ring-stopped-events.patch @@ -0,0 +1,66 @@ +From 33be126510974e2eb9679f1ca9bca4f67ee4c4c7 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Tue, 16 Aug 2016 10:18:03 +0300 +Subject: xhci: always handle "Command Ring Stopped" events + +From: Mathias Nyman + +commit 33be126510974e2eb9679f1ca9bca4f67ee4c4c7 upstream. + +Fix "Command completion event does not match command" errors by always +handling the command ring stopped events. + +The command ring stopped event is generated as a result of aborting +or stopping the command ring with a register write. It is not caused +by a command in the command queue, and thus won't have a matching command +in the comman list. + +Solve it by handling the command ring stopped event before checking for a +matching command. + +In most command time out cases we abort the command ring, and get +a command ring stopped event. The events command pointer will point at +the current command ring dequeue, which in most cases matches the timed +out command in the command list, and no error messages are seen. + +If we instead get a command aborted event before the command ring stopped +event, the abort event will increse the command ring dequeue pointer, and +the following command ring stopped events command pointer will point at the +next, not yet queued command. This case triggered the error message + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1331,12 +1331,6 @@ static void handle_cmd_completion(struct + + cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); + +- if (cmd->command_trb != xhci->cmd_ring->dequeue) { +- xhci_err(xhci, +- "Command completion event does not match command\n"); +- return; +- } +- + del_timer(&xhci->cmd_timer); + + trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event); +@@ -1348,6 +1342,13 @@ static void handle_cmd_completion(struct + xhci_handle_stopped_cmd_ring(xhci, cmd); + return; + } ++ ++ if (cmd->command_trb != xhci->cmd_ring->dequeue) { ++ xhci_err(xhci, ++ "Command completion event does not match command\n"); ++ return; ++ } ++ + /* + * Host aborted the command ring, check if the current command was + * supposed to be aborted, otherwise continue normally. diff --git a/queue-4.4/xhci-don-t-dereference-a-xhci-member-after-removing-xhci.patch b/queue-4.4/xhci-don-t-dereference-a-xhci-member-after-removing-xhci.patch new file mode 100644 index 00000000000..e5692cfb45c --- /dev/null +++ b/queue-4.4/xhci-don-t-dereference-a-xhci-member-after-removing-xhci.patch @@ -0,0 +1,37 @@ +From f1f6d9a8b540df22b87a5bf6bc104edaade81f47 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Tue, 16 Aug 2016 10:18:06 +0300 +Subject: xhci: don't dereference a xhci member after removing xhci + +From: Mathias Nyman + +commit f1f6d9a8b540df22b87a5bf6bc104edaade81f47 upstream. + +Remove the hcd after checking for the xhci last quirks, not before. + +This caused a hang on a Alpine Ridge xhci based maching which remove +the whole xhci controller when unplugging the last usb device + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -311,11 +311,12 @@ static void xhci_pci_remove(struct pci_d + usb_remove_hcd(xhci->shared_hcd); + usb_put_hcd(xhci->shared_hcd); + } +- usb_hcd_pci_remove(dev); + + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(dev, PCI_D3hot); ++ ++ usb_hcd_pci_remove(dev); + } + + #ifdef CONFIG_PM