]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Oct 2020 13:42:00 +0000 (14:42 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Oct 2020 13:42:00 +0000 (14:42 +0100)
added patches:
eeprom-at25-set-minimum-read-write-access-stride-to-1.patch
tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch
tty-serial-lpuart-fix-lpuart32_write-usage.patch
usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch
usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch
usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch

queue-5.4/eeprom-at25-set-minimum-read-write-access-stride-to-1.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch [new file with mode: 0644]
queue-5.4/tty-serial-lpuart-fix-lpuart32_write-usage.patch [new file with mode: 0644]
queue-5.4/usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch [new file with mode: 0644]
queue-5.4/usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch [new file with mode: 0644]
queue-5.4/usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch [new file with mode: 0644]

diff --git a/queue-5.4/eeprom-at25-set-minimum-read-write-access-stride-to-1.patch b/queue-5.4/eeprom-at25-set-minimum-read-write-access-stride-to-1.patch
new file mode 100644 (file)
index 0000000..0c69b8f
--- /dev/null
@@ -0,0 +1,31 @@
+From 284f52ac1c6cfa1b2e5c11b84653dd90e4e91de7 Mon Sep 17 00:00:00 2001
+From: Christian Eggers <ceggers@arri.de>
+Date: Tue, 28 Jul 2020 11:29:59 +0200
+Subject: eeprom: at25: set minimum read/write access stride to 1
+
+From: Christian Eggers <ceggers@arri.de>
+
+commit 284f52ac1c6cfa1b2e5c11b84653dd90e4e91de7 upstream.
+
+SPI eeproms are addressed by byte.
+
+Signed-off-by: Christian Eggers <ceggers@arri.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200728092959.24600-1-ceggers@arri.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/eeprom/at25.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/eeprom/at25.c
++++ b/drivers/misc/eeprom/at25.c
+@@ -358,7 +358,7 @@ static int at25_probe(struct spi_device
+       at25->nvmem_config.reg_read = at25_ee_read;
+       at25->nvmem_config.reg_write = at25_ee_write;
+       at25->nvmem_config.priv = at25;
+-      at25->nvmem_config.stride = 4;
++      at25->nvmem_config.stride = 1;
+       at25->nvmem_config.word_size = 1;
+       at25->nvmem_config.size = chip.byte_len;
index 02b38a4a5be7ac2e10e88d34233ee624cb5c7710..f1fcaf79f8b039959a28ff9d6b24abb9f7fbb061 100644 (file)
@@ -400,3 +400,9 @@ dmaengine-dw-activate-fifo-mode-for-memory-periphera.patch
 ath10k-check-idx-validity-in-__ath10k_htt_rx_ring_fi.patch
 net-korina-cast-kseg0-address-to-pointer-in-kfree.patch
 s390-qeth-don-t-let-hw-override-the-configured-port-.patch
+tty-serial-lpuart-fix-lpuart32_write-usage.patch
+tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch
+usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch
+usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch
+usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch
+eeprom-at25-set-minimum-read-write-access-stride-to-1.patch
diff --git a/queue-5.4/tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch b/queue-5.4/tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch
new file mode 100644 (file)
index 0000000..4d86b77
--- /dev/null
@@ -0,0 +1,35 @@
+From 29788ab1d2bf26c130de8f44f9553ee78a27e8d5 Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Tue, 29 Sep 2020 17:55:09 +0800
+Subject: tty: serial: fsl_lpuart: fix lpuart32_poll_get_char
+
+From: Peng Fan <peng.fan@nxp.com>
+
+commit 29788ab1d2bf26c130de8f44f9553ee78a27e8d5 upstream.
+
+The watermark is set to 1, so we need to input two chars to trigger RDRF
+using the original logic. With the new logic, we could always get the
+char when there is data in FIFO.
+
+Suggested-by: Fugang Duan <fugang.duan@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20200929095509.21680-1-peng.fan@nxp.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/fsl_lpuart.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -666,7 +666,7 @@ static void lpuart32_poll_put_char(struc
+ static int lpuart32_poll_get_char(struct uart_port *port)
+ {
+-      if (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF))
++      if (!(lpuart32_read(port, UARTWATER) >> UARTWATER_RXCNT_OFF))
+               return NO_POLL_CHAR;
+       return lpuart32_read(port, UARTDATA);
diff --git a/queue-5.4/tty-serial-lpuart-fix-lpuart32_write-usage.patch b/queue-5.4/tty-serial-lpuart-fix-lpuart32_write-usage.patch
new file mode 100644 (file)
index 0000000..7c3c26a
--- /dev/null
@@ -0,0 +1,66 @@
+From 9ea40db477c024dcb87321b7f32bd6ea12130ac2 Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Tue, 29 Sep 2020 17:19:20 +0800
+Subject: tty: serial: lpuart: fix lpuart32_write usage
+
+From: Peng Fan <peng.fan@nxp.com>
+
+commit 9ea40db477c024dcb87321b7f32bd6ea12130ac2 upstream.
+
+The 2nd and 3rd parameter were wrongly used, and cause kernel abort when
+doing kgdb debug.
+
+Fixes: 1da17d7cf8e2 ("tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20200929091920.22612-1-peng.fan@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/fsl_lpuart.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -635,26 +635,24 @@ static int lpuart32_poll_init(struct uar
+       spin_lock_irqsave(&sport->port.lock, flags);
+       /* Disable Rx & Tx */
+-      lpuart32_write(&sport->port, UARTCTRL, 0);
++      lpuart32_write(&sport->port, 0, UARTCTRL);
+       temp = lpuart32_read(&sport->port, UARTFIFO);
+       /* Enable Rx and Tx FIFO */
+-      lpuart32_write(&sport->port, UARTFIFO,
+-                     temp | UARTFIFO_RXFE | UARTFIFO_TXFE);
++      lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
+       /* flush Tx and Rx FIFO */
+-      lpuart32_write(&sport->port, UARTFIFO,
+-                     UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH);
++      lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
+       /* explicitly clear RDRF */
+       if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) {
+               lpuart32_read(&sport->port, UARTDATA);
+-              lpuart32_write(&sport->port, UARTFIFO, UARTFIFO_RXUF);
++              lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO);
+       }
+       /* Enable Rx and Tx */
+-      lpuart32_write(&sport->port, UARTCTRL, UARTCTRL_RE | UARTCTRL_TE);
++      lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
+       spin_unlock_irqrestore(&sport->port.lock, flags);
+       return 0;
+@@ -663,7 +661,7 @@ static int lpuart32_poll_init(struct uar
+ static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c)
+ {
+       lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TDRE);
+-      lpuart32_write(port, UARTDATA, c);
++      lpuart32_write(port, c, UARTDATA);
+ }
+ static int lpuart32_poll_get_char(struct uart_port *port)
diff --git a/queue-5.4/usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch b/queue-5.4/usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch
new file mode 100644 (file)
index 0000000..1e18db6
--- /dev/null
@@ -0,0 +1,340 @@
+From a4f88430af896bf34ec25a7a5f0e053fb3d928e0 Mon Sep 17 00:00:00 2001
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Date: Sat, 3 Oct 2020 00:41:51 +0900
+Subject: usb: cdc-acm: add quirk to blacklist ETAS ES58X devices
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+commit a4f88430af896bf34ec25a7a5f0e053fb3d928e0 upstream.
+
+The ES58X devices has a CDC ACM interface (used for debug
+purpose). During probing, the device is thus recognized as USB Modem
+(CDC ACM), preventing the etas-es58x module to load:
+  usbcore: registered new interface driver etas_es58x
+  usb 1-1.1: new full-speed USB device number 14 using xhci_hcd
+  usb 1-1.1: New USB device found, idVendor=108c, idProduct=0159, bcdDevice= 1.00
+  usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+  usb 1-1.1: Product: ES581.4
+  usb 1-1.1: Manufacturer: ETAS GmbH
+  usb 1-1.1: SerialNumber: 2204355
+  cdc_acm 1-1.1:1.0: No union descriptor, testing for castrated device
+  cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
+
+Thus, these have been added to the ignore list in
+drivers/usb/class/cdc-acm.c
+
+N.B. Future firmware release of the ES58X will remove the CDC-ACM
+interface.
+
+`lsusb -v` of the three devices variant (ES581.4, ES582.1 and
+ES584.1):
+
+  Bus 001 Device 011: ID 108c:0159 Robert Bosch GmbH ES581.4
+  Device Descriptor:
+    bLength                18
+    bDescriptorType         1
+    bcdUSB               1.10
+    bDeviceClass            2 Communications
+    bDeviceSubClass         0
+    bDeviceProtocol         0
+    bMaxPacketSize0        64
+    idVendor           0x108c Robert Bosch GmbH
+    idProduct          0x0159
+    bcdDevice            1.00
+    iManufacturer           1 ETAS GmbH
+    iProduct                2 ES581.4
+    iSerial                 3 2204355
+    bNumConfigurations      1
+    Configuration Descriptor:
+      bLength                 9
+      bDescriptorType         2
+      wTotalLength       0x0035
+      bNumInterfaces          1
+      bConfigurationValue     1
+      iConfiguration          5 Bus Powered Configuration
+      bmAttributes         0x80
+        (Bus Powered)
+      MaxPower              100mA
+      Interface Descriptor:
+        bLength                 9
+        bDescriptorType         4
+        bInterfaceNumber        0
+        bAlternateSetting       0
+        bNumEndpoints           3
+        bInterfaceClass         2 Communications
+        bInterfaceSubClass      2 Abstract (modem)
+        bInterfaceProtocol      0
+        iInterface              4 ACM Control Interface
+        CDC Header:
+          bcdCDC               1.10
+        CDC Call Management:
+          bmCapabilities       0x01
+            call management
+          bDataInterface          0
+        CDC ACM:
+          bmCapabilities       0x06
+            sends break
+            line coding and serial state
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x81  EP 1 IN
+          bmAttributes            3
+            Transfer Type            Interrupt
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0010  1x 16 bytes
+          bInterval              10
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x82  EP 2 IN
+          bmAttributes            2
+            Transfer Type            Bulk
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0040  1x 64 bytes
+          bInterval               0
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x03  EP 3 OUT
+          bmAttributes            2
+            Transfer Type            Bulk
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0040  1x 64 bytes
+          bInterval               0
+  Device Status:     0x0000
+    (Bus Powered)
+
+  Bus 001 Device 012: ID 108c:0168 Robert Bosch GmbH ES582
+  Device Descriptor:
+    bLength                18
+    bDescriptorType         1
+    bcdUSB               2.00
+    bDeviceClass            2 Communications
+    bDeviceSubClass         0
+    bDeviceProtocol         0
+    bMaxPacketSize0        64
+    idVendor           0x108c Robert Bosch GmbH
+    idProduct          0x0168
+    bcdDevice            1.00
+    iManufacturer           1 ETAS GmbH
+    iProduct                2 ES582
+    iSerial                 3 0108933
+    bNumConfigurations      1
+    Configuration Descriptor:
+      bLength                 9
+      bDescriptorType         2
+      wTotalLength       0x0043
+      bNumInterfaces          2
+      bConfigurationValue     1
+      iConfiguration          0
+      bmAttributes         0x80
+        (Bus Powered)
+      MaxPower              500mA
+      Interface Descriptor:
+        bLength                 9
+        bDescriptorType         4
+        bInterfaceNumber        0
+        bAlternateSetting       0
+        bNumEndpoints           1
+        bInterfaceClass         2 Communications
+        bInterfaceSubClass      2 Abstract (modem)
+        bInterfaceProtocol      1 AT-commands (v.25ter)
+        iInterface              0
+        CDC Header:
+          bcdCDC               1.10
+        CDC ACM:
+          bmCapabilities       0x02
+            line coding and serial state
+        CDC Union:
+          bMasterInterface        0
+          bSlaveInterface         1
+        CDC Call Management:
+          bmCapabilities       0x03
+            call management
+            use DataInterface
+          bDataInterface          1
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x83  EP 3 IN
+          bmAttributes            3
+            Transfer Type            Interrupt
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0040  1x 64 bytes
+          bInterval              16
+      Interface Descriptor:
+        bLength                 9
+        bDescriptorType         4
+        bInterfaceNumber        1
+        bAlternateSetting       0
+        bNumEndpoints           2
+        bInterfaceClass        10 CDC Data
+        bInterfaceSubClass      0
+        bInterfaceProtocol      0
+        iInterface              0
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x81  EP 1 IN
+          bmAttributes            2
+            Transfer Type            Bulk
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0200  1x 512 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     0x0200  1x 512 bytes
+          bInterval               0
+  Device Qualifier (for other device speed):
+    bLength                10
+    bDescriptorType         6
+    bcdUSB               2.00
+    bDeviceClass            2 Communications
+    bDeviceSubClass         0
+    bDeviceProtocol         0
+    bMaxPacketSize0        64
+    bNumConfigurations      1
+  Device Status:     0x0000
+    (Bus Powered)
+
+  Bus 001 Device 013: ID 108c:0169 Robert Bosch GmbH ES584.1
+  Device Descriptor:
+    bLength                18
+    bDescriptorType         1
+    bcdUSB               2.00
+    bDeviceClass            2 Communications
+    bDeviceSubClass         0
+    bDeviceProtocol         0
+    bMaxPacketSize0        64
+    idVendor           0x108c Robert Bosch GmbH
+    idProduct          0x0169
+    bcdDevice            1.00
+    iManufacturer           1 ETAS GmbH
+    iProduct                2 ES584.1
+    iSerial                 3 0100320
+    bNumConfigurations      1
+    Configuration Descriptor:
+      bLength                 9
+      bDescriptorType         2
+      wTotalLength       0x0043
+      bNumInterfaces          2
+      bConfigurationValue     1
+      iConfiguration          0
+      bmAttributes         0x80
+        (Bus Powered)
+      MaxPower              500mA
+      Interface Descriptor:
+        bLength                 9
+        bDescriptorType         4
+        bInterfaceNumber        0
+        bAlternateSetting       0
+        bNumEndpoints           1
+        bInterfaceClass         2 Communications
+        bInterfaceSubClass      2 Abstract (modem)
+        bInterfaceProtocol      1 AT-commands (v.25ter)
+        iInterface              0
+        CDC Header:
+          bcdCDC               1.10
+        CDC ACM:
+          bmCapabilities       0x02
+            line coding and serial state
+        CDC Union:
+          bMasterInterface        0
+          bSlaveInterface         1
+        CDC Call Management:
+          bmCapabilities       0x03
+            call management
+            use DataInterface
+          bDataInterface          1
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x83  EP 3 IN
+          bmAttributes            3
+            Transfer Type            Interrupt
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0040  1x 64 bytes
+          bInterval              16
+      Interface Descriptor:
+        bLength                 9
+        bDescriptorType         4
+        bInterfaceNumber        1
+        bAlternateSetting       0
+        bNumEndpoints           2
+        bInterfaceClass        10 CDC Data
+        bInterfaceSubClass      0
+        bInterfaceProtocol      0
+        iInterface              0
+        Endpoint Descriptor:
+          bLength                 7
+          bDescriptorType         5
+          bEndpointAddress     0x81  EP 1 IN
+          bmAttributes            2
+            Transfer Type            Bulk
+            Synch Type               None
+            Usage Type               Data
+          wMaxPacketSize     0x0200  1x 512 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     0x0200  1x 512 bytes
+          bInterval               0
+  Device Qualifier (for other device speed):
+    bLength                10
+    bDescriptorType         6
+    bcdUSB               2.00
+    bDeviceClass            2 Communications
+    bDeviceSubClass         0
+    bDeviceProtocol         0
+    bMaxPacketSize0        64
+    bNumConfigurations      1
+  Device Status:     0x0000
+    (Bus Powered)
+
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20201002154219.4887-8-mailhol.vincent@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1912,6 +1912,17 @@ static const struct usb_device_id acm_id
+       .driver_info = IGNORE_DEVICE,
+       },
++      /* Exclude ETAS ES58x */
++      { USB_DEVICE(0x108c, 0x0159), /* ES581.4 */
++      .driver_info = IGNORE_DEVICE,
++      },
++      { USB_DEVICE(0x108c, 0x0168), /* ES582.1 */
++      .driver_info = IGNORE_DEVICE,
++      },
++      { USB_DEVICE(0x108c, 0x0169), /* ES584.1 */
++      .driver_info = IGNORE_DEVICE,
++      },
++
+       { USB_DEVICE(0x1bc7, 0x0021), /* Telit 3G ACM only composition */
+       .driver_info = SEND_ZERO_PACKET,
+       },
diff --git a/queue-5.4/usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch b/queue-5.4/usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch
new file mode 100644 (file)
index 0000000..e2a22b1
--- /dev/null
@@ -0,0 +1,184 @@
+From 37d2a36394d954413a495da61da1b2a51ecd28ab Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Mon, 28 Sep 2020 23:17:55 +0900
+Subject: USB: cdc-wdm: Make wdm_flush() interruptible and add wdm_fsync().
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 37d2a36394d954413a495da61da1b2a51ecd28ab upstream.
+
+syzbot is reporting hung task at wdm_flush() [1], for there is a circular
+dependency that wdm_flush() from flip_close() for /dev/cdc-wdm0 forever
+waits for /dev/raw-gadget to be closed while close() for /dev/raw-gadget
+cannot be called unless close() for /dev/cdc-wdm0 completes.
+
+Tetsuo Handa considered that such circular dependency is an usage error [2]
+which corresponds to an unresponding broken hardware [3]. But Alan Stern
+responded that we should be prepared for such hardware [4]. Therefore,
+this patch changes wdm_flush() to use wait_event_interruptible_timeout()
+which gives up after 30 seconds, for hardware that remains silent must be
+ignored. The 30 seconds are coming out of thin air.
+
+Changing wait_event() to wait_event_interruptible_timeout() makes error
+reporting from close() syscall less reliable. To compensate it, this patch
+also implements wdm_fsync() which does not use timeout. Those who want to
+be very sure that data has gone out to the device are now advised to call
+fsync(), with a caveat that fsync() can return -EINVAL when running on
+older kernels which do not implement wdm_fsync().
+
+This patch also fixes three more problems (listed below) found during
+exhaustive discussion and testing.
+
+  Since multiple threads can concurrently call wdm_write()/wdm_flush(),
+  we need to use wake_up_all() whenever clearing WDM_IN_USE in order to
+  make sure that all waiters are woken up. Also, error reporting needs
+  to use fetch-and-clear approach in order not to report same error for
+  multiple times.
+
+  Since wdm_flush() checks WDM_DISCONNECTING, wdm_write() should as well
+  check WDM_DISCONNECTING.
+
+  In wdm_flush(), since locks are not held, it is not safe to dereference
+  desc->intf after checking that WDM_DISCONNECTING is not set [5]. Thus,
+  remove dev_err() from wdm_flush().
+
+[1] https://syzkaller.appspot.com/bug?id=e7b761593b23eb50855b9ea31e3be5472b711186
+[2] https://lkml.kernel.org/r/27b7545e-8f41-10b8-7c02-e35a08eb1611@i-love.sakura.ne.jp
+[3] https://lkml.kernel.org/r/79ba410f-e0ef-2465-b94f-6b9a4a82adf5@i-love.sakura.ne.jp
+[4] https://lkml.kernel.org/r/20200530011040.GB12419@rowland.harvard.edu
+[5] https://lkml.kernel.org/r/c85331fc-874c-6e46-a77f-0ef1dc075308@i-love.sakura.ne.jp
+
+Reported-by: syzbot <syzbot+854768b99f19e89d7f81@syzkaller.appspotmail.com>
+Cc: stable <stable@vger.kernel.org>
+Co-developed-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200928141755.3476-1-penguin-kernel@I-love.SAKURA.ne.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-wdm.c |   70 +++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 54 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -58,6 +58,9 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
+ #define WDM_MAX                       16
++/* we cannot wait forever at flush() */
++#define WDM_FLUSH_TIMEOUT     (30 * HZ)
++
+ /* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
+ #define WDM_DEFAULT_BUFSIZE   256
+@@ -151,7 +154,7 @@ static void wdm_out_callback(struct urb
+       kfree(desc->outbuf);
+       desc->outbuf = NULL;
+       clear_bit(WDM_IN_USE, &desc->flags);
+-      wake_up(&desc->wait);
++      wake_up_all(&desc->wait);
+ }
+ static void wdm_in_callback(struct urb *urb)
+@@ -393,6 +396,9 @@ static ssize_t wdm_write
+       if (test_bit(WDM_RESETTING, &desc->flags))
+               r = -EIO;
++      if (test_bit(WDM_DISCONNECTING, &desc->flags))
++              r = -ENODEV;
++
+       if (r < 0) {
+               rv = r;
+               goto out_free_mem_pm;
+@@ -424,6 +430,7 @@ static ssize_t wdm_write
+       if (rv < 0) {
+               desc->outbuf = NULL;
+               clear_bit(WDM_IN_USE, &desc->flags);
++              wake_up_all(&desc->wait); /* for wdm_wait_for_response() */
+               dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
+               rv = usb_translate_errors(rv);
+               goto out_free_mem_pm;
+@@ -583,28 +590,58 @@ err:
+       return rv;
+ }
+-static int wdm_flush(struct file *file, fl_owner_t id)
++static int wdm_wait_for_response(struct file *file, long timeout)
+ {
+       struct wdm_device *desc = file->private_data;
++      long rv; /* Use long here because (int) MAX_SCHEDULE_TIMEOUT < 0. */
+-      wait_event(desc->wait,
+-                      /*
+-                       * needs both flags. We cannot do with one
+-                       * because resetting it would cause a race
+-                       * with write() yet we need to signal
+-                       * a disconnect
+-                       */
+-                      !test_bit(WDM_IN_USE, &desc->flags) ||
+-                      test_bit(WDM_DISCONNECTING, &desc->flags));
++      /*
++       * Needs both flags. We cannot do with one because resetting it would
++       * cause a race with write() yet we need to signal a disconnect.
++       */
++      rv = wait_event_interruptible_timeout(desc->wait,
++                            !test_bit(WDM_IN_USE, &desc->flags) ||
++                            test_bit(WDM_DISCONNECTING, &desc->flags),
++                            timeout);
+-      /* cannot dereference desc->intf if WDM_DISCONNECTING */
++      /*
++       * To report the correct error. This is best effort.
++       * We are inevitably racing with the hardware.
++       */
+       if (test_bit(WDM_DISCONNECTING, &desc->flags))
+               return -ENODEV;
+-      if (desc->werr < 0)
+-              dev_err(&desc->intf->dev, "Error in flush path: %d\n",
+-                      desc->werr);
++      if (!rv)
++              return -EIO;
++      if (rv < 0)
++              return -EINTR;
++
++      spin_lock_irq(&desc->iuspin);
++      rv = desc->werr;
++      desc->werr = 0;
++      spin_unlock_irq(&desc->iuspin);
+-      return usb_translate_errors(desc->werr);
++      return usb_translate_errors(rv);
++
++}
++
++/*
++ * You need to send a signal when you react to malicious or defective hardware.
++ * Also, don't abort when fsync() returned -EINVAL, for older kernels which do
++ * not implement wdm_flush() will return -EINVAL.
++ */
++static int wdm_fsync(struct file *file, loff_t start, loff_t end, int datasync)
++{
++      return wdm_wait_for_response(file, MAX_SCHEDULE_TIMEOUT);
++}
++
++/*
++ * Same with wdm_fsync(), except it uses finite timeout in order to react to
++ * malicious or defective hardware which ceased communication after close() was
++ * implicitly called due to process termination.
++ */
++static int wdm_flush(struct file *file, fl_owner_t id)
++{
++      return wdm_wait_for_response(file, WDM_FLUSH_TIMEOUT);
+ }
+ static __poll_t wdm_poll(struct file *file, struct poll_table_struct *wait)
+@@ -729,6 +766,7 @@ static const struct file_operations wdm_
+       .owner =        THIS_MODULE,
+       .read =         wdm_read,
+       .write =        wdm_write,
++      .fsync =        wdm_fsync,
+       .open =         wdm_open,
+       .flush =        wdm_flush,
+       .release =      wdm_release,
diff --git a/queue-5.4/usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch b/queue-5.4/usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch
new file mode 100644 (file)
index 0000000..09df9bc
--- /dev/null
@@ -0,0 +1,88 @@
+From 98df91f8840cf750a0bc7c4c5d6b6085bac945b3 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Tue, 1 Sep 2020 10:35:49 +0800
+Subject: usb: cdns3: gadget: free interrupt after gadget has deleted
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit 98df91f8840cf750a0bc7c4c5d6b6085bac945b3 upstream.
+
+The interrupt may occur during the gadget deletion, it fixes the
+below oops.
+
+[ 2394.974604] configfs-gadget gadget: suspend
+[ 2395.042578] configfs-gadget 5b130000.usb: unregistering UDC driver [g1]
+[ 2395.382562] irq 229: nobody cared (try booting with the "irqpoll" option)
+[ 2395.389362] CPU: 0 PID: 301 Comm: kworker/u12:6 Not tainted 5.8.0-rc3-next-20200703-00060-g2f13b83cbf30-dirty #456
+[ 2395.399712] Hardware name: Freescale i.MX8QM MEK (DT)
+[ 2395.404782] Workqueue: 2-0051 tcpm_state_machine_work
+[ 2395.409832] Call trace:
+[ 2395.412289]  dump_backtrace+0x0/0x1d0
+[ 2395.415950]  show_stack+0x1c/0x28
+[ 2395.419271]  dump_stack+0xbc/0x118
+[ 2395.422678]  __report_bad_irq+0x50/0xe0
+[ 2395.426513]  note_interrupt+0x2cc/0x38c
+[ 2395.430355]  handle_irq_event_percpu+0x88/0x90
+[ 2395.434800]  handle_irq_event+0x4c/0xe8
+[ 2395.438640]  handle_fasteoi_irq+0xbc/0x168
+[ 2395.442740]  generic_handle_irq+0x34/0x48
+[ 2395.446752]  __handle_domain_irq+0x68/0xc0
+[ 2395.450846]  gic_handle_irq+0x64/0x150
+[ 2395.454596]  el1_irq+0xb8/0x180
+[ 2395.457733]  __do_softirq+0xac/0x3b8
+[ 2395.461310]  irq_exit+0xc0/0xe0
+[ 2395.464448]  __handle_domain_irq+0x6c/0xc0
+[ 2395.468540]  gic_handle_irq+0x64/0x150
+[ 2395.472295]  el1_irq+0xb8/0x180
+[ 2395.475436]  _raw_spin_unlock_irqrestore+0x14/0x48
+[ 2395.480232]  usb_gadget_disconnect+0x120/0x140
+[ 2395.484678]  usb_gadget_remove_driver+0xb4/0xd0
+[ 2395.489208]  usb_del_gadget+0x6c/0xc8
+[ 2395.492872]  cdns3_gadget_exit+0x5c/0x120
+[ 2395.496882]  cdns3_role_stop+0x60/0x90
+[ 2395.500634]  cdns3_role_set+0x64/0xd8
+[ 2395.504301]  usb_role_switch_set_role.part.0+0x3c/0x90
+[ 2395.509444]  usb_role_switch_set_role+0x20/0x30
+[ 2395.513978]  tcpm_mux_set+0x60/0xf8
+[ 2395.517470]  tcpm_reset_port+0xa4/0xf0
+[ 2395.521222]  tcpm_detach.part.0+0x44/0x50
+[ 2395.525227]  tcpm_state_machine_work+0x8b0/0x2360
+[ 2395.529932]  process_one_work+0x1c8/0x470
+[ 2395.533939]  worker_thread+0x50/0x420
+[ 2395.537603]  kthread+0x148/0x168
+[ 2395.540830]  ret_from_fork+0x10/0x18
+[ 2395.544399] handlers:
+[ 2395.546671] [<000000008dea28da>] cdns3_wakeup_irq
+[ 2395.551375] [<000000009fee5c61>] cdns3_drd_irq threaded [<000000005148eaec>] cdns3_drd_thread_irq
+[ 2395.560255] Disabling IRQ #229
+[ 2395.563454] configfs-gadget gadget: unbind function 'Mass Storage Function'/000000000132f835
+[ 2395.563657] configfs-gadget gadget: unbind
+[ 2395.563917] udc 5b130000.usb: releasing '5b130000.usb'
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Cc: <stable@vger.kernel.org>
+Acked-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/cdns3/gadget.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2545,12 +2545,12 @@ void cdns3_gadget_exit(struct cdns3 *cdn
+       priv_dev = cdns->gadget_dev;
+-      devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
+       pm_runtime_mark_last_busy(cdns->dev);
+       pm_runtime_put_autosuspend(cdns->dev);
+       usb_del_gadget_udc(&priv_dev->gadget);
++      devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
+       cdns3_free_all_eps(priv_dev);