From: Greg Kroah-Hartman Date: Tue, 27 Oct 2020 13:42:00 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.241~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68dc9a85be4b4459924235a504283d4186f349a9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches 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 --- 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 index 00000000000..0c69b8fe488 --- /dev/null +++ b/queue-5.4/eeprom-at25-set-minimum-read-write-access-stride-to-1.patch @@ -0,0 +1,31 @@ +From 284f52ac1c6cfa1b2e5c11b84653dd90e4e91de7 Mon Sep 17 00:00:00 2001 +From: Christian Eggers +Date: Tue, 28 Jul 2020 11:29:59 +0200 +Subject: eeprom: at25: set minimum read/write access stride to 1 + +From: Christian Eggers + +commit 284f52ac1c6cfa1b2e5c11b84653dd90e4e91de7 upstream. + +SPI eeproms are addressed by byte. + +Signed-off-by: Christian Eggers +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200728092959.24600-1-ceggers@arri.de +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-5.4/series b/queue-5.4/series index 02b38a4a5be..f1fcaf79f8b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -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 index 00000000000..4d86b77cab4 --- /dev/null +++ b/queue-5.4/tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch @@ -0,0 +1,35 @@ +From 29788ab1d2bf26c130de8f44f9553ee78a27e8d5 Mon Sep 17 00:00:00 2001 +From: Peng Fan +Date: Tue, 29 Sep 2020 17:55:09 +0800 +Subject: tty: serial: fsl_lpuart: fix lpuart32_poll_get_char + +From: Peng Fan + +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 +Signed-off-by: Peng Fan +Link: https://lore.kernel.org/r/20200929095509.21680-1-peng.fan@nxp.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7c3c26a798b --- /dev/null +++ b/queue-5.4/tty-serial-lpuart-fix-lpuart32_write-usage.patch @@ -0,0 +1,66 @@ +From 9ea40db477c024dcb87321b7f32bd6ea12130ac2 Mon Sep 17 00:00:00 2001 +From: Peng Fan +Date: Tue, 29 Sep 2020 17:19:20 +0800 +Subject: tty: serial: lpuart: fix lpuart32_write usage + +From: Peng Fan + +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 +Signed-off-by: Peng Fan +Link: https://lore.kernel.org/r/20200929091920.22612-1-peng.fan@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1e18db6b981 --- /dev/null +++ b/queue-5.4/usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch @@ -0,0 +1,340 @@ +From a4f88430af896bf34ec25a7a5f0e053fb3d928e0 Mon Sep 17 00:00:00 2001 +From: Vincent Mailhol +Date: Sat, 3 Oct 2020 00:41:51 +0900 +Subject: usb: cdc-acm: add quirk to blacklist ETAS ES58X devices + +From: Vincent Mailhol + +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 +Cc: stable +Link: https://lore.kernel.org/r/20201002154219.4887-8-mailhol.vincent@wanadoo.fr +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..e2a22b141ef --- /dev/null +++ b/queue-5.4/usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch @@ -0,0 +1,184 @@ +From 37d2a36394d954413a495da61da1b2a51ecd28ab Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Mon, 28 Sep 2020 23:17:55 +0900 +Subject: USB: cdc-wdm: Make wdm_flush() interruptible and add wdm_fsync(). + +From: Oliver Neukum + +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 +Cc: stable +Co-developed-by: Tetsuo Handa +Signed-off-by: Tetsuo Handa +Signed-off-by: Oliver Neukum +Cc: Alan Stern +Link: https://lore.kernel.org/r/20200928141755.3476-1-penguin-kernel@I-love.SAKURA.ne.jp +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..09df9bca501 --- /dev/null +++ b/queue-5.4/usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch @@ -0,0 +1,88 @@ +From 98df91f8840cf750a0bc7c4c5d6b6085bac945b3 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Tue, 1 Sep 2020 10:35:49 +0800 +Subject: usb: cdns3: gadget: free interrupt after gadget has deleted + +From: Peter Chen + +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: +Acked-by: Roger Quadros +Signed-off-by: Peter Chen +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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); +