xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch
xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch
xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch
+usb-host-xhci-update-event-ring-dequeue-pointer-on-purpose.patch
+usb-core-add-endpoint-blacklist-quirk.patch
+usb-quirks-blacklist-duplicate-ep-on-sound-devices-usbpre2.patch
+usb-uas-fix-a-plug-unplug-racing.patch
+usb-fix-novation-sourcecontrol-xl-after-suspend.patch
+usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch
+usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch
+usb-dwc2-fix-set-clear_feature-and-get_status-flows.patch
+usb-dwc3-gadget-check-for-ioc-lst-bit-in-trb-ctrl-fields.patch
+staging-rtl8188eu-fix-potential-security-hole.patch
+staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch
+staging-rtl8723bs-fix-potential-security-hole.patch
+staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch
--- /dev/null
+From 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Mon, 10 Feb 2020 12:02:32 -0600
+Subject: staging: rtl8188eu: Fix potential overuse of kernel memory
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f upstream.
+
+In routine wpa_supplicant_ioctl(), the user-controlled p->length is
+checked to be at least the size of struct ieee_param size, but the code
+does not detect the case where p->length is greater than the size
+of the struct, thus a malicious user could be wasting kernel memory.
+Fixes commit a2c60d42d97c ("Add files for new driver - part 16").
+
+Reported by: Pietro Oliva <pietroliva@gmail.com>
+Cc: Pietro Oliva <pietroliva@gmail.com>
+Cc: Stable <stable@vger.kernel.org>
+Fixes commit a2c60d42d97c ("Add files for new driver - part 16").
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Link: https://lore.kernel.org/r/20200210180235.21691-4-Larry.Finger@lwfinger.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+@@ -2026,7 +2026,7 @@ static int wpa_supplicant_ioctl(struct n
+ struct ieee_param *param;
+ uint ret = 0;
+
+- if (p->length < sizeof(struct ieee_param) || !p->pointer) {
++ if (!p->pointer || p->length != sizeof(struct ieee_param)) {
+ ret = -EINVAL;
+ goto out;
+ }
--- /dev/null
+From 499c405b2b80bb3a04425ba3541d20305e014d3e Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Mon, 10 Feb 2020 12:02:30 -0600
+Subject: staging: rtl8188eu: Fix potential security hole
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 499c405b2b80bb3a04425ba3541d20305e014d3e upstream.
+
+In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed
+to be at least the size of struct ieee_param size, but this assumption is
+never checked. This could result in out-of-bounds read/write on kernel
+heap in case a p->length less than the size of struct ieee_param is
+specified by the user. If p->length is allowed to be greater than the size
+of the struct, then a malicious user could be wasting kernel memory.
+Fixes commit a2c60d42d97c ("Add files for new driver - part 16").
+
+Reported by: Pietro Oliva <pietroliva@gmail.com>
+Cc: Pietro Oliva <pietroliva@gmail.com>
+Cc: Stable <stable@vger.kernel.org>
+Fixes: a2c60d42d97c ("staging: r8188eu: Add files for new driver - part 16")
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Link: https://lore.kernel.org/r/20200210180235.21691-2-Larry.Finger@lwfinger.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+@@ -2819,7 +2819,7 @@ static int rtw_hostapd_ioctl(struct net_
+ goto out;
+ }
+
+- if (!p->pointer) {
++ if (!p->pointer || p->length != sizeof(struct ieee_param)) {
+ ret = -EINVAL;
+ goto out;
+ }
--- /dev/null
+From 23954cb078febfc63a755301fe77e06bccdb4d2a Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Mon, 10 Feb 2020 12:02:33 -0600
+Subject: staging: rtl8723bs: Fix potential overuse of kernel memory
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 23954cb078febfc63a755301fe77e06bccdb4d2a upstream.
+
+In routine wpa_supplicant_ioctl(), the user-controlled p->length is
+checked to be at least the size of struct ieee_param size, but the code
+does not detect the case where p->length is greater than the size
+of the struct, thus a malicious user could be wasting kernel memory.
+Fixes commit 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver").
+
+Reported by: Pietro Oliva <pietroliva@gmail.com>
+Cc: Pietro Oliva <pietroliva@gmail.com>
+Cc: Stable <stable@vger.kernel.org>
+Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver").
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Link: https://lore.kernel.org/r/20200210180235.21691-5-Larry.Finger@lwfinger.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -3400,7 +3400,7 @@ static int wpa_supplicant_ioctl(struct n
+
+ /* down(&ieee->wx_sem); */
+
+- if (p->length < sizeof(struct ieee_param) || !p->pointer) {
++ if (!p->pointer || p->length != sizeof(struct ieee_param)) {
+ ret = -EINVAL;
+ goto out;
+ }
--- /dev/null
+From ac33597c0c0d1d819dccfe001bcd0acef7107e7c Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Mon, 10 Feb 2020 12:02:31 -0600
+Subject: staging: rtl8723bs: Fix potential security hole
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit ac33597c0c0d1d819dccfe001bcd0acef7107e7c upstream.
+
+In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed
+to be at least the size of struct ieee_param size, but this assumption is
+never checked. This could result in out-of-bounds read/write on kernel
+heap in case a p->length less than the size of struct ieee_param is
+specified by the user. If p->length is allowed to be greater than the size
+of the struct, then a malicious user could be wasting kernel memory.
+Fixes commit 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver").
+
+Reported by: Pietro Oliva <pietroliva@gmail.com>
+Cc: Pietro Oliva <pietroliva@gmail.com>
+Cc: Stable <stable@vger.kernel.org>
+Fixes 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver").
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Link: https://lore.kernel.org/r/20200210180235.21691-3-Larry.Finger@lwfinger.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -4236,7 +4236,7 @@ static int rtw_hostapd_ioctl(struct net_
+
+
+ /* if (p->length < sizeof(struct ieee_param) || !p->pointer) { */
+- if (!p->pointer) {
++ if (!p->pointer || p->length != sizeof(*param)) {
+ ret = -EINVAL;
+ goto out;
+ }
--- /dev/null
+From 73f8bda9b5dc1c69df2bc55c0cbb24461a6391a9 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 3 Feb 2020 16:38:28 +0100
+Subject: USB: core: add endpoint-blacklist quirk
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 73f8bda9b5dc1c69df2bc55c0cbb24461a6391a9 upstream.
+
+Add a new device quirk that can be used to blacklist endpoints.
+
+Since commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate
+endpoints") USB core ignores any duplicate endpoints found during
+descriptor parsing.
+
+In order to handle devices where the first interfaces with duplicate
+endpoints are the ones that should have their endpoints ignored, we need
+to add a blacklist.
+
+Tested-by: edes <edes@gmx.net>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20200203153830.26394-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c | 11 +++++++++++
+ drivers/usb/core/quirks.c | 32 ++++++++++++++++++++++++++++++++
+ drivers/usb/core/usb.h | 3 +++
+ include/linux/usb/quirks.h | 3 +++
+ 4 files changed, 49 insertions(+)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -256,6 +256,7 @@ static int usb_parse_endpoint(struct dev
+ struct usb_host_interface *ifp, int num_ep,
+ unsigned char *buffer, int size)
+ {
++ struct usb_device *udev = to_usb_device(ddev);
+ unsigned char *buffer0 = buffer;
+ struct usb_endpoint_descriptor *d;
+ struct usb_host_endpoint *endpoint;
+@@ -297,6 +298,16 @@ static int usb_parse_endpoint(struct dev
+ goto skip_to_next_endpoint_or_interface_descriptor;
+ }
+
++ /* Ignore blacklisted endpoints */
++ if (udev->quirks & USB_QUIRK_ENDPOINT_BLACKLIST) {
++ if (usb_endpoint_is_blacklisted(udev, ifp, d)) {
++ dev_warn(ddev, "config %d interface %d altsetting %d has a blacklisted endpoint with address 0x%X, skipping\n",
++ cfgno, inum, asnum,
++ d->bEndpointAddress);
++ goto skip_to_next_endpoint_or_interface_descriptor;
++ }
++ }
++
+ endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
+ ++ifp->desc.bNumEndpoints;
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -472,6 +472,38 @@ static const struct usb_device_id usb_am
+ { } /* terminating entry must be last */
+ };
+
++/*
++ * Entries for blacklisted endpoints that should be ignored when parsing
++ * configuration descriptors.
++ *
++ * Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST.
++ */
++static const struct usb_device_id usb_endpoint_blacklist[] = {
++ { }
++};
++
++bool usb_endpoint_is_blacklisted(struct usb_device *udev,
++ struct usb_host_interface *intf,
++ struct usb_endpoint_descriptor *epd)
++{
++ const struct usb_device_id *id;
++ unsigned int address;
++
++ for (id = usb_endpoint_blacklist; id->match_flags; ++id) {
++ if (!usb_match_device(udev, id))
++ continue;
++
++ if (!usb_match_one_id_intf(udev, intf, id))
++ continue;
++
++ address = id->driver_info;
++ if (address == epd->bEndpointAddress)
++ return true;
++ }
++
++ return false;
++}
++
+ static bool usb_match_any_interface(struct usb_device *udev,
+ const struct usb_device_id *id)
+ {
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -37,6 +37,9 @@ extern void usb_authorize_interface(stru
+ extern void usb_detect_quirks(struct usb_device *udev);
+ extern void usb_detect_interface_quirks(struct usb_device *udev);
+ extern void usb_release_quirk_list(void);
++extern bool usb_endpoint_is_blacklisted(struct usb_device *udev,
++ struct usb_host_interface *intf,
++ struct usb_endpoint_descriptor *epd);
+ extern int usb_remove_device(struct usb_device *udev);
+
+ extern int usb_get_device_descriptor(struct usb_device *dev,
+--- a/include/linux/usb/quirks.h
++++ b/include/linux/usb/quirks.h
+@@ -69,4 +69,7 @@
+ /* Hub needs extra delay after resetting its port. */
+ #define USB_QUIRK_HUB_SLOW_RESET BIT(14)
+
++/* device has blacklisted endpoints */
++#define USB_QUIRK_ENDPOINT_BLACKLIST BIT(15)
++
+ #endif /* __LINUX_USB_QUIRKS_H */
--- /dev/null
+From 9a0d6f7c0a83844baae1d6d85482863d2bf3b7a7 Mon Sep 17 00:00:00 2001
+From: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
+Date: Tue, 21 Jan 2020 14:17:07 +0400
+Subject: usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows
+
+From: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
+
+commit 9a0d6f7c0a83844baae1d6d85482863d2bf3b7a7 upstream.
+
+SET/CLEAR_FEATURE for Remote Wakeup allowance not handled correctly.
+GET_STATUS handling provided not correct data on DATA Stage.
+Issue seen when gadget's dr_mode set to "otg" mode and connected
+to MacOS.
+Both are fixed and tested using USBCV Ch.9 tests.
+
+Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
+Fixes: fa389a6d7726 ("usb: dwc2: gadget: Add remote_wakeup_allowed flag")
+Tested-by: Jack Mitchell <ml@embed.me.uk>
+Cc: stable@vger.kernel.org
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc2/gadget.c | 28 ++++++++++++++++------------
+ 1 file changed, 16 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/dwc2/gadget.c
++++ b/drivers/usb/dwc2/gadget.c
+@@ -1542,6 +1542,7 @@ static int dwc2_hsotg_process_req_status
+ struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
+ struct dwc2_hsotg_ep *ep;
+ __le16 reply;
++ u16 status;
+ int ret;
+
+ dev_dbg(hsotg->dev, "%s: USB_REQ_GET_STATUS\n", __func__);
+@@ -1553,11 +1554,10 @@ static int dwc2_hsotg_process_req_status
+
+ switch (ctrl->bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+- /*
+- * bit 0 => self powered
+- * bit 1 => remote wakeup
+- */
+- reply = cpu_to_le16(0);
++ status = 1 << USB_DEVICE_SELF_POWERED;
++ status |= hsotg->remote_wakeup_allowed <<
++ USB_DEVICE_REMOTE_WAKEUP;
++ reply = cpu_to_le16(status);
+ break;
+
+ case USB_RECIP_INTERFACE:
+@@ -1668,7 +1668,10 @@ static int dwc2_hsotg_process_req_featur
+ case USB_RECIP_DEVICE:
+ switch (wValue) {
+ case USB_DEVICE_REMOTE_WAKEUP:
+- hsotg->remote_wakeup_allowed = 1;
++ if (set)
++ hsotg->remote_wakeup_allowed = 1;
++ else
++ hsotg->remote_wakeup_allowed = 0;
+ break;
+
+ case USB_DEVICE_TEST_MODE:
+@@ -1678,16 +1681,17 @@ static int dwc2_hsotg_process_req_featur
+ return -EINVAL;
+
+ hsotg->test_mode = wIndex >> 8;
+- ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
+- if (ret) {
+- dev_err(hsotg->dev,
+- "%s: failed to send reply\n", __func__);
+- return ret;
+- }
+ break;
+ default:
+ return -ENOENT;
+ }
++
++ ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
++ if (ret) {
++ dev_err(hsotg->dev,
++ "%s: failed to send reply\n", __func__);
++ return ret;
++ }
+ break;
+
+ case USB_RECIP_ENDPOINT:
--- /dev/null
+From 5ee858975b13a9b40db00f456989a689fdbb296c Mon Sep 17 00:00:00 2001
+From: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
+Date: Mon, 27 Jan 2020 19:30:46 +0000
+Subject: usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields
+
+From: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
+
+commit 5ee858975b13a9b40db00f456989a689fdbb296c upstream.
+
+The current code in dwc3_gadget_ep_reclaim_completed_trb() will
+check for IOC/LST bit in the event->status and returns if
+IOC/LST bit is set. This logic doesn't work if multiple TRBs
+are queued per request and the IOC/LST bit is set on the last
+TRB of that request.
+
+Consider an example where a queued request has multiple queued
+TRBs and IOC/LST bit is set only for the last TRB. In this case,
+the core generates XferComplete/XferInProgress events only for
+the last TRB (since IOC/LST are set only for the last TRB). As
+per the logic in dwc3_gadget_ep_reclaim_completed_trb()
+event->status is checked for IOC/LST bit and returns on the
+first TRB. This leaves the remaining TRBs left unhandled.
+
+Similarly, if the gadget function enqueues an unaligned request
+with sglist already in it, it should fail the same way, since we
+will append another TRB to something that already uses more than
+one TRB.
+
+To aviod this, this patch changes the code to check for IOC/LST
+bits in TRB->ctrl instead.
+
+At a practical level, this patch resolves USB transfer stalls seen
+with adb on dwc3 based HiKey960 after functionfs gadget added
+scatter-gather support around v4.20.
+
+Cc: Felipe Balbi <balbi@kernel.org>
+Cc: Yang Fei <fei.yang@intel.com>
+Cc: Thinh Nguyen <thinhn@synopsys.com>
+Cc: Tejas Joglekar <tejas.joglekar@synopsys.com>
+Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Cc: Jack Pham <jackp@codeaurora.org>
+Cc: Todd Kjos <tkjos@google.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Linux USB List <linux-usb@vger.kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Tested-by: Tejas Joglekar <tejas.joglekar@synopsys.com>
+Reviewed-by: Thinh Nguyen <thinhn@synopsys.com>
+Signed-off-by: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
+[jstultz: forward ported to mainline, reworded commit log, reworked
+ to only check trb->ctrl as suggested by Felipe]
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2224,7 +2224,8 @@ static int dwc3_gadget_ep_reclaim_comple
+ if (event->status & DEPEVT_STATUS_SHORT && !chain)
+ return 1;
+
+- if (event->status & DEPEVT_STATUS_IOC)
++ if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
++ (trb->ctrl & DWC3_TRB_CTRL_LST))
+ return 1;
+
+ return 0;
--- /dev/null
+From b692056db8ecc7f452b934f016c17348282b7699 Mon Sep 17 00:00:00 2001
+From: Richard Dodd <richard.o.dodd@gmail.com>
+Date: Wed, 12 Feb 2020 14:22:18 +0000
+Subject: USB: Fix novation SourceControl XL after suspend
+
+From: Richard Dodd <richard.o.dodd@gmail.com>
+
+commit b692056db8ecc7f452b934f016c17348282b7699 upstream.
+
+Currently, the SourceControl will stay in power-down mode after resuming
+from suspend. This patch resets the device after suspend to power it up.
+
+Signed-off-by: Richard Dodd <richard.o.dodd@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200212142220.36892-1-richard.o.dodd@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -449,6 +449,9 @@ static const struct usb_device_id usb_qu
+ /* INTEL VALUE SSD */
+ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+
++ /* novation SoundControl XL */
++ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ { } /* terminating entry must be last */
+ };
+
--- /dev/null
+From dc0ffbea5729a3abafa577ebfce87f18b79e294b Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Fri, 15 Nov 2019 18:50:00 +0200
+Subject: usb: host: xhci: update event ring dequeue pointer on purpose
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit dc0ffbea5729a3abafa577ebfce87f18b79e294b upstream.
+
+On some situations, the software handles TRB events slower
+than adding TRBs, then xhci_handle_event can't return zero
+long time, the xHC will consider the event ring is full,
+and trigger "Event Ring Full" error, but in fact, the software
+has already finished lots of events, just no chance to
+update ERDP (event ring dequeue pointer).
+
+In this commit, we force update ERDP if half of TRBS_PER_SEGMENT
+events have handled to avoid "Event Ring Full" error.
+
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1573836603-10871-2-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c | 60 ++++++++++++++++++++++++++++++-------------
+ 1 file changed, 43 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2693,6 +2693,42 @@ static int xhci_handle_event(struct xhci
+ }
+
+ /*
++ * Update Event Ring Dequeue Pointer:
++ * - When all events have finished
++ * - To avoid "Event Ring Full Error" condition
++ */
++static void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
++ union xhci_trb *event_ring_deq)
++{
++ u64 temp_64;
++ dma_addr_t deq;
++
++ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
++ /* If necessary, update the HW's version of the event ring deq ptr. */
++ if (event_ring_deq != xhci->event_ring->dequeue) {
++ deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
++ xhci->event_ring->dequeue);
++ if (deq == 0)
++ xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n");
++ /*
++ * Per 4.9.4, Software writes to the ERDP register shall
++ * always advance the Event Ring Dequeue Pointer value.
++ */
++ if ((temp_64 & (u64) ~ERST_PTR_MASK) ==
++ ((u64) deq & (u64) ~ERST_PTR_MASK))
++ return;
++
++ /* Update HC event ring dequeue pointer */
++ temp_64 &= ERST_PTR_MASK;
++ temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK);
++ }
++
++ /* Clear the event handler busy flag (RW1C) */
++ temp_64 |= ERST_EHB;
++ xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
++}
++
++/*
+ * xHCI spec says we can get an interrupt, and if the HC has an error condition,
+ * we might get bad data out of the event ring. Section 4.10.2.7 has a list of
+ * indicators of an event TRB error, but we check the status *first* to be safe.
+@@ -2703,9 +2739,9 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd
+ union xhci_trb *event_ring_deq;
+ irqreturn_t ret = IRQ_NONE;
+ unsigned long flags;
+- dma_addr_t deq;
+ u64 temp_64;
+ u32 status;
++ int event_loop = 0;
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ /* Check if the xHC generated the interrupt, or the irq is shared */
+@@ -2759,24 +2795,14 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd
+ /* FIXME this should be a delayed service routine
+ * that clears the EHB.
+ */
+- while (xhci_handle_event(xhci) > 0) {}
+-
+- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+- /* If necessary, update the HW's version of the event ring deq ptr. */
+- if (event_ring_deq != xhci->event_ring->dequeue) {
+- deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
+- xhci->event_ring->dequeue);
+- if (deq == 0)
+- xhci_warn(xhci, "WARN something wrong with SW event "
+- "ring dequeue ptr.\n");
+- /* Update HC event ring dequeue pointer */
+- temp_64 &= ERST_PTR_MASK;
+- temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK);
++ while (xhci_handle_event(xhci) > 0) {
++ if (event_loop++ < TRBS_PER_SEGMENT / 2)
++ continue;
++ xhci_update_erst_dequeue(xhci, event_ring_deq);
++ event_loop = 0;
+ }
+
+- /* Clear the event handler busy flag (RW1C); event ring is empty. */
+- temp_64 |= ERST_EHB;
+- xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
++ xhci_update_erst_dequeue(xhci, event_ring_deq);
+ ret = IRQ_HANDLED;
+
+ out:
--- /dev/null
+From 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 31 Jan 2020 10:39:26 -0500
+Subject: USB: hub: Don't record a connect-change event during reset-resume
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 upstream.
+
+Paul Zimmerman reports that his USB Bluetooth adapter sometimes
+crashes following system resume, when it receives a
+Get-Device-Descriptor request while it is busy doing something else.
+
+Such a request was added by commit a4f55d8b8c14 ("usb: hub: Check
+device descriptor before resusciation"). It gets sent when the hub
+driver's work thread checks whether a connect-change event on an
+enabled port really indicates a new device has been connected, as
+opposed to an old device momentarily disconnecting and then
+reconnecting (which can happen with xHCI host controllers, since they
+automatically enable connected ports).
+
+The same kind of thing occurs when a port's power session is lost
+during system suspend. When the system wakes up it sees a
+connect-change event on the port, and if the child device's
+persist_enabled flag was set then hub_activate() sets the device's
+reset_resume flag as well as the port's bit in hub->change_bits. The
+reset-resume code then takes responsibility for checking that the same
+device is still attached to the port, and it does this as part of the
+device's resume pathway. By the time the hub driver's work thread
+starts up again, the device has already been fully reinitialized and
+is busy doing its own thing. There's no need for the work thread to
+do the same check a second time, and in fact this unnecessary check is
+what caused the problem that Paul observed.
+
+Note that performing the unnecessary check is not actually a bug.
+Devices are supposed to be able to send descriptors back to the host
+even when they are busy doing something else. The underlying cause of
+Paul's problem lies in his Bluetooth adapter. Nevertheless, we
+shouldn't perform the same check twice in a row -- and as a nice side
+benefit, removing the extra check allows the Bluetooth adapter to work
+more reliably.
+
+The work thread performs its check when it sees that the port's bit is
+set in hub->change_bits. In this situation that bit is interpreted as
+though a connect-change event had occurred on the port _after_ the
+reset-resume, which is not what actually happened.
+
+One possible fix would be to make the reset-resume code clear the
+port's bit in hub->change_bits. But it seems simpler to just avoid
+setting the bit during hub_activate() in the first place. That's what
+this patch does.
+
+(Proving that the patch is correct when CONFIG_PM is disabled requires
+a little thought. In that setting hub_activate() will be called only
+for initialization and resets, since there won't be any resumes or
+reset-resumes. During initialization and hub resets the hub doesn't
+have any child devices, and so this code path never gets executed.)
+
+Reported-and-tested-by: Paul Zimmerman <pauldzim@gmail.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://marc.info/?t=157949360700001&r=1&w=2
+CC: David Heinzelmann <heinzelmann.david@gmail.com>
+CC: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2001311037460.1577-100000@iolanthe.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1190,11 +1190,6 @@ static void hub_activate(struct usb_hub
+ #ifdef CONFIG_PM
+ udev->reset_resume = 1;
+ #endif
+- /* Don't set the change_bits when the device
+- * was powered off.
+- */
+- if (test_bit(port1, hub->power_bits))
+- set_bit(port1, hub->change_bits);
+
+ } else {
+ /* The power session is gone; tell hub_wq */
--- /dev/null
+From 1208f9e1d758c991b0a46a1bd60c616b906bbe27 Mon Sep 17 00:00:00 2001
+From: Hardik Gajjar <hgajjar@de.adit-jv.com>
+Date: Thu, 6 Feb 2020 12:49:23 +0100
+Subject: USB: hub: Fix the broken detection of USB3 device in SMSC hub
+
+From: Hardik Gajjar <hgajjar@de.adit-jv.com>
+
+commit 1208f9e1d758c991b0a46a1bd60c616b906bbe27 upstream.
+
+Renesas R-Car H3ULCB + Kingfisher Infotainment Board is either not able
+to detect the USB3.0 mass storage devices or is detecting those as
+USB2.0 high speed devices.
+
+The explanation given by Renesas is that, due to a HW issue, the XHCI
+driver does not wake up after going to sleep on connecting a USB3.0
+device.
+
+In order to mitigate that, disable the auto-suspend feature
+specifically for SMSC hubs from hub_probe() function, as a quirk.
+
+Renesas Kingfisher Infotainment Board has two USB3.0 ports (CN2) which
+are connected via USB5534B 4-port SuperSpeed/Hi-Speed, low-power,
+configurable hub controller.
+
+[1] SanDisk USB 3.0 device detected as USB-2.0 before the patch
+ [ 74.036390] usb 5-1.1: new high-speed USB device number 4 using xhci-hcd
+ [ 74.061598] usb 5-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00
+ [ 74.069976] usb 5-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+ [ 74.077303] usb 5-1.1: Product: Ultra
+ [ 74.080980] usb 5-1.1: Manufacturer: SanDisk
+ [ 74.085263] usb 5-1.1: SerialNumber: 4C530001110208116550
+
+[2] SanDisk USB 3.0 device detected as USB-3.0 after the patch
+ [ 34.565078] usb 6-1.1: new SuperSpeed Gen 1 USB device number 3 using xhci-hcd
+ [ 34.588719] usb 6-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00
+ [ 34.597098] usb 6-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+ [ 34.604430] usb 6-1.1: Product: Ultra
+ [ 34.608110] usb 6-1.1: Manufacturer: SanDisk
+ [ 34.612397] usb 6-1.1: SerialNumber: 4C530001110208116550
+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Hardik Gajjar <hgajjar@de.adit-jv.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1580989763-32291-1-git-send-email-hgajjar@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 15 +++++++++++++++
+ drivers/usb/core/hub.h | 1 +
+ 2 files changed, 16 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -36,7 +36,9 @@
+ #include "otg_whitelist.h"
+
+ #define USB_VENDOR_GENESYS_LOGIC 0x05e3
++#define USB_VENDOR_SMSC 0x0424
+ #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01
++#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02
+
+ #define USB_TP_TRANSMISSION_DELAY 40 /* ns */
+ #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */
+@@ -1695,6 +1697,10 @@ static void hub_disconnect(struct usb_in
+ kfree(hub->buffer);
+
+ pm_suspend_ignore_children(&intf->dev, false);
++
++ if (hub->quirk_disable_autosuspend)
++ usb_autopm_put_interface(intf);
++
+ kref_put(&hub->kref, hub_release);
+ }
+
+@@ -1825,6 +1831,11 @@ static int hub_probe(struct usb_interfac
+ if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
+ hub->quirk_check_port_auto_suspend = 1;
+
++ if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) {
++ hub->quirk_disable_autosuspend = 1;
++ usb_autopm_get_interface(intf);
++ }
++
+ if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
+ return 0;
+
+@@ -5405,6 +5416,10 @@ out_hdev_lock:
+ }
+
+ static const struct usb_device_id hub_id_table[] = {
++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS,
++ .idVendor = USB_VENDOR_SMSC,
++ .bInterfaceClass = USB_CLASS_HUB,
++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_CLASS,
+ .idVendor = USB_VENDOR_GENESYS_LOGIC,
+--- a/drivers/usb/core/hub.h
++++ b/drivers/usb/core/hub.h
+@@ -61,6 +61,7 @@ struct usb_hub {
+ unsigned quiescing:1;
+ unsigned disconnected:1;
+ unsigned in_reset:1;
++ unsigned quirk_disable_autosuspend:1;
+
+ unsigned quirk_check_port_auto_suspend:1;
+
--- /dev/null
+From bdd1b147b8026df0e4260b387026b251d888ed01 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 3 Feb 2020 16:38:29 +0100
+Subject: USB: quirks: blacklist duplicate ep on Sound Devices USBPre2
+
+From: Johan Hovold <johan@kernel.org>
+
+commit bdd1b147b8026df0e4260b387026b251d888ed01 upstream.
+
+This device has a broken vendor-specific altsetting for interface 1,
+where endpoint 0x85 is declared as an isochronous endpoint despite being
+used by interface 2 for audio capture.
+
+Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 2.00
+ bDeviceClass 239 Miscellaneous Device
+ bDeviceSubClass 2
+ bDeviceProtocol 1 Interface Association
+ bMaxPacketSize0 64
+ idVendor 0x0926
+ idProduct 0x0202
+ bcdDevice 1.00
+ iManufacturer 1 Sound Devices
+ iProduct 2 USBPre2
+ iSerial 3 [...]
+ bNumConfigurations 1
+
+[...]
+
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 1
+ bAlternateSetting 3
+ bNumEndpoints 2
+ bInterfaceClass 255 Vendor Specific Class
+ bInterfaceSubClass 0
+ bInterfaceProtocol 0
+ iInterface 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x85 EP 5 IN
+ bmAttributes 5
+ Transfer Type Isochronous
+ Synch Type Asynchronous
+ Usage Type Data
+ wMaxPacketSize 0x0126 1x 294 bytes
+ bInterval 1
+
+[...]
+
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 2
+ bAlternateSetting 1
+ bNumEndpoints 1
+ bInterfaceClass 1 Audio
+ bInterfaceSubClass 2 Streaming
+ bInterfaceProtocol 0
+ iInterface 0
+ AudioStreaming Interface Descriptor:
+ bLength 7
+ bDescriptorType 36
+ bDescriptorSubtype 1 (AS_GENERAL)
+ bTerminalLink 4
+ bDelay 1 frames
+ wFormatTag 0x0001 PCM
+ AudioStreaming Interface Descriptor:
+ bLength 26
+ bDescriptorType 36
+ bDescriptorSubtype 2 (FORMAT_TYPE)
+ bFormatType 1 (FORMAT_TYPE_I)
+ bNrChannels 2
+ bSubframeSize 2
+ bBitResolution 16
+ bSamFreqType 6 Discrete
+ tSamFreq[ 0] 8000
+ tSamFreq[ 1] 16000
+ tSamFreq[ 2] 24000
+ tSamFreq[ 3] 32000
+ tSamFreq[ 4] 44100
+ tSamFreq[ 5] 48000
+ Endpoint Descriptor:
+ bLength 9
+ bDescriptorType 5
+ bEndpointAddress 0x85 EP 5 IN
+ bmAttributes 5
+ Transfer Type Isochronous
+ Synch Type Asynchronous
+ Usage Type Data
+ wMaxPacketSize 0x0126 1x 294 bytes
+ bInterval 4
+ bRefresh 0
+ bSynchAddress 0
+ AudioStreaming Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 37
+ bDescriptorSubtype 1 (EP_GENERAL)
+ bmAttributes 0x01
+ Sampling Frequency
+ bLockDelayUnits 2 Decoded PCM samples
+ wLockDelay 0x0000
+
+Since commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate
+endpoints") USB core ignores any duplicate endpoints found during
+descriptor parsing, but in this case we need to ignore the first
+instance in order to avoid breaking the audio capture interface.
+
+Fixes: 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints")
+Cc: stable <stable@vger.kernel.org>
+Reported-by: edes <edes@gmx.net>
+Tested-by: edes <edes@gmx.net>
+Link: https://lore.kernel.org/r/20200201105829.5682c887@acme7.acmenet
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20200203153830.26394-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -354,6 +354,10 @@ static const struct usb_device_id usb_qu
+ { USB_DEVICE(0x0904, 0x6103), .driver_info =
+ USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+
++ /* Sound Devices USBPre2 */
++ { USB_DEVICE(0x0926, 0x0202), .driver_info =
++ USB_QUIRK_ENDPOINT_BLACKLIST },
++
+ /* Keytouch QWERTY Panel keyboard */
+ { USB_DEVICE(0x0926, 0x3333), .driver_info =
+ USB_QUIRK_CONFIG_INTF_STRINGS },
+@@ -479,6 +483,7 @@ static const struct usb_device_id usb_am
+ * Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST.
+ */
+ static const struct usb_device_id usb_endpoint_blacklist[] = {
++ { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 },
+ { }
+ };
+
--- /dev/null
+From 3e99862c05a9caa5a27969f41566b428696f5a9a Mon Sep 17 00:00:00 2001
+From: EJ Hsu <ejh@nvidia.com>
+Date: Thu, 30 Jan 2020 01:25:06 -0800
+Subject: usb: uas: fix a plug & unplug racing
+
+From: EJ Hsu <ejh@nvidia.com>
+
+commit 3e99862c05a9caa5a27969f41566b428696f5a9a upstream.
+
+When a uas disk is plugged into an external hub, uas_probe()
+will be called by the hub thread to do the probe. It will
+first create a SCSI host and then do the scan for this host.
+During the scan, it will probe the LUN using SCSI INQUERY command
+which will be packed in the URB and submitted to uas disk.
+
+There might be a chance that this external hub with uas disk
+attached is unplugged during the scan. In this case, uas driver
+will fail to submit the URB (due to the NOTATTACHED state of uas
+device) and try to put this SCSI command back to request queue
+waiting for next chance to run.
+
+In normal case, this cycle will terminate when hub thread gets
+disconnection event and calls into uas_disconnect() accordingly.
+But in this case, uas_disconnect() will not be called because
+hub thread of external hub gets stuck waiting for the completion
+of this SCSI command. A deadlock happened.
+
+In this fix, uas will call scsi_scan_host() asynchronously to
+avoid the blocking of hub thread.
+
+Signed-off-by: EJ Hsu <ejh@nvidia.com>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200130092506.102760-1-ejh@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/uas.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/uas.c
++++ b/drivers/usb/storage/uas.c
+@@ -45,6 +45,7 @@ struct uas_dev_info {
+ struct scsi_cmnd *cmnd[MAX_CMNDS];
+ spinlock_t lock;
+ struct work_struct work;
++ struct work_struct scan_work; /* for async scanning */
+ };
+
+ enum {
+@@ -114,6 +115,17 @@ out:
+ spin_unlock_irqrestore(&devinfo->lock, flags);
+ }
+
++static void uas_scan_work(struct work_struct *work)
++{
++ struct uas_dev_info *devinfo =
++ container_of(work, struct uas_dev_info, scan_work);
++ struct Scsi_Host *shost = usb_get_intfdata(devinfo->intf);
++
++ dev_dbg(&devinfo->intf->dev, "starting scan\n");
++ scsi_scan_host(shost);
++ dev_dbg(&devinfo->intf->dev, "scan complete\n");
++}
++
+ static void uas_add_work(struct uas_cmd_info *cmdinfo)
+ {
+ struct scsi_pointer *scp = (void *)cmdinfo;
+@@ -989,6 +1001,7 @@ static int uas_probe(struct usb_interfac
+ init_usb_anchor(&devinfo->data_urbs);
+ spin_lock_init(&devinfo->lock);
+ INIT_WORK(&devinfo->work, uas_do_work);
++ INIT_WORK(&devinfo->scan_work, uas_scan_work);
+
+ result = uas_configure_endpoints(devinfo);
+ if (result)
+@@ -1005,7 +1018,9 @@ static int uas_probe(struct usb_interfac
+ if (result)
+ goto free_streams;
+
+- scsi_scan_host(shost);
++ /* Submit the delayed_work for SCSI-device scanning */
++ schedule_work(&devinfo->scan_work);
++
+ return result;
+
+ free_streams:
+@@ -1173,6 +1188,12 @@ static void uas_disconnect(struct usb_in
+ usb_kill_anchored_urbs(&devinfo->data_urbs);
+ uas_zap_pending(devinfo, DID_NO_CONNECT);
+
++ /*
++ * Prevent SCSI scanning (if it hasn't started yet)
++ * or wait for the SCSI-scanning routine to stop.
++ */
++ cancel_work_sync(&devinfo->scan_work);
++
+ scsi_remove_host(shost);
+ uas_free_streams(devinfo);
+ scsi_host_put(shost);