]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 14 Mar 2021 12:29:13 +0000 (13:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 14 Mar 2021 12:29:13 +0000 (13:29 +0100)
added patches:
goodix-fingerprint-device-is-not-a-modem.patch
revert-serial-max310x-rework-rx-interrupt-handling.patch
usb-dwc3-qcom-add-acpi-device-id-for-sc8180x.patch
usb-dwc3-qcom-add-missing-dwc3-of-node-refcount-decrement.patch
usb-dwc3-qcom-add-urs-host-support-for-sdm845-acpi-boot.patch
usb-dwc3-qcom-honor-wakeup-enabled-disabled-state.patch
usb-gadget-f_uac1-stop-playback-on-function-disable.patch
usb-gadget-f_uac2-always-increase-endpoint-max_packet_size-by-one-audio-slot.patch
usb-gadget-u_ether-fix-a-configfs-return-code.patch
usb-gadget-udc-s3c2410_udc-fix-return-value-check-in-s3c2410_udc_probe.patch
usb-renesas_usbhs-clear-pipecfg-for-re-enabling-pipe-with-other-epnum.patch
usb-serial-ch341-add-new-product-id.patch
usb-serial-cp210x-add-id-for-acuity-brands-nlight-air-adapter.patch
usb-serial-cp210x-add-some-more-ge-usb-ids.patch
usb-serial-io_edgeport-fix-memory-leak-in-edge_startup.patch
usb-usblp-fix-a-hang-in-poll-if-disconnected.patch
usb-xhci-do-not-perform-soft-retry-for-some-xhci-hosts.patch
usb-xhci-fix-asmedia-asm1042a-and-asm3242-dma-addressing.patch
usbip-fix-stub_dev-to-check-for-stream-socket.patch
usbip-fix-stub_dev-usbip_sockfd_store-races-leading-to-gpf.patch
usbip-fix-vhci_hcd-attach_store-races-leading-to-gpf.patch
usbip-fix-vhci_hcd-to-check-for-stream-socket.patch
usbip-fix-vudc-to-check-for-stream-socket.patch
usbip-fix-vudc-usbip_sockfd_store-races-leading-to-gpf.patch
xhci-fix-repeated-xhci-wake-after-suspend-due-to-uncleared-internal-wake-state.patch
xhci-improve-detection-of-device-initiated-wake-signal.patch

27 files changed:
queue-5.10/goodix-fingerprint-device-is-not-a-modem.patch [new file with mode: 0644]
queue-5.10/revert-serial-max310x-rework-rx-interrupt-handling.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/usb-dwc3-qcom-add-acpi-device-id-for-sc8180x.patch [new file with mode: 0644]
queue-5.10/usb-dwc3-qcom-add-missing-dwc3-of-node-refcount-decrement.patch [new file with mode: 0644]
queue-5.10/usb-dwc3-qcom-add-urs-host-support-for-sdm845-acpi-boot.patch [new file with mode: 0644]
queue-5.10/usb-dwc3-qcom-honor-wakeup-enabled-disabled-state.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_uac1-stop-playback-on-function-disable.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_uac2-always-increase-endpoint-max_packet_size-by-one-audio-slot.patch [new file with mode: 0644]
queue-5.10/usb-gadget-u_ether-fix-a-configfs-return-code.patch [new file with mode: 0644]
queue-5.10/usb-gadget-udc-s3c2410_udc-fix-return-value-check-in-s3c2410_udc_probe.patch [new file with mode: 0644]
queue-5.10/usb-renesas_usbhs-clear-pipecfg-for-re-enabling-pipe-with-other-epnum.patch [new file with mode: 0644]
queue-5.10/usb-serial-ch341-add-new-product-id.patch [new file with mode: 0644]
queue-5.10/usb-serial-cp210x-add-id-for-acuity-brands-nlight-air-adapter.patch [new file with mode: 0644]
queue-5.10/usb-serial-cp210x-add-some-more-ge-usb-ids.patch [new file with mode: 0644]
queue-5.10/usb-serial-io_edgeport-fix-memory-leak-in-edge_startup.patch [new file with mode: 0644]
queue-5.10/usb-usblp-fix-a-hang-in-poll-if-disconnected.patch [new file with mode: 0644]
queue-5.10/usb-xhci-do-not-perform-soft-retry-for-some-xhci-hosts.patch [new file with mode: 0644]
queue-5.10/usb-xhci-fix-asmedia-asm1042a-and-asm3242-dma-addressing.patch [new file with mode: 0644]
queue-5.10/usbip-fix-stub_dev-to-check-for-stream-socket.patch [new file with mode: 0644]
queue-5.10/usbip-fix-stub_dev-usbip_sockfd_store-races-leading-to-gpf.patch [new file with mode: 0644]
queue-5.10/usbip-fix-vhci_hcd-attach_store-races-leading-to-gpf.patch [new file with mode: 0644]
queue-5.10/usbip-fix-vhci_hcd-to-check-for-stream-socket.patch [new file with mode: 0644]
queue-5.10/usbip-fix-vudc-to-check-for-stream-socket.patch [new file with mode: 0644]
queue-5.10/usbip-fix-vudc-usbip_sockfd_store-races-leading-to-gpf.patch [new file with mode: 0644]
queue-5.10/xhci-fix-repeated-xhci-wake-after-suspend-due-to-uncleared-internal-wake-state.patch [new file with mode: 0644]
queue-5.10/xhci-improve-detection-of-device-initiated-wake-signal.patch [new file with mode: 0644]

diff --git a/queue-5.10/goodix-fingerprint-device-is-not-a-modem.patch b/queue-5.10/goodix-fingerprint-device-is-not-a-modem.patch
new file mode 100644 (file)
index 0000000..6858ff1
--- /dev/null
@@ -0,0 +1,41 @@
+From 4d8654e81db7346f915eca9f1aff18f385cab621 Mon Sep 17 00:00:00 2001
+From: Yorick de Wid <ydewid@gmail.com>
+Date: Sat, 13 Feb 2021 15:49:02 +0100
+Subject: Goodix Fingerprint device is not a modem
+
+From: Yorick de Wid <ydewid@gmail.com>
+
+commit 4d8654e81db7346f915eca9f1aff18f385cab621 upstream.
+
+The CDC ACM driver is false matching the Goodix Fingerprint device
+against the USB_CDC_ACM_PROTO_AT_V25TER.
+
+The Goodix Fingerprint device is a biometrics sensor that should be
+handled in user-space. libfprint has some support for Goodix
+fingerprint sensors, although not for this particular one. It is
+possible that the vendor allocates a PID per OEM (Lenovo, Dell etc).
+If this happens to be the case then more devices from the same vendor
+could potentially match the ACM modem module table.
+
+Signed-off-by: Yorick de Wid <ydewid@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210213144901.53199-1-ydewid@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1929,6 +1929,11 @@ static const struct usb_device_id acm_id
+       .driver_info = SEND_ZERO_PACKET,
+       },
++      /* Exclude Goodix Fingerprint Reader */
++      { USB_DEVICE(0x27c6, 0x5395),
++      .driver_info = IGNORE_DEVICE,
++      },
++
+       /* control interfaces without any protocol set */
+       { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
+               USB_CDC_PROTO_NONE) },
diff --git a/queue-5.10/revert-serial-max310x-rework-rx-interrupt-handling.patch b/queue-5.10/revert-serial-max310x-rework-rx-interrupt-handling.patch
new file mode 100644 (file)
index 0000000..7503675
--- /dev/null
@@ -0,0 +1,75 @@
+From 2334de198fed3da72e9785ecdd691d101aa96e77 Mon Sep 17 00:00:00 2001
+From: Alexander Shiyan <shc_work@mail.ru>
+Date: Wed, 17 Feb 2021 11:06:08 +0300
+Subject: Revert "serial: max310x: rework RX interrupt handling"
+
+From: Alexander Shiyan <shc_work@mail.ru>
+
+commit 2334de198fed3da72e9785ecdd691d101aa96e77 upstream.
+
+This reverts commit fce3c5c1a2d9cd888f2987662ce17c0c651916b2.
+
+FIFO is triggered 4 intervals after receiving a byte, it's good
+when we don't care about the time of reception, but are only
+interested in the presence of any activity on the line.
+Unfortunately, this method is not suitable for all tasks,
+for example, the RS-485 protocol will not work properly,
+since the state machine must track the request-response time
+and after the timeout expires, a decision is made that the device
+on the line is not responding.
+
+Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
+Link: https://lore.kernel.org/r/20210217080608.31192-1-shc_work@mail.ru
+Fixes: fce3c5c1a2d9 ("serial: max310x: rework RX interrupt handling")
+Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/max310x.c |   29 +++++------------------------
+ 1 file changed, 5 insertions(+), 24 deletions(-)
+
+--- a/drivers/tty/serial/max310x.c
++++ b/drivers/tty/serial/max310x.c
+@@ -1056,9 +1056,9 @@ static int max310x_startup(struct uart_p
+       max310x_port_update(port, MAX310X_MODE1_REG,
+                           MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
+-      /* Reset FIFOs */
+-      max310x_port_write(port, MAX310X_MODE2_REG,
+-                         MAX310X_MODE2_FIFORST_BIT);
++      /* Configure MODE2 register & Reset FIFOs*/
++      val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT;
++      max310x_port_write(port, MAX310X_MODE2_REG, val);
+       max310x_port_update(port, MAX310X_MODE2_REG,
+                           MAX310X_MODE2_FIFORST_BIT, 0);
+@@ -1086,27 +1086,8 @@ static int max310x_startup(struct uart_p
+       /* Clear IRQ status register */
+       max310x_port_read(port, MAX310X_IRQSTS_REG);
+-      /*
+-       * Let's ask for an interrupt after a timeout equivalent to
+-       * the receiving time of 4 characters after the last character
+-       * has been received.
+-       */
+-      max310x_port_write(port, MAX310X_RXTO_REG, 4);
+-
+-      /*
+-       * Make sure we also get RX interrupts when the RX FIFO is
+-       * filling up quickly, so get an interrupt when half of the RX
+-       * FIFO has been filled in.
+-       */
+-      max310x_port_write(port, MAX310X_FIFOTRIGLVL_REG,
+-                         MAX310X_FIFOTRIGLVL_RX(MAX310X_FIFO_SIZE / 2));
+-
+-      /* Enable RX timeout interrupt in LSR */
+-      max310x_port_write(port, MAX310X_LSR_IRQEN_REG,
+-                         MAX310X_LSR_RXTO_BIT);
+-
+-      /* Enable LSR, RX FIFO trigger, CTS change interrupts */
+-      val = MAX310X_IRQ_LSR_BIT  | MAX310X_IRQ_RXFIFO_BIT | MAX310X_IRQ_TXEMPTY_BIT;
++      /* Enable RX, TX, CTS change interrupts */
++      val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT;
+       max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT);
+       return 0;
index 16828e582f67446d2a2ff0b6a2b26745d3d785d3..0a1f668b6d4a18d2096059ee7c064de355c81068 100644 (file)
@@ -195,3 +195,29 @@ mmc-mmci-add-mmc_cap_need_rsp_busy-for-the-stm32-variants.patch
 mmc-core-fix-partition-switch-time-for-emmc.patch
 mmc-cqhci-fix-random-crash-when-remove-mmc-module-card.patch
 cifs-do-not-send-close-in-compound-create-close-requests.patch
+goodix-fingerprint-device-is-not-a-modem.patch
+usb-gadget-udc-s3c2410_udc-fix-return-value-check-in-s3c2410_udc_probe.patch
+usb-gadget-u_ether-fix-a-configfs-return-code.patch
+usb-gadget-f_uac2-always-increase-endpoint-max_packet_size-by-one-audio-slot.patch
+usb-gadget-f_uac1-stop-playback-on-function-disable.patch
+usb-dwc3-qcom-add-missing-dwc3-of-node-refcount-decrement.patch
+usb-dwc3-qcom-add-urs-host-support-for-sdm845-acpi-boot.patch
+usb-dwc3-qcom-add-acpi-device-id-for-sc8180x.patch
+usb-dwc3-qcom-honor-wakeup-enabled-disabled-state.patch
+usb-usblp-fix-a-hang-in-poll-if-disconnected.patch
+usb-renesas_usbhs-clear-pipecfg-for-re-enabling-pipe-with-other-epnum.patch
+usb-xhci-do-not-perform-soft-retry-for-some-xhci-hosts.patch
+xhci-improve-detection-of-device-initiated-wake-signal.patch
+usb-xhci-fix-asmedia-asm1042a-and-asm3242-dma-addressing.patch
+xhci-fix-repeated-xhci-wake-after-suspend-due-to-uncleared-internal-wake-state.patch
+usb-serial-io_edgeport-fix-memory-leak-in-edge_startup.patch
+usb-serial-ch341-add-new-product-id.patch
+usb-serial-cp210x-add-id-for-acuity-brands-nlight-air-adapter.patch
+usb-serial-cp210x-add-some-more-ge-usb-ids.patch
+usbip-fix-stub_dev-to-check-for-stream-socket.patch
+usbip-fix-vhci_hcd-to-check-for-stream-socket.patch
+usbip-fix-vudc-to-check-for-stream-socket.patch
+usbip-fix-stub_dev-usbip_sockfd_store-races-leading-to-gpf.patch
+usbip-fix-vhci_hcd-attach_store-races-leading-to-gpf.patch
+usbip-fix-vudc-usbip_sockfd_store-races-leading-to-gpf.patch
+revert-serial-max310x-rework-rx-interrupt-handling.patch
diff --git a/queue-5.10/usb-dwc3-qcom-add-acpi-device-id-for-sc8180x.patch b/queue-5.10/usb-dwc3-qcom-add-acpi-device-id-for-sc8180x.patch
new file mode 100644 (file)
index 0000000..10d1035
--- /dev/null
@@ -0,0 +1,32 @@
+From 1edbff9c80ed32071fffa7dbaaea507fdb21ff2d Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Mon, 1 Mar 2021 15:57:45 +0800
+Subject: usb: dwc3: qcom: add ACPI device id for sc8180x
+
+From: Shawn Guo <shawn.guo@linaro.org>
+
+commit 1edbff9c80ed32071fffa7dbaaea507fdb21ff2d upstream.
+
+It enables USB Host support for sc8180x ACPI boot, both the standalone
+one and the one behind URS (USB Role Switch).  And they share the
+the same dwc3_acpi_pdata with sdm845.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Link: https://lore.kernel.org/r/20210301075745.20544-1-shawn.guo@linaro.org
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -935,6 +935,8 @@ static const struct dwc3_acpi_pdata sdm8
+ static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
+       { "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
+       { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata },
++      { "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata },
++      { "QCOM04A6", (unsigned long)&sdm845_acpi_pdata },
+       { },
+ };
+ MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
diff --git a/queue-5.10/usb-dwc3-qcom-add-missing-dwc3-of-node-refcount-decrement.patch b/queue-5.10/usb-dwc3-qcom-add-missing-dwc3-of-node-refcount-decrement.patch
new file mode 100644 (file)
index 0000000..e063898
--- /dev/null
@@ -0,0 +1,49 @@
+From 1cffb1c66499a9db9a735473778abf8427d16287 Mon Sep 17 00:00:00 2001
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Date: Fri, 12 Feb 2021 23:55:19 +0300
+Subject: usb: dwc3: qcom: Add missing DWC3 OF node refcount decrement
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+commit 1cffb1c66499a9db9a735473778abf8427d16287 upstream.
+
+of_get_child_by_name() increments the reference counter of the OF node it
+managed to find. So after the code is done using the device node, the
+refcount must be decremented. Add missing of_node_put() invocation then
+to the dwc3_qcom_of_register_core() method, since DWC3 OF node is being
+used only there.
+
+Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver")
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Link: https://lore.kernel.org/r/20210212205521.14280-1-Sergey.Semin@baikalelectronics.ru
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -639,16 +639,19 @@ static int dwc3_qcom_of_register_core(st
+       ret = of_platform_populate(np, NULL, NULL, dev);
+       if (ret) {
+               dev_err(dev, "failed to register dwc3 core - %d\n", ret);
+-              return ret;
++              goto node_put;
+       }
+       qcom->dwc3 = of_find_device_by_node(dwc3_np);
+       if (!qcom->dwc3) {
++              ret = -ENODEV;
+               dev_err(dev, "failed to get dwc3 platform device\n");
+-              return -ENODEV;
+       }
+-      return 0;
++node_put:
++      of_node_put(dwc3_np);
++
++      return ret;
+ }
+ static int dwc3_qcom_probe(struct platform_device *pdev)
diff --git a/queue-5.10/usb-dwc3-qcom-add-urs-host-support-for-sdm845-acpi-boot.patch b/queue-5.10/usb-dwc3-qcom-add-urs-host-support-for-sdm845-acpi-boot.patch
new file mode 100644 (file)
index 0000000..f432b87
--- /dev/null
@@ -0,0 +1,146 @@
+From c25c210f590e7a37eecd865d84f97d1f40e39786 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Fri, 15 Jan 2021 11:50:57 +0800
+Subject: usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot
+
+From: Shawn Guo <shawn.guo@linaro.org>
+
+commit c25c210f590e7a37eecd865d84f97d1f40e39786 upstream.
+
+For sdm845 ACPI boot, the URS (USB Role Switch) node in ACPI DSDT table
+holds the memory resource, while interrupt resources reside in the child
+nodes USB0 and UFN0.  It adds USB0 host support by probing URS node,
+creating platform device for USB0 node, and then retrieve interrupt
+resources from USB0 platform device.
+
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Link: https://lore.kernel.org/r/20210115035057.10994-1-shawn.guo@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c |   59 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 56 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -60,12 +60,14 @@ struct dwc3_acpi_pdata {
+       int                     dp_hs_phy_irq_index;
+       int                     dm_hs_phy_irq_index;
+       int                     ss_phy_irq_index;
++      bool                    is_urs;
+ };
+ struct dwc3_qcom {
+       struct device           *dev;
+       void __iomem            *qscratch_base;
+       struct platform_device  *dwc3;
++      struct platform_device  *urs_usb;
+       struct clk              **clks;
+       int                     num_clocks;
+       struct reset_control    *resets;
+@@ -429,13 +431,15 @@ static void dwc3_qcom_select_utmi_clk(st
+ static int dwc3_qcom_get_irq(struct platform_device *pdev,
+                            const char *name, int num)
+ {
++      struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
++      struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : pdev;
+       struct device_node *np = pdev->dev.of_node;
+       int ret;
+       if (np)
+-              ret = platform_get_irq_byname(pdev, name);
++              ret = platform_get_irq_byname(pdev_irq, name);
+       else
+-              ret = platform_get_irq(pdev, num);
++              ret = platform_get_irq(pdev_irq, num);
+       return ret;
+ }
+@@ -568,6 +572,8 @@ static int dwc3_qcom_acpi_register_core(
+       struct dwc3_qcom        *qcom = platform_get_drvdata(pdev);
+       struct device           *dev = &pdev->dev;
+       struct resource         *res, *child_res = NULL;
++      struct platform_device  *pdev_irq = qcom->urs_usb ? qcom->urs_usb :
++                                                          pdev;
+       int                     irq;
+       int                     ret;
+@@ -597,7 +603,7 @@ static int dwc3_qcom_acpi_register_core(
+       child_res[0].end = child_res[0].start +
+               qcom->acpi_pdata->dwc3_core_base_size;
+-      irq = platform_get_irq(pdev, 0);
++      irq = platform_get_irq(pdev_irq, 0);
+       child_res[1].flags = IORESOURCE_IRQ;
+       child_res[1].start = child_res[1].end = irq;
+@@ -654,6 +660,33 @@ node_put:
+       return ret;
+ }
++static struct platform_device *
++dwc3_qcom_create_urs_usb_platdev(struct device *dev)
++{
++      struct fwnode_handle *fwh;
++      struct acpi_device *adev;
++      char name[8];
++      int ret;
++      int id;
++
++      /* Figure out device id */
++      ret = sscanf(fwnode_get_name(dev->fwnode), "URS%d", &id);
++      if (!ret)
++              return NULL;
++
++      /* Find the child using name */
++      snprintf(name, sizeof(name), "USB%d", id);
++      fwh = fwnode_get_named_child_node(dev->fwnode, name);
++      if (!fwh)
++              return NULL;
++
++      adev = to_acpi_device_node(fwh);
++      if (!adev)
++              return NULL;
++
++      return acpi_create_platform_device(adev, NULL);
++}
++
+ static int dwc3_qcom_probe(struct platform_device *pdev)
+ {
+       struct device_node      *np = pdev->dev.of_node;
+@@ -718,6 +751,14 @@ static int dwc3_qcom_probe(struct platfo
+                       qcom->acpi_pdata->qscratch_base_offset;
+               parent_res->end = parent_res->start +
+                       qcom->acpi_pdata->qscratch_base_size;
++
++              if (qcom->acpi_pdata->is_urs) {
++                      qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev);
++                      if (!qcom->urs_usb) {
++                              dev_err(dev, "failed to create URS USB platdev\n");
++                              return -ENODEV;
++                      }
++              }
+       }
+       qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
+@@ -880,8 +921,20 @@ static const struct dwc3_acpi_pdata sdm8
+       .ss_phy_irq_index = 2
+ };
++static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = {
++      .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
++      .qscratch_base_size = SDM845_QSCRATCH_SIZE,
++      .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
++      .hs_phy_irq_index = 1,
++      .dp_hs_phy_irq_index = 4,
++      .dm_hs_phy_irq_index = 3,
++      .ss_phy_irq_index = 2,
++      .is_urs = true,
++};
++
+ static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
+       { "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
++      { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata },
+       { },
+ };
+ MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
diff --git a/queue-5.10/usb-dwc3-qcom-honor-wakeup-enabled-disabled-state.patch b/queue-5.10/usb-dwc3-qcom-honor-wakeup-enabled-disabled-state.patch
new file mode 100644 (file)
index 0000000..89af8fe
--- /dev/null
@@ -0,0 +1,48 @@
+From 2664deb0930643149d61cddbb66ada527ae180bd Mon Sep 17 00:00:00 2001
+From: Matthias Kaehlcke <mka@chromium.org>
+Date: Tue, 2 Mar 2021 10:37:03 -0800
+Subject: usb: dwc3: qcom: Honor wakeup enabled/disabled state
+
+From: Matthias Kaehlcke <mka@chromium.org>
+
+commit 2664deb0930643149d61cddbb66ada527ae180bd upstream.
+
+The dwc3-qcom currently enables wakeup interrupts unconditionally
+when suspending, however this should not be done when wakeup is
+disabled (e.g. through the sysfs attribute power/wakeup). Only
+enable wakeup interrupts when device_may_wakeup() returns true.
+
+Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver")
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210302103659.v2.1.I44954d9e1169f2cf5c44e6454d357c75ddfa99a2@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -358,8 +358,10 @@ static int dwc3_qcom_suspend(struct dwc3
+       if (ret)
+               dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
++      if (device_may_wakeup(qcom->dev))
++              dwc3_qcom_enable_interrupts(qcom);
++
+       qcom->is_suspended = true;
+-      dwc3_qcom_enable_interrupts(qcom);
+       return 0;
+ }
+@@ -372,7 +374,8 @@ static int dwc3_qcom_resume(struct dwc3_
+       if (!qcom->is_suspended)
+               return 0;
+-      dwc3_qcom_disable_interrupts(qcom);
++      if (device_may_wakeup(qcom->dev))
++              dwc3_qcom_disable_interrupts(qcom);
+       for (i = 0; i < qcom->num_clocks; i++) {
+               ret = clk_prepare_enable(qcom->clks[i]);
diff --git a/queue-5.10/usb-gadget-f_uac1-stop-playback-on-function-disable.patch b/queue-5.10/usb-gadget-f_uac1-stop-playback-on-function-disable.patch
new file mode 100644 (file)
index 0000000..0ef719b
--- /dev/null
@@ -0,0 +1,32 @@
+From cc2ac63d4cf72104e0e7f58bb846121f0f51bb19 Mon Sep 17 00:00:00 2001
+From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Date: Mon, 1 Mar 2021 13:49:32 +0200
+Subject: usb: gadget: f_uac1: stop playback on function disable
+
+From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+
+commit cc2ac63d4cf72104e0e7f58bb846121f0f51bb19 upstream.
+
+There is missing playback stop/cleanup in case of
+gadget's ->disable callback that happens on
+events like USB host resetting or gadget disconnection
+
+Fixes: 0591bc236015 ("usb: gadget: add f_uac1 variant based on a new u_audio api")
+Cc: <stable@vger.kernel.org> # 4.13+
+Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Link: https://lore.kernel.org/r/1614599375-8803-3-git-send-email-ruslan.bilovol@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_uac1.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/function/f_uac1.c
++++ b/drivers/usb/gadget/function/f_uac1.c
+@@ -499,6 +499,7 @@ static void f_audio_disable(struct usb_f
+       uac1->as_out_alt = 0;
+       uac1->as_in_alt = 0;
++      u_audio_stop_playback(&uac1->g_audio);
+       u_audio_stop_capture(&uac1->g_audio);
+ }
diff --git a/queue-5.10/usb-gadget-f_uac2-always-increase-endpoint-max_packet_size-by-one-audio-slot.patch b/queue-5.10/usb-gadget-f_uac2-always-increase-endpoint-max_packet_size-by-one-audio-slot.patch
new file mode 100644 (file)
index 0000000..9e2c2cb
--- /dev/null
@@ -0,0 +1,48 @@
+From 789ea77310f0200c84002884ffd628e2baf3ad8a Mon Sep 17 00:00:00 2001
+From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Date: Mon, 1 Mar 2021 13:49:31 +0200
+Subject: usb: gadget: f_uac2: always increase endpoint max_packet_size by one audio slot
+
+From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+
+commit 789ea77310f0200c84002884ffd628e2baf3ad8a upstream.
+
+As per UAC2 Audio Data Formats spec (2.3.1.1 USB Packets),
+if the sampling rate is a constant, the allowable variation
+of number of audio slots per virtual frame is +/- 1 audio slot.
+
+It means that endpoint should be able to accept/send +1 audio
+slot.
+
+Previous endpoint max_packet_size calculation code
+was adding sometimes +1 audio slot due to DIV_ROUND_UP
+behaviour which was rounding up to closest integer.
+However this doesn't work if the numbers are divisible.
+
+It had no any impact with Linux hosts which ignore
+this issue, but in case of more strict Windows it
+caused rejected enumeration
+
+Thus always add +1 audio slot to endpoint's max packet size
+
+Fixes: 913e4a90b6f9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth")
+Cc: Peter Chen <peter.chen@freescale.com>
+Cc: <stable@vger.kernel.org> #v4.3+
+Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Link: https://lore.kernel.org/r/1614599375-8803-2-git-send-email-ruslan.bilovol@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_uac2.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_uac2.c
++++ b/drivers/usb/gadget/function/f_uac2.c
+@@ -478,7 +478,7 @@ static int set_ep_max_packet_size(const
+       }
+       max_size_bw = num_channels(chmask) * ssize *
+-              DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
++              ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1);
+       ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
+                                                   max_size_ep));
diff --git a/queue-5.10/usb-gadget-u_ether-fix-a-configfs-return-code.patch b/queue-5.10/usb-gadget-u_ether-fix-a-configfs-return-code.patch
new file mode 100644 (file)
index 0000000..285580c
--- /dev/null
@@ -0,0 +1,38 @@
+From 650bf52208d804ad5ee449c58102f8dc43175573 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 15 Feb 2021 15:57:16 +0000
+Subject: USB: gadget: u_ether: Fix a configfs return code
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 650bf52208d804ad5ee449c58102f8dc43175573 upstream.
+
+If the string is invalid, this should return -EINVAL instead of 0.
+
+Fixes: 73517cf49bd4 ("usb: gadget: add RNDIS configfs options for class/subclass/protocol")
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Lorenzo Colitti <lorenzo@google.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YCqZ3P53yyIg5cn7@mwanda
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/u_ether_configfs.h |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/function/u_ether_configfs.h
++++ b/drivers/usb/gadget/function/u_ether_configfs.h
+@@ -169,12 +169,11 @@ out:                                                                     \
+                                               size_t len)             \
+       {                                                               \
+               struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
+-              int ret;                                                \
++              int ret = -EINVAL;                                      \
+               u8 val;                                                 \
+                                                                       \
+               mutex_lock(&opts->lock);                                \
+-              ret = sscanf(page, "%02hhx", &val);                     \
+-              if (ret > 0) {                                          \
++              if (sscanf(page, "%02hhx", &val) > 0) {                 \
+                       opts->_n_ = val;                                \
+                       ret = len;                                      \
+               }                                                       \
diff --git a/queue-5.10/usb-gadget-udc-s3c2410_udc-fix-return-value-check-in-s3c2410_udc_probe.patch b/queue-5.10/usb-gadget-udc-s3c2410_udc-fix-return-value-check-in-s3c2410_udc_probe.patch
new file mode 100644 (file)
index 0000000..9654b20
--- /dev/null
@@ -0,0 +1,38 @@
+From 414c20df7d401bcf1cb6c13d2dd944fb53ae4acf Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Fri, 5 Mar 2021 03:49:27 +0000
+Subject: USB: gadget: udc: s3c2410_udc: fix return value check in s3c2410_udc_probe()
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+commit 414c20df7d401bcf1cb6c13d2dd944fb53ae4acf upstream.
+
+In case of error, the function devm_platform_ioremap_resource()
+returns ERR_PTR() and never returns NULL. The NULL test in the
+return value check should be replaced with IS_ERR().
+
+Fixes: 188db4435ac6 ("usb: gadget: s3c: use platform resources")
+Cc: stable <stable@vger.kernel.org>
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Link: https://lore.kernel.org/r/20210305034927.3232386-1-weiyongjun1@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/s3c2410_udc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/udc/s3c2410_udc.c
++++ b/drivers/usb/gadget/udc/s3c2410_udc.c
+@@ -1773,8 +1773,8 @@ static int s3c2410_udc_probe(struct plat
+       udc_info = dev_get_platdata(&pdev->dev);
+       base_addr = devm_platform_ioremap_resource(pdev, 0);
+-      if (!base_addr) {
+-              retval = -ENOMEM;
++      if (IS_ERR(base_addr)) {
++              retval = PTR_ERR(base_addr);
+               goto err_mem;
+       }
diff --git a/queue-5.10/usb-renesas_usbhs-clear-pipecfg-for-re-enabling-pipe-with-other-epnum.patch b/queue-5.10/usb-renesas_usbhs-clear-pipecfg-for-re-enabling-pipe-with-other-epnum.patch
new file mode 100644 (file)
index 0000000..1376eca
--- /dev/null
@@ -0,0 +1,47 @@
+From b1d25e6ee57c2605845595b6c61340d734253eb3 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Mon, 8 Mar 2021 10:55:38 +0900
+Subject: usb: renesas_usbhs: Clear PIPECFG for re-enabling pipe with other EPNUM
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit b1d25e6ee57c2605845595b6c61340d734253eb3 upstream.
+
+According to the datasheet, this controller has a restriction
+which "set an endpoint number so that combinations of the DIR bit and
+the EPNUM bits do not overlap.". However, since the udc core driver is
+possible to assign a bulk pipe as an interrupt endpoint, an endpoint
+number may not match the pipe number. After that, when user rebinds
+another gadget driver, this driver broke the restriction because
+the driver didn't clear any configuration in usb_ep_disable().
+
+Example:
+ # modprobe g_ncm
+ Then, EP3 = pipe 3, EP4 = pipe 4, EP5 = pipe 6
+ # rmmod g_ncm
+ # modprobe g_hid
+ Then, EP3 = pipe 6, EP4 = pipe 7.
+ So, pipe 3 and pipe 6 are set as EP3.
+
+So, clear PIPECFG register in usbhs_pipe_free().
+
+Fixes: dfb87b8bfe09 ("usb: renesas_usbhs: gadget: fix re-enabling pipe without re-connecting")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/1615168538-26101-1-git-send-email-yoshihiro.shimoda.uh@renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/renesas_usbhs/pipe.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/renesas_usbhs/pipe.c
++++ b/drivers/usb/renesas_usbhs/pipe.c
+@@ -746,6 +746,8 @@ struct usbhs_pipe *usbhs_pipe_malloc(str
+ void usbhs_pipe_free(struct usbhs_pipe *pipe)
+ {
++      usbhsp_pipe_select(pipe);
++      usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0);
+       usbhsp_put_pipe(pipe);
+ }
diff --git a/queue-5.10/usb-serial-ch341-add-new-product-id.patch b/queue-5.10/usb-serial-ch341-add-new-product-id.patch
new file mode 100644 (file)
index 0000000..d5d10e1
--- /dev/null
@@ -0,0 +1,103 @@
+From 5563b3b6420362c8a1f468ca04afe6d5f0a8d0a3 Mon Sep 17 00:00:00 2001
+From: Niv Sardi <xaiki@evilgiggle.com>
+Date: Mon, 1 Mar 2021 17:16:12 -0300
+Subject: USB: serial: ch341: add new Product ID
+
+From: Niv Sardi <xaiki@evilgiggle.com>
+
+commit 5563b3b6420362c8a1f468ca04afe6d5f0a8d0a3 upstream.
+
+Add PID for CH340 that's found on cheap programmers.
+
+The driver works flawlessly as soon as the new PID (0x9986) is added to it.
+These look like ANU232MI but ship with a ch341 inside. They have no special
+identifiers (mine only has the string "DB9D20130716" printed on the PCB and
+nothing identifiable on the packaging. The merchant i bought it from
+doesn't sell these anymore).
+
+the lsusb -v output is:
+Bus 001 Device 009: ID 9986:7523
+Device Descriptor:
+  bLength                18
+  bDescriptorType         1
+  bcdUSB               1.10
+  bDeviceClass          255 Vendor Specific Class
+  bDeviceSubClass         0
+  bDeviceProtocol         0
+  bMaxPacketSize0         8
+  idVendor           0x9986
+  idProduct          0x7523
+  bcdDevice            2.54
+  iManufacturer           0
+  iProduct                0
+  iSerial                 0
+  bNumConfigurations      1
+  Configuration Descriptor:
+    bLength                 9
+    bDescriptorType         2
+    wTotalLength       0x0027
+    bNumInterfaces          1
+    bConfigurationValue     1
+    iConfiguration          0
+    bmAttributes         0x80
+      (Bus Powered)
+    MaxPower               96mA
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        0
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      1
+      bInterfaceProtocol      2
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x82  EP 2 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0020  1x 32 bytes
+        bInterval               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x02  EP 2 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0020  1x 32 bytes
+        bInterval               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x81  EP 1 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0008  1x 8 bytes
+        bInterval               1
+
+Signed-off-by: Niv Sardi <xaiki@evilgiggle.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/ch341.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/ch341.c
++++ b/drivers/usb/serial/ch341.c
+@@ -86,6 +86,7 @@ static const struct usb_device_id id_tab
+       { USB_DEVICE(0x1a86, 0x7522) },
+       { USB_DEVICE(0x1a86, 0x7523) },
+       { USB_DEVICE(0x4348, 0x5523) },
++      { USB_DEVICE(0x9986, 0x7523) },
+       { },
+ };
+ MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/queue-5.10/usb-serial-cp210x-add-id-for-acuity-brands-nlight-air-adapter.patch b/queue-5.10/usb-serial-cp210x-add-id-for-acuity-brands-nlight-air-adapter.patch
new file mode 100644 (file)
index 0000000..86dd9cd
--- /dev/null
@@ -0,0 +1,31 @@
+From ca667a33207daeaf9c62b106815728718def60ec Mon Sep 17 00:00:00 2001
+From: Karan Singhal <karan.singhal@acuitybrands.com>
+Date: Tue, 16 Feb 2021 11:03:10 -0500
+Subject: USB: serial: cp210x: add ID for Acuity Brands nLight Air Adapter
+
+From: Karan Singhal <karan.singhal@acuitybrands.com>
+
+commit ca667a33207daeaf9c62b106815728718def60ec upstream.
+
+IDs of nLight Air Adapter, Acuity Brands, Inc.:
+vid: 10c4
+pid: 88d8
+
+Signed-off-by: Karan Singhal <karan.singhal@acuitybrands.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/cp210x.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -149,6 +149,7 @@ static const struct usb_device_id id_tab
+       { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */
+       { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
+       { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
++      { USB_DEVICE(0x10C4, 0x88D8) }, /* Acuity Brands nLight Air Adapter */
+       { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */
+       { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */
+       { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
diff --git a/queue-5.10/usb-serial-cp210x-add-some-more-ge-usb-ids.patch b/queue-5.10/usb-serial-cp210x-add-some-more-ge-usb-ids.patch
new file mode 100644 (file)
index 0000000..12e8902
--- /dev/null
@@ -0,0 +1,31 @@
+From 42213a0190b535093a604945db05a4225bf43885 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 23 Feb 2021 17:44:18 +0100
+Subject: USB: serial: cp210x: add some more GE USB IDs
+
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+
+commit 42213a0190b535093a604945db05a4225bf43885 upstream.
+
+GE CS1000 has some more custom USB IDs for CP2102N; add them
+to the driver to have working auto-probing.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/cp210x.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -206,6 +206,8 @@ static const struct usb_device_id id_tab
+       { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
+       { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
+       { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
++      { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 Display serial interface */
++      { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */
+       { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */
+       { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
+       { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
diff --git a/queue-5.10/usb-serial-io_edgeport-fix-memory-leak-in-edge_startup.patch b/queue-5.10/usb-serial-io_edgeport-fix-memory-leak-in-edge_startup.patch
new file mode 100644 (file)
index 0000000..9873366
--- /dev/null
@@ -0,0 +1,68 @@
+From cfdc67acc785e01a8719eeb7012709d245564701 Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Tue, 2 Mar 2021 02:01:52 +0300
+Subject: USB: serial: io_edgeport: fix memory leak in edge_startup
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit cfdc67acc785e01a8719eeb7012709d245564701 upstream.
+
+sysbot found memory leak in edge_startup().
+The problem was that when an error was received from the usb_submit_urb(),
+nothing was cleaned up.
+
+Reported-by: syzbot+59f777bdcbdd7eea5305@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver")
+Cc: stable@vger.kernel.org     # 2.6.21: c5c0c55598ce
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/io_edgeport.c |   26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -3003,26 +3003,32 @@ static int edge_startup(struct usb_seria
+                               response = -ENODEV;
+                       }
+-                      usb_free_urb(edge_serial->interrupt_read_urb);
+-                      kfree(edge_serial->interrupt_in_buffer);
+-
+-                      usb_free_urb(edge_serial->read_urb);
+-                      kfree(edge_serial->bulk_in_buffer);
+-
+-                      kfree(edge_serial);
+-
+-                      return response;
++                      goto error;
+               }
+               /* start interrupt read for this edgeport this interrupt will
+                * continue as long as the edgeport is connected */
+               response = usb_submit_urb(edge_serial->interrupt_read_urb,
+                                                               GFP_KERNEL);
+-              if (response)
++              if (response) {
+                       dev_err(ddev, "%s - Error %d submitting control urb\n",
+                               __func__, response);
++
++                      goto error;
++              }
+       }
+       return response;
++
++error:
++      usb_free_urb(edge_serial->interrupt_read_urb);
++      kfree(edge_serial->interrupt_in_buffer);
++
++      usb_free_urb(edge_serial->read_urb);
++      kfree(edge_serial->bulk_in_buffer);
++
++      kfree(edge_serial);
++
++      return response;
+ }
diff --git a/queue-5.10/usb-usblp-fix-a-hang-in-poll-if-disconnected.patch b/queue-5.10/usb-usblp-fix-a-hang-in-poll-if-disconnected.patch
new file mode 100644 (file)
index 0000000..aac8ae6
--- /dev/null
@@ -0,0 +1,61 @@
+From 9de2c43acf37a17dc4c69ff78bb099b80fb74325 Mon Sep 17 00:00:00 2001
+From: Pete Zaitcev <zaitcev@redhat.com>
+Date: Wed, 3 Mar 2021 22:10:53 -0600
+Subject: USB: usblp: fix a hang in poll() if disconnected
+
+From: Pete Zaitcev <zaitcev@redhat.com>
+
+commit 9de2c43acf37a17dc4c69ff78bb099b80fb74325 upstream.
+
+Apparently an application that opens a device and calls select()
+on it, will hang if the decice is disconnected. It's a little
+surprising that we had this bug for 15 years, but apparently
+nobody ever uses select() with a printer: only write() and read(),
+and those work fine. Well, you can also select() with a timeout.
+
+The fix is modeled after devio.c. A few other drivers check the
+condition first, then do not add the wait queue in case the
+device is disconnected. We doubt that's completely race-free.
+So, this patch adds the process first, then locks properly
+and checks for the disconnect.
+
+Reviewed-by: Zqiang <qiang.zhang@windriver.com>
+Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210303221053.1cf3313e@suzdal.zaitcev.lan
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/usblp.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/class/usblp.c
++++ b/drivers/usb/class/usblp.c
+@@ -494,16 +494,24 @@ static int usblp_release(struct inode *i
+ /* No kernel lock - fine */
+ static __poll_t usblp_poll(struct file *file, struct poll_table_struct *wait)
+ {
+-      __poll_t ret;
++      struct usblp *usblp = file->private_data;
++      __poll_t ret = 0;
+       unsigned long flags;
+-      struct usblp *usblp = file->private_data;
+       /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */
+       poll_wait(file, &usblp->rwait, wait);
+       poll_wait(file, &usblp->wwait, wait);
++
++      mutex_lock(&usblp->mut);
++      if (!usblp->present)
++              ret |= EPOLLHUP;
++      mutex_unlock(&usblp->mut);
++
+       spin_lock_irqsave(&usblp->lock, flags);
+-      ret = ((usblp->bidir && usblp->rcomplete) ? EPOLLIN  | EPOLLRDNORM : 0) |
+-         ((usblp->no_paper || usblp->wcomplete) ? EPOLLOUT | EPOLLWRNORM : 0);
++      if (usblp->bidir && usblp->rcomplete)
++              ret |= EPOLLIN  | EPOLLRDNORM;
++      if (usblp->no_paper || usblp->wcomplete)
++              ret |= EPOLLOUT | EPOLLWRNORM;
+       spin_unlock_irqrestore(&usblp->lock, flags);
+       return ret;
+ }
diff --git a/queue-5.10/usb-xhci-do-not-perform-soft-retry-for-some-xhci-hosts.patch b/queue-5.10/usb-xhci-do-not-perform-soft-retry-for-some-xhci-hosts.patch
new file mode 100644 (file)
index 0000000..f534156
--- /dev/null
@@ -0,0 +1,75 @@
+From a4a251f8c23518899d2078c320cf9ce2fa459c9f Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <stf_xl@wp.pl>
+Date: Thu, 11 Mar 2021 13:53:50 +0200
+Subject: usb: xhci: do not perform Soft Retry for some xHCI hosts
+
+From: Stanislaw Gruszka <stf_xl@wp.pl>
+
+commit a4a251f8c23518899d2078c320cf9ce2fa459c9f upstream.
+
+On some systems rt2800usb and mt7601u devices are unable to operate since
+commit f8f80be501aa ("xhci: Use soft retry to recover faster from
+transaction errors")
+
+Seems that some xHCI controllers can not perform Soft Retry correctly,
+affecting those devices.
+
+To avoid the problem add xhci->quirks flag that restore pre soft retry
+xhci behaviour for affected xHCI controllers. Currently those are
+AMD_PROMONTORYA_4 and AMD_PROMONTORYA_2, since it was confirmed
+by the users: on those xHCI hosts issue happen and is gone after
+disabling Soft Retry.
+
+[minor commit message rewording for checkpatch -Mathias]
+
+Fixes: f8f80be501aa ("xhci: Use soft retry to recover faster from transaction errors")
+Cc: <stable@vger.kernel.org> # 4.20+
+Reported-by: Bernhard <bernhard.gebetsberger@gmx.at>
+Tested-by: Bernhard <bernhard.gebetsberger@gmx.at>
+Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202541
+Link: https://lore.kernel.org/r/20210311115353.2137560-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci.c  |    5 +++++
+ drivers/usb/host/xhci-ring.c |    3 ++-
+ drivers/usb/host/xhci.h      |    1 +
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -295,6 +295,11 @@ static void xhci_pci_quirks(struct devic
+            pdev->device == 0x9026)
+               xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT;
++      if (pdev->vendor == PCI_VENDOR_ID_AMD &&
++          (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2 ||
++           pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
++              xhci->quirks |= XHCI_NO_SOFT_RETRY;
++
+       if (xhci->quirks & XHCI_RESET_ON_RESUME)
+               xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+                               "QUIRK: Resetting on resume");
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2307,7 +2307,8 @@ static int process_bulk_intr_td(struct x
+               remaining       = 0;
+               break;
+       case COMP_USB_TRANSACTION_ERROR:
+-              if ((ep_ring->err_count++ > MAX_SOFT_RETRY) ||
++              if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
++                  (ep_ring->err_count++ > MAX_SOFT_RETRY) ||
+                   le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
+                       break;
+               *status = 0;
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1879,6 +1879,7 @@ struct xhci_hcd {
+ #define XHCI_SKIP_PHY_INIT    BIT_ULL(37)
+ #define XHCI_DISABLE_SPARSE   BIT_ULL(38)
+ #define XHCI_SG_TRB_CACHE_SIZE_QUIRK  BIT_ULL(39)
++#define XHCI_NO_SOFT_RETRY    BIT_ULL(40)
+       unsigned int            num_active_eps;
+       unsigned int            limit_active_eps;
diff --git a/queue-5.10/usb-xhci-fix-asmedia-asm1042a-and-asm3242-dma-addressing.patch b/queue-5.10/usb-xhci-fix-asmedia-asm1042a-and-asm3242-dma-addressing.patch
new file mode 100644 (file)
index 0000000..889a855
--- /dev/null
@@ -0,0 +1,51 @@
+From b71c669ad8390dd1c866298319ff89fe68b45653 Mon Sep 17 00:00:00 2001
+From: Forest Crossman <cyrozap@gmail.com>
+Date: Thu, 11 Mar 2021 13:53:52 +0200
+Subject: usb: xhci: Fix ASMedia ASM1042A and ASM3242 DMA addressing
+
+From: Forest Crossman <cyrozap@gmail.com>
+
+commit b71c669ad8390dd1c866298319ff89fe68b45653 upstream.
+
+I've confirmed that both the ASMedia ASM1042A and ASM3242 have the same
+problem as the ASM1142 and ASM2142/ASM3142, where they lose some of the
+upper bits of 64-bit DMA addresses. As with the other chips, this can
+cause problems on systems where the upper bits matter, and adding the
+XHCI_NO_64BIT_SUPPORT quirk completely fixes the issue.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Forest Crossman <cyrozap@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210311115353.2137560-4-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -66,6 +66,7 @@
+ #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI              0x1142
+ #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI                       0x1242
+ #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI                       0x2142
++#define PCI_DEVICE_ID_ASMEDIA_3242_XHCI                       0x3242
+ static const char hcd_name[] = "xhci_hcd";
+@@ -276,11 +277,14 @@ static void xhci_pci_quirks(struct devic
+               pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
+               xhci->quirks |= XHCI_BROKEN_STREAMS;
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+-              pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
++              pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
++              xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
++      }
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+           (pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI ||
+-           pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI))
++           pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI ||
++           pdev->device == PCI_DEVICE_ID_ASMEDIA_3242_XHCI))
+               xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
diff --git a/queue-5.10/usbip-fix-stub_dev-to-check-for-stream-socket.patch b/queue-5.10/usbip-fix-stub_dev-to-check-for-stream-socket.patch
new file mode 100644 (file)
index 0000000..8de40f9
--- /dev/null
@@ -0,0 +1,51 @@
+From 47ccc8fc2c9c94558b27b6f9e2582df32d29e6e8 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Sun, 7 Mar 2021 20:53:26 -0700
+Subject: usbip: fix stub_dev to check for stream socket
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 47ccc8fc2c9c94558b27b6f9e2582df32d29e6e8 upstream.
+
+Fix usbip_sockfd_store() to validate the passed in file descriptor is
+a stream socket. If the file descriptor passed was a SOCK_DGRAM socket,
+sock_recvmsg() can't detect end of stream.
+
+Cc: stable@vger.kernel.org
+Suggested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/e942d2bd03afb8e8552bd2a5d84e18d17670d521.1615171203.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/stub_dev.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -69,8 +69,16 @@ static ssize_t usbip_sockfd_store(struct
+               }
+               socket = sockfd_lookup(sockfd, &err);
+-              if (!socket)
++              if (!socket) {
++                      dev_err(dev, "failed to lookup sock");
+                       goto err;
++              }
++
++              if (socket->type != SOCK_STREAM) {
++                      dev_err(dev, "Expecting SOCK_STREAM - found %d",
++                              socket->type);
++                      goto sock_err;
++              }
+               sdev->ud.tcp_socket = socket;
+               sdev->ud.sockfd = sockfd;
+@@ -100,6 +108,8 @@ static ssize_t usbip_sockfd_store(struct
+       return count;
++sock_err:
++      sockfd_put(socket);
+ err:
+       spin_unlock_irq(&sdev->ud.lock);
+       return -EINVAL;
diff --git a/queue-5.10/usbip-fix-stub_dev-usbip_sockfd_store-races-leading-to-gpf.patch b/queue-5.10/usbip-fix-stub_dev-usbip_sockfd_store-races-leading-to-gpf.patch
new file mode 100644 (file)
index 0000000..0f9035b
--- /dev/null
@@ -0,0 +1,134 @@
+From 9380afd6df70e24eacbdbde33afc6a3950965d22 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Sun, 7 Mar 2021 20:53:29 -0700
+Subject: usbip: fix stub_dev usbip_sockfd_store() races leading to gpf
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 9380afd6df70e24eacbdbde33afc6a3950965d22 upstream.
+
+usbip_sockfd_store() is invoked when user requests attach (import)
+detach (unimport) usb device from usbip host. vhci_hcd sends import
+request and usbip_sockfd_store() exports the device if it is free
+for export.
+
+Export and unexport are governed by local state and shared state
+- Shared state (usbip device status, sockfd) - sockfd and Device
+  status are used to determine if stub should be brought up or shut
+  down.
+- Local state (tcp_socket, rx and tx thread task_struct ptrs)
+  A valid tcp_socket controls rx and tx thread operations while the
+  device is in exported state.
+- While the device is exported, device status is marked used and socket,
+  sockfd, and thread pointers are valid.
+
+Export sequence (stub-up) includes validating the socket and creating
+receive (rx) and transmit (tx) threads to talk to the client to provide
+access to the exported device. rx and tx threads depends on local and
+shared state to be correct and in sync.
+
+Unexport (stub-down) sequence shuts the socket down and stops the rx and
+tx threads. Stub-down sequence relies on local and shared states to be
+in sync.
+
+There are races in updating the local and shared status in the current
+stub-up sequence resulting in crashes. These stem from starting rx and
+tx threads before local and global state is updated correctly to be in
+sync.
+
+1. Doesn't handle kthread_create() error and saves invalid ptr in local
+   state that drives rx and tx threads.
+2. Updates tcp_socket and sockfd,  starts stub_rx and stub_tx threads
+   before updating usbip_device status to SDEV_ST_USED. This opens up a
+   race condition between the threads and usbip_sockfd_store() stub up
+   and down handling.
+
+Fix the above problems:
+- Stop using kthread_get_run() macro to create/start threads.
+- Create threads and get task struct reference.
+- Add kthread_create() failure handling and bail out.
+- Hold usbip_device lock to update local and shared states after
+  creating rx and tx threads.
+- Update usbip_device status to SDEV_ST_USED.
+- Update usbip_device tcp_socket, sockfd, tcp_rx, and tcp_tx
+- Start threads after usbip_device (tcp_socket, sockfd, tcp_rx, tcp_tx,
+  and status) is complete.
+
+Credit goes to syzbot and Tetsuo Handa for finding and root-causing the
+kthread_get_run() improper error handling problem and others. This is a
+hard problem to find and debug since the races aren't seen in a normal
+case. Fuzzing forces the race window to be small enough for the
+kthread_get_run() error path bug and starting threads before updating the
+local and shared state bug in the stub-up sequence.
+
+Tested with syzbot reproducer:
+- https://syzkaller.appspot.com/text?tag=ReproC&x=14801034d00000
+
+Fixes: 9720b4bc76a83807 ("staging/usbip: convert to kthread")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot <syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+bf1a360e305ee719e364@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+95ce4b142579611ef0a9@syzkaller.appspotmail.com>
+Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/268a0668144d5ff36ec7d87fdfa90faf583b7ccc.1615171203.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/stub_dev.c |   32 +++++++++++++++++++++++++-------
+ 1 file changed, 25 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -46,6 +46,8 @@ static ssize_t usbip_sockfd_store(struct
+       int sockfd = 0;
+       struct socket *socket;
+       int rv;
++      struct task_struct *tcp_rx = NULL;
++      struct task_struct *tcp_tx = NULL;
+       if (!sdev) {
+               dev_err(dev, "sdev is null\n");
+@@ -80,20 +82,36 @@ static ssize_t usbip_sockfd_store(struct
+                       goto sock_err;
+               }
+-              sdev->ud.tcp_socket = socket;
+-              sdev->ud.sockfd = sockfd;
+-
++              /* unlock and create threads and get tasks */
+               spin_unlock_irq(&sdev->ud.lock);
++              tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx");
++              if (IS_ERR(tcp_rx)) {
++                      sockfd_put(socket);
++                      return -EINVAL;
++              }
++              tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx");
++              if (IS_ERR(tcp_tx)) {
++                      kthread_stop(tcp_rx);
++                      sockfd_put(socket);
++                      return -EINVAL;
++              }
+-              sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud,
+-                                                "stub_rx");
+-              sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud,
+-                                                "stub_tx");
++              /* get task structs now */
++              get_task_struct(tcp_rx);
++              get_task_struct(tcp_tx);
++              /* lock and update sdev->ud state */
+               spin_lock_irq(&sdev->ud.lock);
++              sdev->ud.tcp_socket = socket;
++              sdev->ud.sockfd = sockfd;
++              sdev->ud.tcp_rx = tcp_rx;
++              sdev->ud.tcp_tx = tcp_tx;
+               sdev->ud.status = SDEV_ST_USED;
+               spin_unlock_irq(&sdev->ud.lock);
++              wake_up_process(sdev->ud.tcp_rx);
++              wake_up_process(sdev->ud.tcp_tx);
++
+       } else {
+               dev_info(dev, "stub down\n");
diff --git a/queue-5.10/usbip-fix-vhci_hcd-attach_store-races-leading-to-gpf.patch b/queue-5.10/usbip-fix-vhci_hcd-attach_store-races-leading-to-gpf.patch
new file mode 100644 (file)
index 0000000..a03f9f8
--- /dev/null
@@ -0,0 +1,142 @@
+From 718ad9693e3656120064b715fe931f43a6201e67 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Sun, 7 Mar 2021 20:53:30 -0700
+Subject: usbip: fix vhci_hcd attach_store() races leading to gpf
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 718ad9693e3656120064b715fe931f43a6201e67 upstream.
+
+attach_store() is invoked when user requests import (attach) a device
+from usbip host.
+
+Attach and detach are governed by local state and shared state
+- Shared state (usbip device status) - Device status is used to manage
+  the attach and detach operations on import-able devices.
+- Local state (tcp_socket, rx and tx thread task_struct ptrs)
+  A valid tcp_socket controls rx and tx thread operations while the
+  device is in exported state.
+- Device has to be in the right state to be attached and detached.
+
+Attach sequence includes validating the socket and creating receive (rx)
+and transmit (tx) threads to talk to the host to get access to the
+imported device. rx and tx threads depends on local and shared state to
+be correct and in sync.
+
+Detach sequence shuts the socket down and stops the rx and tx threads.
+Detach sequence relies on local and shared states to be in sync.
+
+There are races in updating the local and shared status in the current
+attach sequence resulting in crashes. These stem from starting rx and
+tx threads before local and global state is updated correctly to be in
+sync.
+
+1. Doesn't handle kthread_create() error and saves invalid ptr in local
+   state that drives rx and tx threads.
+2. Updates tcp_socket and sockfd,  starts stub_rx and stub_tx threads
+   before updating usbip_device status to VDEV_ST_NOTASSIGNED. This opens
+   up a race condition between the threads, port connect, and detach
+   handling.
+
+Fix the above problems:
+- Stop using kthread_get_run() macro to create/start threads.
+- Create threads and get task struct reference.
+- Add kthread_create() failure handling and bail out.
+- Hold vhci and usbip_device locks to update local and shared states after
+  creating rx and tx threads.
+- Update usbip_device status to VDEV_ST_NOTASSIGNED.
+- Update usbip_device tcp_socket, sockfd, tcp_rx, and tcp_tx
+- Start threads after usbip_device (tcp_socket, sockfd, tcp_rx, tcp_tx,
+  and status) is complete.
+
+Credit goes to syzbot and Tetsuo Handa for finding and root-causing the
+kthread_get_run() improper error handling problem and others. This is
+hard problem to find and debug since the races aren't seen in a normal
+case. Fuzzing forces the race window to be small enough for the
+kthread_get_run() error path bug and starting threads before updating the
+local and shared state bug in the attach sequence.
+- Update usbip_device tcp_rx and tcp_tx pointers holding vhci and
+  usbip_device locks.
+
+Tested with syzbot reproducer:
+- https://syzkaller.appspot.com/text?tag=ReproC&x=14801034d00000
+
+Fixes: 9720b4bc76a83807 ("staging/usbip: convert to kthread")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot <syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+bf1a360e305ee719e364@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+95ce4b142579611ef0a9@syzkaller.appspotmail.com>
+Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/bb434bd5d7a64fbec38b5ecfb838a6baef6eb12b.1615171203.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/vhci_sysfs.c |   29 +++++++++++++++++++++++++----
+ 1 file changed, 25 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/usbip/vhci_sysfs.c
++++ b/drivers/usb/usbip/vhci_sysfs.c
+@@ -312,6 +312,8 @@ static ssize_t attach_store(struct devic
+       struct vhci *vhci;
+       int err;
+       unsigned long flags;
++      struct task_struct *tcp_rx = NULL;
++      struct task_struct *tcp_tx = NULL;
+       /*
+        * @rhport: port number of vhci_hcd
+@@ -360,9 +362,24 @@ static ssize_t attach_store(struct devic
+               return -EINVAL;
+       }
+-      /* now need lock until setting vdev status as used */
++      /* create threads before locking */
++      tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
++      if (IS_ERR(tcp_rx)) {
++              sockfd_put(socket);
++              return -EINVAL;
++      }
++      tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
++      if (IS_ERR(tcp_tx)) {
++              kthread_stop(tcp_rx);
++              sockfd_put(socket);
++              return -EINVAL;
++      }
++
++      /* get task structs now */
++      get_task_struct(tcp_rx);
++      get_task_struct(tcp_tx);
+-      /* begin a lock */
++      /* now begin lock until setting vdev status set */
+       spin_lock_irqsave(&vhci->lock, flags);
+       spin_lock(&vdev->ud.lock);
+@@ -372,6 +389,8 @@ static ssize_t attach_store(struct devic
+               spin_unlock_irqrestore(&vhci->lock, flags);
+               sockfd_put(socket);
++              kthread_stop_put(tcp_rx);
++              kthread_stop_put(tcp_tx);
+               dev_err(dev, "port %d already used\n", rhport);
+               /*
+@@ -390,14 +409,16 @@ static ssize_t attach_store(struct devic
+       vdev->speed         = speed;
+       vdev->ud.sockfd     = sockfd;
+       vdev->ud.tcp_socket = socket;
++      vdev->ud.tcp_rx     = tcp_rx;
++      vdev->ud.tcp_tx     = tcp_tx;
+       vdev->ud.status     = VDEV_ST_NOTASSIGNED;
+       spin_unlock(&vdev->ud.lock);
+       spin_unlock_irqrestore(&vhci->lock, flags);
+       /* end the lock */
+-      vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx");
+-      vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx");
++      wake_up_process(vdev->ud.tcp_rx);
++      wake_up_process(vdev->ud.tcp_tx);
+       rh_port_connect(vdev, speed);
diff --git a/queue-5.10/usbip-fix-vhci_hcd-to-check-for-stream-socket.patch b/queue-5.10/usbip-fix-vhci_hcd-to-check-for-stream-socket.patch
new file mode 100644 (file)
index 0000000..8404541
--- /dev/null
@@ -0,0 +1,42 @@
+From f55a0571690c4aae03180e001522538c0927432f Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Sun, 7 Mar 2021 20:53:27 -0700
+Subject: usbip: fix vhci_hcd to check for stream socket
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit f55a0571690c4aae03180e001522538c0927432f upstream.
+
+Fix attach_store() to validate the passed in file descriptor is a
+stream socket. If the file descriptor passed was a SOCK_DGRAM socket,
+sock_recvmsg() can't detect end of stream.
+
+Cc: stable@vger.kernel.org
+Suggested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/52712aa308915bda02cece1589e04ee8b401d1f3.1615171203.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/vhci_sysfs.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/usbip/vhci_sysfs.c
++++ b/drivers/usb/usbip/vhci_sysfs.c
+@@ -349,8 +349,16 @@ static ssize_t attach_store(struct devic
+       /* Extract socket from fd. */
+       socket = sockfd_lookup(sockfd, &err);
+-      if (!socket)
++      if (!socket) {
++              dev_err(dev, "failed to lookup sock");
+               return -EINVAL;
++      }
++      if (socket->type != SOCK_STREAM) {
++              dev_err(dev, "Expecting SOCK_STREAM - found %d",
++                      socket->type);
++              sockfd_put(socket);
++              return -EINVAL;
++      }
+       /* now need lock until setting vdev status as used */
diff --git a/queue-5.10/usbip-fix-vudc-to-check-for-stream-socket.patch b/queue-5.10/usbip-fix-vudc-to-check-for-stream-socket.patch
new file mode 100644 (file)
index 0000000..67aa2ae
--- /dev/null
@@ -0,0 +1,47 @@
+From 6801854be94fe8819b3894979875ea31482f5658 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Sun, 7 Mar 2021 20:53:28 -0700
+Subject: usbip: fix vudc to check for stream socket
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 6801854be94fe8819b3894979875ea31482f5658 upstream.
+
+Fix usbip_sockfd_store() to validate the passed in file descriptor is
+a stream socket. If the file descriptor passed was a SOCK_DGRAM socket,
+sock_recvmsg() can't detect end of stream.
+
+Cc: stable@vger.kernel.org
+Suggested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/387a670316002324113ac7ea1e8b53f4085d0c95.1615171203.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/vudc_sysfs.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/usb/usbip/vudc_sysfs.c
++++ b/drivers/usb/usbip/vudc_sysfs.c
+@@ -138,6 +138,13 @@ static ssize_t usbip_sockfd_store(struct
+                       goto unlock_ud;
+               }
++              if (socket->type != SOCK_STREAM) {
++                      dev_err(dev, "Expecting SOCK_STREAM - found %d",
++                              socket->type);
++                      ret = -EINVAL;
++                      goto sock_err;
++              }
++
+               udc->ud.tcp_socket = socket;
+               spin_unlock_irq(&udc->ud.lock);
+@@ -177,6 +184,8 @@ static ssize_t usbip_sockfd_store(struct
+       return count;
++sock_err:
++      sockfd_put(socket);
+ unlock_ud:
+       spin_unlock_irq(&udc->ud.lock);
+ unlock:
diff --git a/queue-5.10/usbip-fix-vudc-usbip_sockfd_store-races-leading-to-gpf.patch b/queue-5.10/usbip-fix-vudc-usbip_sockfd_store-races-leading-to-gpf.patch
new file mode 100644 (file)
index 0000000..7f98e06
--- /dev/null
@@ -0,0 +1,153 @@
+From 46613c9dfa964c0c60b5385dbdf5aaa18be52a9c Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Sun, 7 Mar 2021 20:53:31 -0700
+Subject: usbip: fix vudc usbip_sockfd_store races leading to gpf
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 46613c9dfa964c0c60b5385dbdf5aaa18be52a9c upstream.
+
+usbip_sockfd_store() is invoked when user requests attach (import)
+detach (unimport) usb gadget device from usbip host. vhci_hcd sends
+import request and usbip_sockfd_store() exports the device if it is
+free for export.
+
+Export and unexport are governed by local state and shared state
+- Shared state (usbip device status, sockfd) - sockfd and Device
+  status are used to determine if stub should be brought up or shut
+  down. Device status is shared between host and client.
+- Local state (tcp_socket, rx and tx thread task_struct ptrs)
+  A valid tcp_socket controls rx and tx thread operations while the
+  device is in exported state.
+- While the device is exported, device status is marked used and socket,
+  sockfd, and thread pointers are valid.
+
+Export sequence (stub-up) includes validating the socket and creating
+receive (rx) and transmit (tx) threads to talk to the client to provide
+access to the exported device. rx and tx threads depends on local and
+shared state to be correct and in sync.
+
+Unexport (stub-down) sequence shuts the socket down and stops the rx and
+tx threads. Stub-down sequence relies on local and shared states to be
+in sync.
+
+There are races in updating the local and shared status in the current
+stub-up sequence resulting in crashes. These stem from starting rx and
+tx threads before local and global state is updated correctly to be in
+sync.
+
+1. Doesn't handle kthread_create() error and saves invalid ptr in local
+   state that drives rx and tx threads.
+2. Updates tcp_socket and sockfd,  starts stub_rx and stub_tx threads
+   before updating usbip_device status to SDEV_ST_USED. This opens up a
+   race condition between the threads and usbip_sockfd_store() stub up
+   and down handling.
+
+Fix the above problems:
+- Stop using kthread_get_run() macro to create/start threads.
+- Create threads and get task struct reference.
+- Add kthread_create() failure handling and bail out.
+- Hold usbip_device lock to update local and shared states after
+  creating rx and tx threads.
+- Update usbip_device status to SDEV_ST_USED.
+- Update usbip_device tcp_socket, sockfd, tcp_rx, and tcp_tx
+- Start threads after usbip_device (tcp_socket, sockfd, tcp_rx, tcp_tx,
+  and status) is complete.
+
+Credit goes to syzbot and Tetsuo Handa for finding and root-causing the
+kthread_get_run() improper error handling problem and others. This is a
+hard problem to find and debug since the races aren't seen in a normal
+case. Fuzzing forces the race window to be small enough for the
+kthread_get_run() error path bug and starting threads before updating the
+local and shared state bug in the stub-up sequence.
+
+Fixes: 9720b4bc76a83807 ("staging/usbip: convert to kthread")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot <syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+bf1a360e305ee719e364@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+95ce4b142579611ef0a9@syzkaller.appspotmail.com>
+Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/b1c08b983ffa185449c9f0f7d1021dc8c8454b60.1615171203.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/vudc_sysfs.c |   42 +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/usbip/vudc_sysfs.c
++++ b/drivers/usb/usbip/vudc_sysfs.c
+@@ -90,8 +90,9 @@ unlock:
+ }
+ static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor));
+-static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *attr,
+-                   const char *in, size_t count)
++static ssize_t usbip_sockfd_store(struct device *dev,
++                                struct device_attribute *attr,
++                                const char *in, size_t count)
+ {
+       struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
+       int rv;
+@@ -100,6 +101,8 @@ static ssize_t usbip_sockfd_store(struct
+       struct socket *socket;
+       unsigned long flags;
+       int ret;
++      struct task_struct *tcp_rx = NULL;
++      struct task_struct *tcp_tx = NULL;
+       rv = kstrtoint(in, 0, &sockfd);
+       if (rv != 0)
+@@ -145,24 +148,47 @@ static ssize_t usbip_sockfd_store(struct
+                       goto sock_err;
+               }
+-              udc->ud.tcp_socket = socket;
+-
++              /* unlock and create threads and get tasks */
+               spin_unlock_irq(&udc->ud.lock);
+               spin_unlock_irqrestore(&udc->lock, flags);
+-              udc->ud.tcp_rx = kthread_get_run(&v_rx_loop,
+-                                                  &udc->ud, "vudc_rx");
+-              udc->ud.tcp_tx = kthread_get_run(&v_tx_loop,
+-                                                  &udc->ud, "vudc_tx");
++              tcp_rx = kthread_create(&v_rx_loop, &udc->ud, "vudc_rx");
++              if (IS_ERR(tcp_rx)) {
++                      sockfd_put(socket);
++                      return -EINVAL;
++              }
++              tcp_tx = kthread_create(&v_tx_loop, &udc->ud, "vudc_tx");
++              if (IS_ERR(tcp_tx)) {
++                      kthread_stop(tcp_rx);
++                      sockfd_put(socket);
++                      return -EINVAL;
++              }
++
++              /* get task structs now */
++              get_task_struct(tcp_rx);
++              get_task_struct(tcp_tx);
++              /* lock and update udc->ud state */
+               spin_lock_irqsave(&udc->lock, flags);
+               spin_lock_irq(&udc->ud.lock);
++
++              udc->ud.tcp_socket = socket;
++              udc->ud.tcp_rx = tcp_rx;
++              udc->ud.tcp_rx = tcp_tx;
+               udc->ud.status = SDEV_ST_USED;
++
+               spin_unlock_irq(&udc->ud.lock);
+               ktime_get_ts64(&udc->start_time);
+               v_start_timer(udc);
+               udc->connected = 1;
++
++              spin_unlock_irqrestore(&udc->lock, flags);
++
++              wake_up_process(udc->ud.tcp_rx);
++              wake_up_process(udc->ud.tcp_tx);
++              return count;
++
+       } else {
+               if (!udc->connected) {
+                       dev_err(dev, "Device not connected");
diff --git a/queue-5.10/xhci-fix-repeated-xhci-wake-after-suspend-due-to-uncleared-internal-wake-state.patch b/queue-5.10/xhci-fix-repeated-xhci-wake-after-suspend-due-to-uncleared-internal-wake-state.patch
new file mode 100644 (file)
index 0000000..29e420b
--- /dev/null
@@ -0,0 +1,115 @@
+From d26c00e7276fc92b18c253d69e872f6b03832bad Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 11 Mar 2021 13:53:53 +0200
+Subject: xhci: Fix repeated xhci wake after suspend due to uncleared internal wake state
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit d26c00e7276fc92b18c253d69e872f6b03832bad upstream.
+
+If port terminations are detected in suspend, but link never reaches U0
+then xHCI may have an internal uncleared wake state that will cause an
+immediate wake after suspend.
+
+This wake state is normally cleared when driver clears the PORT_CSC bit,
+which is set after a device is enabled and in U0.
+
+Write 1 to clear PORT_CSC for ports that don't have anything connected
+when suspending. This makes sure any pending internal wake states in
+xHCI are cleared.
+
+Cc: stable@vger.kernel.org
+Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210311115353.2137560-5-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci.c |   62 +++++++++++++++++++++++-------------------------
+ 1 file changed, 30 insertions(+), 32 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -883,44 +883,42 @@ static void xhci_clear_command_ring(stru
+       xhci_set_cmd_ring_deq(xhci);
+ }
+-static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
++/*
++ * Disable port wake bits if do_wakeup is not set.
++ *
++ * Also clear a possible internal port wake state left hanging for ports that
++ * detected termination but never successfully enumerated (trained to 0U).
++ * Internal wake causes immediate xHCI wake after suspend. PORT_CSC write done
++ * at enumeration clears this wake, force one here as well for unconnected ports
++ */
++
++static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
++                                     struct xhci_hub *rhub,
++                                     bool do_wakeup)
+ {
+-      struct xhci_port **ports;
+-      int port_index;
+       unsigned long flags;
+       u32 t1, t2, portsc;
++      int i;
+       spin_lock_irqsave(&xhci->lock, flags);
+-      /* disable usb3 ports Wake bits */
+-      port_index = xhci->usb3_rhub.num_ports;
+-      ports = xhci->usb3_rhub.ports;
+-      while (port_index--) {
+-              t1 = readl(ports[port_index]->addr);
+-              portsc = t1;
+-              t1 = xhci_port_state_to_neutral(t1);
+-              t2 = t1 & ~PORT_WAKE_BITS;
+-              if (t1 != t2) {
+-                      writel(t2, ports[port_index]->addr);
+-                      xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
+-                               xhci->usb3_rhub.hcd->self.busnum,
+-                               port_index + 1, portsc, t2);
+-              }
+-      }
++      for (i = 0; i < rhub->num_ports; i++) {
++              portsc = readl(rhub->ports[i]->addr);
++              t1 = xhci_port_state_to_neutral(portsc);
++              t2 = t1;
++
++              /* clear wake bits if do_wake is not set */
++              if (!do_wakeup)
++                      t2 &= ~PORT_WAKE_BITS;
++
++              /* Don't touch csc bit if connected or connect change is set */
++              if (!(portsc & (PORT_CSC | PORT_CONNECT)))
++                      t2 |= PORT_CSC;
+-      /* disable usb2 ports Wake bits */
+-      port_index = xhci->usb2_rhub.num_ports;
+-      ports = xhci->usb2_rhub.ports;
+-      while (port_index--) {
+-              t1 = readl(ports[port_index]->addr);
+-              portsc = t1;
+-              t1 = xhci_port_state_to_neutral(t1);
+-              t2 = t1 & ~PORT_WAKE_BITS;
+               if (t1 != t2) {
+-                      writel(t2, ports[port_index]->addr);
+-                      xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
+-                               xhci->usb2_rhub.hcd->self.busnum,
+-                               port_index + 1, portsc, t2);
++                      writel(t2, rhub->ports[i]->addr);
++                      xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n",
++                               rhub->hcd->self.busnum, i + 1, portsc, t2);
+               }
+       }
+       spin_unlock_irqrestore(&xhci->lock, flags);
+@@ -983,8 +981,8 @@ int xhci_suspend(struct xhci_hcd *xhci,
+               return -EINVAL;
+       /* Clear root port wake on bits if wakeup not allowed. */
+-      if (!do_wakeup)
+-              xhci_disable_port_wake_on_bits(xhci);
++      xhci_disable_hub_port_wake(xhci, &xhci->usb3_rhub, do_wakeup);
++      xhci_disable_hub_port_wake(xhci, &xhci->usb2_rhub, do_wakeup);
+       if (!HCD_HW_ACCESSIBLE(hcd))
+               return 0;
diff --git a/queue-5.10/xhci-improve-detection-of-device-initiated-wake-signal.patch b/queue-5.10/xhci-improve-detection-of-device-initiated-wake-signal.patch
new file mode 100644 (file)
index 0000000..c3d75eb
--- /dev/null
@@ -0,0 +1,69 @@
+From 253f588c70f66184b1f3a9bbb428b49bbda73e80 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 11 Mar 2021 13:53:51 +0200
+Subject: xhci: Improve detection of device initiated wake signal.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 253f588c70f66184b1f3a9bbb428b49bbda73e80 upstream.
+
+A xHC USB 3 port might miss the first wake signal from a USB 3 device
+if the port LFPS reveiver isn't enabled fast enough after xHC resume.
+
+xHC host will anyway be resumed by a PME# signal, but will go back to
+suspend if no port activity is seen.
+The device resends the U3 LFPS wake signal after a 100ms delay, but
+by then host is already suspended, starting all over from the
+beginning of this issue.
+
+USB 3 specs say U3 wake LFPS signal is sent for max 10ms, then device
+needs to delay 100ms before resending the wake.
+
+Don't suspend immediately if port activity isn't detected in resume.
+Instead add a retry. If there is no port activity then delay for 120ms,
+and re-check for port activity.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210311115353.2137560-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci.c |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1088,6 +1088,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
+       struct usb_hcd          *secondary_hcd;
+       int                     retval = 0;
+       bool                    comp_timer_running = false;
++      bool                    pending_portevent = false;
+       if (!hcd->state)
+               return 0;
+@@ -1226,13 +1227,22 @@ int xhci_resume(struct xhci_hcd *xhci, b
+  done:
+       if (retval == 0) {
+-              /* Resume root hubs only when have pending events. */
+-              if (xhci_pending_portevent(xhci)) {
++              /*
++               * Resume roothubs only if there are pending events.
++               * USB 3 devices resend U3 LFPS wake after a 100ms delay if
++               * the first wake signalling failed, give it that chance.
++               */
++              pending_portevent = xhci_pending_portevent(xhci);
++              if (!pending_portevent) {
++                      msleep(120);
++                      pending_portevent = xhci_pending_portevent(xhci);
++              }
++
++              if (pending_portevent) {
+                       usb_hcd_resume_root_hub(xhci->shared_hcd);
+                       usb_hcd_resume_root_hub(hcd);
+               }
+       }
+-
+       /*
+        * If system is subject to the Quirk, Compliance Mode Timer needs to
+        * be re-initialized Always after a system resume. Ports are subject