--- /dev/null
+From 47b6bcef6e679593d2e86e04ee72c46a4e2f7139 Mon Sep 17 00:00:00 2001
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+Date: Mon, 22 Jun 2026 16:01:57 +0800
+Subject: net: usb: kalmia: bound RX frame length in kalmia_rx_fixup()
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+commit 47b6bcef6e679593d2e86e04ee72c46a4e2f7139 upstream.
+
+kalmia_rx_fixup() computes usb_packet_length = skb->len - (2 *
+KALMIA_HEADER_LENGTH) as a u16, guarded only by a pre-loop check that
+skb->len is at least KALMIA_HEADER_LENGTH, which is 6. A device can
+deliver a short bulk-IN frame with skb->len in the 6 to 11 range, or
+leave a short trailing remainder on a later loop iteration. Either case
+underflows usb_packet_length to about 65530.
+
+That bypasses the usb_packet_length < ether_packet_length truncation path.
+The device-supplied ether_packet_length, a le16 up to 65535 read from
+header_start[2], then drives a memcmp() and the following skb_trim() and
+skb_pull() past the end of the rx buffer. The rx buffer is hard_mtu * 10,
+which is 14000 bytes. That is an out of bounds read.
+
+Require both the start and end framing headers to be present before
+subtracting them, on every loop iteration.
+
+Fixes: d40261236e8e ("net/usb: Add Samsung Kalmia driver for Samsung GT-B3730")
+Cc: stable@vger.kernel.org
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/178211531778.2216480.12637613349790980750@maoyixie.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/kalmia.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/usb/kalmia.c
++++ b/drivers/net/usb/kalmia.c
+@@ -276,6 +276,14 @@ kalmia_rx_fixup(struct usbnet *dev, stru
+ "Received header: %6phC. Package length: %i\n",
+ header_start, skb->len - KALMIA_HEADER_LENGTH);
+
++ /* both framing headers must be present before we subtract
++ * them, otherwise usb_packet_length underflows and the
++ * device-supplied ether_packet_length drives an out of bounds
++ * access below
++ */
++ if (skb->len < 2 * KALMIA_HEADER_LENGTH)
++ return 0;
++
+ /* subtract start header and end header */
+ usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
+ ether_packet_length = get_unaligned_le16(&header_start[2]);
xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch
bpf-reject-fragmented-frames-in-devmap.patch
bpf-restore-sysctl-new-value-from-1-to-0.patch
+net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch
+usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch
+usb-cdnsp-fix-stream-context-array-leak-in-cdnsp_alloc_stream_info.patch
+usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch
+usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch
+usb-free-iso-schedules-on-failed-submit.patch
+usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch
+usb-gadget-udc-fix-use-after-free-in-gadget_match_driver.patch
+usb-gadget-f_printer-take-kref-only-for-successful-open.patch
+usb-idmouse-fix-use-after-free-on-disconnect-race.patch
+usb-ldusb-fix-use-after-free-on-disconnect-race.patch
+usb-iowarrior-fix-use-after-free-on-disconnect.patch
+usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch
+usb-legousbtower-fix-use-after-free-on-disconnect-race.patch
+usb-sl811-hcd-disable-controller-wakeup-on-remove.patch
+usb-storage-include-us_fl_no_same-in-quirks-mask.patch
+usb-misc-uss720-unregister-parport-on-probe-failure.patch
+usb-mtu3-unmap-request-dma-on-queue-failure.patch
+usb-serial-keyspan_pda-fix-information-leak.patch
+usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch
+usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch
+usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch
+usb-serial-digi_acceleport-fix-write-buffer-corruption.patch
+usb-ulpi-fix-memory-leak-on-registration-failure.patch
+usb-usb-storage-ene_ub6250-restore-media-ready-check.patch
+usbip-tools-support-superspeedplus-devices.patch
+usbip-vudc-fix-null-deref-in-vep_dequeue.patch
+usb-typec-anx7411-use-devm_pm_runtime_enable.patch
+usb-typec-class-drop-pd-lookup-reference.patch
+usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch
+usb-typec-ucsi-invert-displayport-role-assignment.patch
+usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch
+usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch
+usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch
--- /dev/null
+From 6eba58568f6cc3ff8515a00b05e258d8cfb72b72 Mon Sep 17 00:00:00 2001
+From: Jared Baldridge <jrb@expunge.us>
+Date: Sat, 30 May 2026 18:19:48 -0400
+Subject: usb: cdc_acm: Add quirk for Uniden BC125AT scanner
+
+From: Jared Baldridge <jrb@expunge.us>
+
+commit 6eba58568f6cc3ff8515a00b05e258d8cfb72b72 upstream.
+
+Uniden BC125AT radio scanner has a USB interface which fails to work
+with the cdc_acm driver:
+ usb 1-1: new full-speed USB device number 2 using uhci_hcd
+ cdc_acm 1-1:1.0: Zero length descriptor references
+ cdc_acm 1-1:1.0: probe with driver cdc_acm failed with error -22
+ usbcore: registered new interface driver cdc_acm
+
+Adding the NO_UNION_NORMAL quirk for the device fixes the issue:
+
+ usb 1-1: new full-speed USB device number 2 using uhci_hcd
+ cdc_acm 1-1:1.0: ttyACM0: USB ACM device
+ usbcore: registered new interface driver cdc_acm
+
+`lsusb -v` of the device:
+
+ Bus 001 Device 002: ID 1965:0017 Uniden Corporation BC125AT
+ Negotiated speed: Full Speed (12Mbps)
+ Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 2.00
+ bDeviceClass 2 Communications
+ bDeviceSubClass 0 [unknown]
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x1965 Uniden Corporation
+ idProduct 0x0017 BC125AT
+ bcdDevice 0.01
+ iManufacturer 1 Uniden America Corp.
+ iProduct 2 BC125AT
+ iSerial 3 0001
+ bNumConfigurations 1
+ Configuration Descriptor:
+ bLength 9
+ bDescriptorType 2
+ wTotalLength 0x0030
+ 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 0
+ iInterface 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x87 EP 7 IN
+ bmAttributes 3
+ Transfer Type Interrupt
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0008 1x 8 bytes
+ bInterval 10
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 1
+ bAlternateSetting 0
+ bNumEndpoints 2
+ bInterfaceClass 10 CDC Data
+ bInterfaceSubClass 0 [unknown]
+ 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 0x0040 1x 64 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 0x0040 1x 64 bytes
+ bInterval 0
+ Device Status: 0x0000
+ (Bus Powered)
+
+Signed-off-by: Jared Baldridge <jrb@expunge.us>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260530221959.612526-1-jrb@expunge.us
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1810,6 +1810,9 @@ static const struct usb_device_id acm_id
+ { USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI Controller */
+ .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */
+ },
++ { USB_DEVICE(0x1965, 0x0017), /* Uniden BC125AT */
++ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
++ },
+ { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
--- /dev/null
+From 3348f444a4ce43dd5c2d1aa41634cb6eff33aa64 Mon Sep 17 00:00:00 2001
+From: Haoxiang Li <haoxiang_li2024@163.com>
+Date: Mon, 22 Jun 2026 13:26:27 +0800
+Subject: usb: cdnsp: fix stream context array leak in cdnsp_alloc_stream_info()
+
+From: Haoxiang Li <haoxiang_li2024@163.com>
+
+commit 3348f444a4ce43dd5c2d1aa41634cb6eff33aa64 upstream.
+
+cdnsp_alloc_stream_info() allocates stream_info->stream_ctx_array with
+cdnsp_alloc_stream_ctx(). If a later stream ring allocation or stream
+mapping update fails, the error path frees the allocated stream rings
+and stream_rings array, but leaves stream_ctx_array allocated.
+
+Free the stream context array before falling through to the stream_rings
+cleanup path.
+
+Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://patch.msgid.link/20260622052627.696373-1-haoxiang_li2024@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdnsp-mem.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/cdns3/cdnsp-mem.c
++++ b/drivers/usb/cdns3/cdnsp-mem.c
+@@ -632,6 +632,8 @@ cleanup_rings:
+ }
+ }
+
++ cdnsp_free_stream_ctx(pdev, pep);
++
+ cleanup_stream_rings:
+ kfree(pep->stream_info.stream_rings);
+
--- /dev/null
+From bd728c3d9b1cc0bb0fda6a7055c5c8b55d7477b2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rodrigo=20Lugathe=20da=20Concei=C3=A7=C3=A3o=20Alves?=
+ <lugathe2@gmail.com>
+Date: Wed, 3 Jun 2026 08:36:26 -0300
+Subject: USB: core: add USB_QUIRK_NO_LPM for VIA Labs USB 2.0 hub
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rodrigo Lugathe da Conceição Alves <lugathe2@gmail.com>
+
+commit bd728c3d9b1cc0bb0fda6a7055c5c8b55d7477b2 upstream.
+
+The VIA Labs, Inc. USB 2.0 hub controller (2109:2817),
+found in a KVM switch, fails to enumerate high-power devices during
+cold boot and system restart.
+
+Applying the kernel parameter
+ usbcore.quirks=2109:2817:k
+resolves the issue.
+
+Enumeration failure log:
+ usb 1-1.2.3: device descriptor read/64, error -32
+ usb 1-1.2.3: Device not responding to setup address.
+ usb 1-1.2.3: device not accepting address 11, error -71
+ usb 1-1.2-port3: unable to enumerate USB device
+
+Add USB_QUIRK_NO_LPM for this device.
+
+Signed-off-by: Rodrigo Lugathe da Conceição Alves <lugathe2@gmail.com>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260603113626.395612-1-lugathe2@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/quirks.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -574,6 +574,9 @@ static const struct usb_device_id usb_qu
+ /* VLI disk */
+ { USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },
+
++ /* VIA Labs, Inc. USB2.0 Hub */
++ { USB_DEVICE(0x2109, 0x2817), .driver_info = USB_QUIRK_NO_LPM },
++
+ /* Raydium Touchscreen */
+ { USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
+
--- /dev/null
+From 692c354bef03b77b30e57e61934da502c8a12d45 Mon Sep 17 00:00:00 2001
+From: WenTao Liang <vulab@iscas.ac.cn>
+Date: Thu, 11 Jun 2026 21:11:21 +0800
+Subject: usb: dwc3: meson-g12a: fix refcount leak in dwc3_meson_g12a_resume()
+
+From: WenTao Liang <vulab@iscas.ac.cn>
+
+commit 692c354bef03b77b30e57e61934da502c8a12d45 upstream.
+
+If dwc3_meson_g12a_resume() succeeds in calling
+reset_control_reset(), an internal triggered_count reference is
+acquired. If any later step fails (usb_init, phy_init,
+phy_power_on, regulator_enable, or usb_post_init), the function
+returns the error without rearming the reset control. This leaks
+the reference and leaves the reset control in a triggered state,
+causing future reset_control_reset() calls to incorrectly return
+early as if already reset.
+
+Add an error path that calls reset_control_rearm() to balance
+the reference before returning the error.
+
+Cc: stable <stable@kernel.org>
+Fixes: 5b0ba0caaf3a ("usb: dwc3: meson-g12a: refactor usb init")
+Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260611131121.81784-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-meson-g12a.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
++++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
+@@ -907,35 +907,39 @@ static int __maybe_unused dwc3_meson_g12
+
+ ret = priv->drvdata->usb_init(priv);
+ if (ret)
+- return ret;
++ goto err_rearm;
+
+ /* Init PHYs */
+ for (i = 0 ; i < PHY_COUNT ; ++i) {
+ ret = phy_init(priv->phys[i]);
+ if (ret)
+- return ret;
++ goto err_rearm;
+ }
+
+ /* Set PHY Power */
+ for (i = 0 ; i < PHY_COUNT ; ++i) {
+ ret = phy_power_on(priv->phys[i]);
+ if (ret)
+- return ret;
++ goto err_rearm;
+ }
+
+ if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
+ ret = regulator_enable(priv->vbus);
+ if (ret)
+- return ret;
++ goto err_rearm;
+ }
+
+ if (priv->drvdata->usb_post_init) {
+ ret = priv->drvdata->usb_post_init(priv);
+ if (ret)
+- return ret;
++ goto err_rearm;
+ }
+
+ return 0;
++
++err_rearm:
++ reset_control_rearm(priv->reset);
++ return ret;
+ }
+
+ static const struct dev_pm_ops dwc3_meson_g12a_dev_pm_ops = {
--- /dev/null
+From b9399d25fbb34a05bbe76eeedd730f62ff2670e9 Mon Sep 17 00:00:00 2001
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+Date: Tue, 30 Jun 2026 15:14:19 +0800
+Subject: usb: free iso schedules on failed submit
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+commit b9399d25fbb34a05bbe76eeedd730f62ff2670e9 upstream.
+
+EHCI and FOTG210 isochronous submits build an ehci_iso_sched before
+linking the URB to the endpoint queue, and keep the staged schedule in
+urb->hcpriv until iso_stream_schedule() and the link helpers consume it.
+If the controller is no longer accessible, or usb_hcd_link_urb_to_ep()
+fails, submit jumps to done_not_linked before that handoff happens and
+leaks the staged schedule still attached to urb->hcpriv.
+
+Free the staged schedule from done_not_linked when submit fails before
+the URB is linked and clear urb->hcpriv after the free.
+
+The bug was first flagged by an experimental analysis tool we are
+developing for kernel memory-management bugs while analyzing
+v6.13-rc1. The tool is still under development and is not yet publicly
+available. Manual inspection confirms that the bug is still
+present in v7.1.1.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have an
+EHCI host controller with a USB isochronous device to test with, no
+runtime testing was able to be performed.
+
+Fixes: 8de98402652c ("[PATCH] USB: Fix USB suspend/resume crasher (#2)")
+Fixes: e9df41c5c589 ("USB: make HCDs responsible for managing endpoint queues")
+Fixes: 7d50195f6c50 ("usb: host: Faraday fotg210-hcd driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://patch.msgid.link/20260630071419.349161-1-dawei.feng@seu.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/fotg210/fotg210-hcd.c | 6 ++++--
+ drivers/usb/host/ehci-sched.c | 11 +++++++++--
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/fotg210/fotg210-hcd.c
++++ b/drivers/usb/fotg210/fotg210-hcd.c
+@@ -4271,8 +4271,6 @@ static int iso_stream_schedule(struct fo
+ return 0;
+
+ fail:
+- iso_sched_free(stream, sched);
+- urb->hcpriv = NULL;
+ return status;
+ }
+
+@@ -4566,6 +4564,10 @@ static int itd_submit(struct fotg210_hcd
+ else
+ usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+ done_not_linked:
++ if (status < 0) {
++ iso_sched_free(stream, urb->hcpriv);
++ urb->hcpriv = NULL;
++ }
+ spin_unlock_irqrestore(&fotg210->lock, flags);
+ done:
+ return status;
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1624,6 +1624,7 @@ iso_stream_schedule(
+ status = 1; /* and give it back immediately */
+ iso_sched_free(stream, sched);
+ sched = NULL;
++ urb->hcpriv = NULL;
+ }
+ }
+ urb->error_count = skip / period;
+@@ -1654,8 +1655,6 @@ iso_stream_schedule(
+ return status;
+
+ fail:
+- iso_sched_free(stream, sched);
+- urb->hcpriv = NULL;
+ return status;
+ }
+
+@@ -1967,6 +1966,10 @@ static int itd_submit(struct ehci_hcd *e
+ usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+ }
+ done_not_linked:
++ if (status < 0) {
++ iso_sched_free(stream, urb->hcpriv);
++ urb->hcpriv = NULL;
++ }
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ done:
+ return status;
+@@ -2344,6 +2347,10 @@ static int sitd_submit(struct ehci_hcd *
+ usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+ }
+ done_not_linked:
++ if (status < 0) {
++ iso_sched_free(stream, urb->hcpriv);
++ urb->hcpriv = NULL;
++ }
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ done:
+ return status;
--- /dev/null
+From f8f680609c2b3ab795ffcd6f21585b6dfc46d395 Mon Sep 17 00:00:00 2001
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+Date: Wed, 27 May 2026 23:08:32 +0800
+Subject: usb: gadget: composite: fix dead empty check in the USB_DT_OTG handler
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+commit f8f680609c2b3ab795ffcd6f21585b6dfc46d395 upstream.
+
+The OTG branch of composite_setup() falls back to the first
+configuration when none is selected:
+
+ if (cdev->config)
+ config = cdev->config;
+ else
+ config = list_first_entry(&cdev->configs,
+ struct usb_configuration, list);
+ if (!config)
+ goto done;
+ ...
+ memcpy(req->buf, config->descriptors[0], value);
+
+list_first_entry() never returns NULL. On an empty list it returns
+container_of() of the list head. So the "if (!config)" check is dead.
+
+When cdev->configs is empty, config points at the head inside struct
+usb_composite_dev. config->descriptors[0] reads whatever sits at that
+offset. The memcpy copies up to w_length bytes of it into the response
+buffer.
+
+cdev->configs can be empty in two cases. One is a teardown race on
+gadget unbind with a control transfer in flight. The other is a driver
+that sets is_otg before it adds a config. A reproducer that holds
+cdev->configs empty triggers a KASAN fault in this branch.
+
+Use list_first_entry_or_null() so the existing check does its job.
+
+Fixes: 53e6242db8d6 ("usb: gadget: composite: add USB_DT_OTG request handling")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Link: https://patch.msgid.link/20260527150832.2943293-1-maoyixie.tju@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/composite.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -1887,9 +1887,10 @@ composite_setup(struct usb_gadget *gadge
+ if (cdev->config)
+ config = cdev->config;
+ else
+- config = list_first_entry(
++ config = list_first_entry_or_null(
+ &cdev->configs,
+- struct usb_configuration, list);
++ struct usb_configuration,
++ list);
+ if (!config)
+ goto done;
+
--- /dev/null
+From 30adce93d5c4a5a1ec29d9249e3fdfcc391d406b Mon Sep 17 00:00:00 2001
+From: Xu Rao <raoxu@uniontech.com>
+Date: Fri, 26 Jun 2026 14:46:17 +0800
+Subject: usb: gadget: f_printer: take kref only for successful open
+
+From: Xu Rao <raoxu@uniontech.com>
+
+commit 30adce93d5c4a5a1ec29d9249e3fdfcc391d406b upstream.
+
+printer_open() returns -EBUSY when the character device is already
+open, but it increments dev->kref regardless of the return value. VFS
+does not call ->release() for a failed open, so every rejected second
+open permanently leaks one reference.
+
+Move kref_get() into the successful-open branch.
+
+Fixes: e8d5f92b8d30 ("usb: gadget: function: printer: fix use-after-free in __lock_acquire")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Xu Rao <raoxu@uniontech.com>
+Link: https://patch.msgid.link/80295742B820DA9B+20260626064617.4090626-1-raoxu@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_printer.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -363,12 +363,11 @@ printer_open(struct inode *inode, struct
+ ret = 0;
+ /* Change the printer status to show that it's on-line. */
+ dev->printer_status |= PRINTER_SELECTED;
++ kref_get(&dev->kref);
+ }
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- kref_get(&dev->kref);
+-
+ return ret;
+ }
+
--- /dev/null
+From 67e511d2989eb1c8c588b599ce2fcc6bb8e6f7ea Mon Sep 17 00:00:00 2001
+From: Jimmy Hu <hhhuuu@google.com>
+Date: Thu, 25 Jun 2026 15:37:04 +0800
+Subject: usb: gadget: udc: Fix use-after-free in gadget_match_driver
+
+From: Jimmy Hu <hhhuuu@google.com>
+
+commit 67e511d2989eb1c8c588b599ce2fcc6bb8e6f7ea upstream.
+
+The udc structure acts as the management structure for the gadget,
+but their lifecycles are decoupled. A race condition exists where
+usb_del_gadget() frees the udc memory (e.g., via mode-switch work)
+while gadget_match_driver() concurrently accesses the freed udc memory
+(e.g., via configfs), causing a Use-After-Free (UAF) that triggers a
+NULL pointer dereference when the freed memory is zeroed:
+
+[39430.908615][ T1171] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+[39430.911397][ T1171] pc : __pi_strcmp+0x20/0x140
+[39430.911441][ T1171] lr : gadget_match_driver+0x34/0x60
+...
+[39430.911890][ T1171] usb_gadget_register_driver_owner+0x50/0xf8
+[39430.911910][ T1171] gadget_dev_desc_UDC_store+0xf4/0x140
+[39430.931308][ T1171] configfs_write_iter+0xec/0x134
+
+[39430.957058][ T1171] Workqueue: events_freezable __dwc3_set_mode
+[39430.957287][ T1171] dwc3_gadget_exit+0x34/0x8c
+[39430.957304][ T1171] __dwc3_set_mode+0xc0/0x664
+
+Fix this by ensuring the udc structure remains allocated until the
+gadget is released. To achieve this, introduce a new
+usb_gadget_release() routine to the core. When the gadget is added,
+usb_add_gadget() stores the gadget's release routine in the udc
+structure and takes a reference to the udc. When the gadget is
+released, usb_gadget_release() drops the reference to the udc and
+then calls the gadget's release routine.
+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Jimmy Hu <hhhuuu@google.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://patch.msgid.link/20260625073705.803880-1-hhhuuu@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/core.c | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -31,8 +31,9 @@ static const struct bus_type gadget_bus_
+ /**
+ * struct usb_udc - describes one usb device controller
+ * @driver: the gadget driver pointer. For use by the class code
+- * @dev: the child device to the actual controller
+ * @gadget: the gadget. For use by the class code
++ * @gadget_release: the gadget's release routine
++ * @dev: the child device to the actual controller
+ * @list: for use by the udc class driver
+ * @vbus: for udcs who care about vbus status, this value is real vbus status;
+ * for udcs who do not care about vbus status, this value is always true
+@@ -53,6 +54,7 @@ static const struct bus_type gadget_bus_
+ struct usb_udc {
+ struct usb_gadget_driver *driver;
+ struct usb_gadget *gadget;
++ void (*gadget_release)(struct device *dev);
+ struct device dev;
+ struct list_head list;
+ bool vbus;
+@@ -1351,6 +1353,17 @@ static void usb_udc_nop_release(struct d
+ dev_vdbg(dev, "%s\n", __func__);
+ }
+
++static void usb_gadget_release(struct device *dev)
++{
++ struct usb_gadget *gadget = dev_to_usb_gadget(dev);
++ struct usb_udc *udc = gadget->udc;
++ /* Cache the gadget's release routine to prevent UAF */
++ void (*release)(struct device *dev) = udc->gadget_release;
++
++ put_device(&udc->dev);
++ release(dev);
++}
++
+ /**
+ * usb_initialize_gadget - initialize a gadget and its embedded struct device
+ * @parent: the parent device to this udc. Usually the controller driver's
+@@ -1407,6 +1420,14 @@ int usb_add_gadget(struct usb_gadget *ga
+ mutex_init(&udc->connect_lock);
+
+ udc->started = false;
++ /*
++ * Align decoupled lifecycles: take a UDC reference to ensure it
++ * remains allocated until the gadget is released, requiring an
++ * override of the gadget's release routine to drop it.
++ */
++ udc->gadget_release = gadget->dev.release;
++ gadget->dev.release = usb_gadget_release;
++ get_device(&udc->dev);
+
+ mutex_lock(&udc_lock);
+ list_add_tail(&udc->list, &udc_list);
+@@ -1451,6 +1472,12 @@ int usb_add_gadget(struct usb_gadget *ga
+ mutex_lock(&udc_lock);
+ list_del(&udc->list);
+ mutex_unlock(&udc_lock);
++ /*
++ * Revert the override and drop the UDC reference to prevent
++ * leaking the UDC if the gadget was statically allocated.
++ */
++ gadget->dev.release = udc->gadget_release;
++ put_device(&udc->dev);
+
+ err_put_udc:
+ put_device(&udc->dev);
--- /dev/null
+From ff002c153f9722caece3983cc23dc4d9d4652cb4 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 22 Jun 2026 17:26:10 +0200
+Subject: USB: idmouse: fix use-after-free on disconnect race
+
+From: Johan Hovold <johan@kernel.org>
+
+commit ff002c153f9722caece3983cc23dc4d9d4652cb4 upstream.
+
+mutex_unlock() may access the mutex structure after releasing the lock
+and therefore cannot be used to manage lifetime of objects directly
+(unlike spinlocks and refcounts). [1][2]
+
+Use a kref to release the driver data to avoid use-after-free in
+mutex_unlock() when release() races with disconnect().
+
+[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
+ non-atomic")
+[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
+ other sleeping locks, can still use the lock object
+ after it's unlocked")
+
+Fixes: 54d2bc068fd2 ("USB: fix locking in idmouse")
+Cc: stable@vger.kernel.org # 2.6.24
+Cc: Oliver Neukum <oliver@neukum.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260622152612.116422-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/idmouse.c | 45 ++++++++++++++++++++++-----------------------
+ 1 file changed, 22 insertions(+), 23 deletions(-)
+
+--- a/drivers/usb/misc/idmouse.c
++++ b/drivers/usb/misc/idmouse.c
+@@ -63,6 +63,7 @@ MODULE_DEVICE_TABLE(usb, idmouse_table);
+
+ /* structure to hold all of our device specific stuff */
+ struct usb_idmouse {
++ struct kref kref;
+
+ struct usb_device *udev; /* save off the usb device pointer */
+ struct usb_interface *interface; /* the interface for this device */
+@@ -209,8 +210,10 @@ static int idmouse_resume(struct usb_int
+ return 0;
+ }
+
+-static inline void idmouse_delete(struct usb_idmouse *dev)
++static inline void idmouse_delete(struct kref *kref)
+ {
++ struct usb_idmouse *dev = container_of(kref, struct usb_idmouse, kref);
++
+ kfree(dev->bulk_in_buffer);
+ kfree(dev);
+ }
+@@ -254,6 +257,8 @@ static int idmouse_open(struct inode *in
+ /* increment our usage count for the driver */
+ ++dev->open;
+
++ kref_get(&dev->kref);
++
+ /* save our object in the file's private structure */
+ file->private_data = dev;
+
+@@ -277,16 +282,11 @@ static int idmouse_release(struct inode
+
+ /* lock our device */
+ mutex_lock(&dev->lock);
+-
+ --dev->open;
++ mutex_unlock(&dev->lock);
++
++ kref_put(&dev->kref, idmouse_delete);
+
+- if (!dev->present) {
+- /* the device was unplugged before the file was released */
+- mutex_unlock(&dev->lock);
+- idmouse_delete(dev);
+- } else {
+- mutex_unlock(&dev->lock);
+- }
+ return 0;
+ }
+
+@@ -334,6 +334,7 @@ static int idmouse_probe(struct usb_inte
+ if (dev == NULL)
+ return -ENOMEM;
+
++ kref_init(&dev->kref);
+ mutex_init(&dev->lock);
+ dev->udev = udev;
+ dev->interface = interface;
+@@ -342,8 +343,7 @@ static int idmouse_probe(struct usb_inte
+ result = usb_find_bulk_in_endpoint(iface_desc, &endpoint);
+ if (result) {
+ dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
+- idmouse_delete(dev);
+- return result;
++ goto err_put_kref;
+ }
+
+ dev->orig_bi_size = usb_endpoint_maxp(endpoint);
+@@ -351,8 +351,8 @@ static int idmouse_probe(struct usb_inte
+ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+ dev->bulk_in_buffer = kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
+ if (!dev->bulk_in_buffer) {
+- idmouse_delete(dev);
+- return -ENOMEM;
++ result = -ENOMEM;
++ goto err_put_kref;
+ }
+
+ /* allow device read, write and ioctl */
+@@ -364,14 +364,18 @@ static int idmouse_probe(struct usb_inte
+ if (result) {
+ /* something prevented us from registering this device */
+ dev_err(&interface->dev, "Unable to allocate minor number.\n");
+- idmouse_delete(dev);
+- return result;
++ goto err_put_kref;
+ }
+
+ /* be noisy */
+ dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
+
+ return 0;
++
++err_put_kref:
++ kref_put(&dev->kref, idmouse_delete);
++
++ return result;
+ }
+
+ static void idmouse_disconnect(struct usb_interface *interface)
+@@ -387,14 +391,9 @@ static void idmouse_disconnect(struct us
+ /* prevent device read, write and ioctl */
+ dev->present = 0;
+
+- /* if the device is opened, idmouse_release will clean this up */
+- if (!dev->open) {
+- mutex_unlock(&dev->lock);
+- idmouse_delete(dev);
+- } else {
+- /* unlock */
+- mutex_unlock(&dev->lock);
+- }
++ mutex_unlock(&dev->lock);
++
++ kref_put(&dev->kref, idmouse_delete);
+
+ dev_info(&interface->dev, "disconnected\n");
+ }
--- /dev/null
+From bc0e4f16c44e50daa0b1ea729934baa3b4815dee Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Sat, 23 May 2026 19:05:23 +0200
+Subject: USB: iowarrior: fix use-after-free on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit bc0e4f16c44e50daa0b1ea729934baa3b4815dee upstream.
+
+Submitted write URBs are not stopped on close() and therefore need to be
+stopped unconditionally on disconnect() to avoid use-after-free in the
+completion handler.
+
+Fixes: b5f8d46867ca ("USB: iowarrior: fix use-after-free after driver unbind")
+Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
+Reported-by: syzbot+ad2aac2febc3bedf0962@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/6a0ce39b.170a0220.39a13.0007.GAE@google.com/
+Cc: stable <stable@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260523170523.1074563-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/iowarrior.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -920,13 +920,15 @@ static void iowarrior_disconnect(struct
+ /* prevent device read, write and ioctl */
+ dev->present = 0;
+
++ /* write urbs are not stopped on close() so kill unconditionally */
++ usb_kill_anchored_urbs(&dev->submitted);
++
+ if (dev->opened) {
+ /* There is a process that holds a filedescriptor to the device ,
+ so we only shutdown read-/write-ops going on.
+ Deleting the device is postponed until close() was called.
+ */
+ usb_kill_urb(dev->int_in_urb);
+- usb_kill_anchored_urbs(&dev->submitted);
+ wake_up_interruptible(&dev->read_wait);
+ wake_up_interruptible(&dev->write_wait);
+ mutex_unlock(&dev->mutex);
--- /dev/null
+From 19bdfc7b3c179331eafa423d87e1336f43bbfeb8 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 22 Jun 2026 17:26:11 +0200
+Subject: USB: ldusb: fix use-after-free on disconnect race
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 19bdfc7b3c179331eafa423d87e1336f43bbfeb8 upstream.
+
+mutex_unlock() may access the mutex structure after releasing the lock
+and therefore cannot be used to manage lifetime of objects directly
+(unlike spinlocks and refcounts). [1][2]
+
+Use a kref to release the driver data to avoid use-after-free in
+mutex_unlock() when release() races with disconnect().
+
+[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
+ non-atomic")
+[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
+ other sleeping locks, can still use the lock object
+ after it's unlocked")
+
+Fixes: ce0d7d3f575f ("usb: ldusb: ld_usb semaphore to mutex")
+Cc: stable <stable@kernel.org>
+Cc: Daniel Walker <dwalker@mvista.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260622152612.116422-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/ldusb.c | 38 ++++++++++++++++++--------------------
+ 1 file changed, 18 insertions(+), 20 deletions(-)
+
+--- a/drivers/usb/misc/ldusb.c
++++ b/drivers/usb/misc/ldusb.c
+@@ -150,6 +150,7 @@ MODULE_PARM_DESC(min_interrupt_out_inter
+
+ /* Structure to hold all of our device specific stuff */
+ struct ld_usb {
++ struct kref kref;
+ struct mutex mutex; /* locks this structure */
+ struct usb_interface *intf; /* save off the usb interface pointer */
+ unsigned long disconnected:1;
+@@ -201,8 +202,10 @@ static void ld_usb_abort_transfers(struc
+ /*
+ * ld_usb_delete
+ */
+-static void ld_usb_delete(struct ld_usb *dev)
++static void ld_usb_delete(struct kref *kref)
+ {
++ struct ld_usb *dev = container_of(kref, struct ld_usb, kref);
++
+ /* free data structures */
+ usb_free_urb(dev->interrupt_in_urb);
+ usb_free_urb(dev->interrupt_out_urb);
+@@ -355,6 +358,8 @@ static int ld_usb_open(struct inode *ino
+ goto unlock_exit;
+ }
+
++ kref_get(&dev->kref);
++
+ /* save device in the file's private structure */
+ file->private_data = dev;
+
+@@ -381,17 +386,8 @@ static int ld_usb_release(struct inode *
+
+ mutex_lock(&dev->mutex);
+
+- if (dev->open_count != 1) {
+- retval = -ENODEV;
++ if (dev->disconnected)
+ goto unlock_exit;
+- }
+- if (dev->disconnected) {
+- /* the device was unplugged before the file was released */
+- mutex_unlock(&dev->mutex);
+- /* unlock here as ld_usb_delete frees dev */
+- ld_usb_delete(dev);
+- goto exit;
+- }
+
+ /* wait until write transfer is finished */
+ if (dev->interrupt_out_busy)
+@@ -401,7 +397,7 @@ static int ld_usb_release(struct inode *
+
+ unlock_exit:
+ mutex_unlock(&dev->mutex);
+-
++ kref_put(&dev->kref, ld_usb_delete);
+ exit:
+ return retval;
+ }
+@@ -660,6 +656,8 @@ static int ld_usb_probe(struct usb_inter
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ goto exit;
++
++ kref_init(&dev->kref);
+ mutex_init(&dev->mutex);
+ spin_lock_init(&dev->rbsl);
+ dev->intf = intf;
+@@ -741,7 +739,7 @@ exit:
+ return retval;
+
+ error:
+- ld_usb_delete(dev);
++ kref_put(&dev->kref, ld_usb_delete);
+
+ return retval;
+ }
+@@ -769,18 +767,18 @@ static void ld_usb_disconnect(struct usb
+
+ mutex_lock(&dev->mutex);
+
+- /* if the device is not opened, then we clean up right now */
+- if (!dev->open_count) {
+- mutex_unlock(&dev->mutex);
+- ld_usb_delete(dev);
+- } else {
+- dev->disconnected = 1;
++ dev->disconnected = 1;
++
++ if (dev->open_count) {
+ /* wake up pollers */
+ wake_up_interruptible_all(&dev->read_wait);
+ wake_up_interruptible_all(&dev->write_wait);
+- mutex_unlock(&dev->mutex);
+ }
+
++ mutex_unlock(&dev->mutex);
++
++ kref_put(&dev->kref, ld_usb_delete);
++
+ dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
+ (minor - USB_LD_MINOR_BASE));
+ }
--- /dev/null
+From 62fc8eb1b1481051f7bab4aa93d79809053dd09f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 22 Jun 2026 17:26:12 +0200
+Subject: USB: legousbtower: fix use-after-free on disconnect race
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 62fc8eb1b1481051f7bab4aa93d79809053dd09f upstream.
+
+mutex_unlock() may access the mutex structure after releasing the lock
+and therefore cannot be used to manage lifetime of objects directly
+(unlike spinlocks and refcounts). [1][2]
+
+Use a kref to release the driver data to avoid use-after-free in
+mutex_unlock() when release() races with disconnect().
+
+[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
+ non-atomic")
+[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
+ other sleeping locks, can still use the lock object
+ after it's unlocked")
+
+Fixes: 18bcbcfe9ca2 ("USB: misc: legousbtower: semaphore to mutex")
+Cc: stable <stable@kernel.org>
+Cc: Daniel Walker <dwalker@mvista.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260622152612.116422-5-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/legousbtower.c | 37 +++++++++++++++++++------------------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -185,6 +185,7 @@ MODULE_DEVICE_TABLE(usb, tower_table);
+
+ /* Structure to hold all of our device specific stuff */
+ struct lego_usb_tower {
++ struct kref kref;
+ struct mutex lock; /* locks this structure */
+ struct usb_device *udev; /* save off the usb device pointer */
+ unsigned char minor; /* the starting minor number for this device */
+@@ -220,7 +221,6 @@ struct lego_usb_tower {
+ /* local function prototypes */
+ static ssize_t tower_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos);
+ static ssize_t tower_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
+-static inline void tower_delete(struct lego_usb_tower *dev);
+ static int tower_open(struct inode *inode, struct file *file);
+ static int tower_release(struct inode *inode, struct file *file);
+ static __poll_t tower_poll(struct file *file, poll_table *wait);
+@@ -286,8 +286,10 @@ static inline void lego_usb_tower_debug_
+ /*
+ * tower_delete
+ */
+-static inline void tower_delete(struct lego_usb_tower *dev)
++static inline void tower_delete(struct kref *kref)
+ {
++ struct lego_usb_tower *dev = container_of(kref, struct lego_usb_tower, kref);
++
+ /* free data structures */
+ usb_free_urb(dev->interrupt_in_urb);
+ usb_free_urb(dev->interrupt_out_urb);
+@@ -381,6 +383,8 @@ static int tower_open(struct inode *inod
+
+ dev->open_count = 1;
+
++ kref_get(&dev->kref);
++
+ unlock_exit:
+ mutex_unlock(&dev->lock);
+
+@@ -404,14 +408,8 @@ static int tower_release(struct inode *i
+
+ mutex_lock(&dev->lock);
+
+- if (dev->disconnected) {
+- /* the device was unplugged before the file was released */
+-
+- /* unlock here as tower_delete frees dev */
+- mutex_unlock(&dev->lock);
+- tower_delete(dev);
+- goto exit;
+- }
++ if (dev->disconnected)
++ goto out_unlock;
+
+ /* wait until write transfer is finished */
+ if (dev->interrupt_out_busy) {
+@@ -425,7 +423,9 @@ static int tower_release(struct inode *i
+
+ dev->open_count = 0;
+
++out_unlock:
+ mutex_unlock(&dev->lock);
++ kref_put(&dev->kref, tower_delete);
+ exit:
+ return retval;
+ }
+@@ -752,6 +752,7 @@ static int tower_probe(struct usb_interf
+ if (!dev)
+ goto exit;
+
++ kref_init(&dev->kref);
+ mutex_init(&dev->lock);
+ dev->udev = usb_get_dev(udev);
+ spin_lock_init(&dev->read_buffer_lock);
+@@ -828,7 +829,7 @@ exit:
+ return retval;
+
+ error:
+- tower_delete(dev);
++ kref_put(&dev->kref, tower_delete);
+ return retval;
+ }
+
+@@ -856,18 +857,18 @@ static void tower_disconnect(struct usb_
+
+ mutex_lock(&dev->lock);
+
+- /* if the device is not opened, then we clean up right now */
+- if (!dev->open_count) {
+- mutex_unlock(&dev->lock);
+- tower_delete(dev);
+- } else {
+- dev->disconnected = 1;
++ dev->disconnected = 1;
++
++ if (dev->open_count) {
+ /* wake up pollers */
+ wake_up_interruptible_all(&dev->read_wait);
+ wake_up_interruptible_all(&dev->write_wait);
+- mutex_unlock(&dev->lock);
+ }
+
++ mutex_unlock(&dev->lock);
++
++ kref_put(&dev->kref, tower_delete);
++
+ dev_info(&interface->dev, "LEGO USB Tower #%d now disconnected\n",
+ (minor - LEGO_USB_TOWER_MINOR_BASE));
+ }
--- /dev/null
+From b4ecbdc4f8830f5586c4a5cfc384c00f20f8f8b3 Mon Sep 17 00:00:00 2001
+From: Myeonghun Pak <mhun512@gmail.com>
+Date: Tue, 7 Jul 2026 00:10:49 +0900
+Subject: USB: misc: uss720: unregister parport on probe failure
+
+From: Myeonghun Pak <mhun512@gmail.com>
+
+commit b4ecbdc4f8830f5586c4a5cfc384c00f20f8f8b3 upstream.
+
+uss720_probe() registers a parport before reading the 1284 register used
+to detect unsupported Belkin F5U002 adapters. If get_1284_register()
+fails, the error path drops the driver private data and the USB device
+reference, but leaves the parport device registered.
+
+Leaving the port registered is more than a private allocation leak:
+parport_register_port() has already reserved a parport number and
+registered the parport bus device, while pp->private_data still points at
+the private data that the common error path is about to release.
+
+Undo the pre-announce registration in the get_1284_register() failure
+branch before jumping to the common private-data cleanup path. Clear
+priv->pp first, matching the disconnect path and avoiding a stale pointer
+in the private data.
+
+This issue was identified during our ongoing static-analysis research while
+reviewing kernel code.
+
+Fixes: 3295f1b866bf ("usb: misc: uss720: check for incompatible versions of the Belkin F5U002")
+Cc: stable <stable@kernel.org>
+Co-developed-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
+Reviewed-by: Alex Henrie <alexhenrie24@gmail.com>
+Link: https://patch.msgid.link/20260706151049.63470-1-mhun512@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/uss720.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/uss720.c
++++ b/drivers/usb/misc/uss720.c
+@@ -732,8 +732,11 @@ static int uss720_probe(struct usb_inter
+ * here. */
+ ret = get_1284_register(pp, 0, ®, GFP_KERNEL);
+ dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg);
+- if (ret < 0)
++ if (ret < 0) {
++ priv->pp = NULL;
++ parport_del_port(pp);
+ goto probe_abort;
++ }
+
+ ret = usb_find_last_int_in_endpoint(interface, &epd);
+ if (!ret) {
--- /dev/null
+From 0bddda5a11665c210339de76d27ebbd1a2e0b43c Mon Sep 17 00:00:00 2001
+From: Haoxiang Li <haoxiang_li2024@163.com>
+Date: Tue, 23 Jun 2026 17:33:25 +0800
+Subject: usb: mtu3: unmap request DMA on queue failure
+
+From: Haoxiang Li <haoxiang_li2024@163.com>
+
+commit 0bddda5a11665c210339de76d27ebbd1a2e0b43c upstream.
+
+mtu3_gadget_queue() maps the request before checking whether
+the QMU GPD ring can accept another transfer. the request is
+returned with -EAGAIN before it is linked on the endpoint
+request list if mtu3_prepare_transfer() fails.
+
+Normal completion and dequeue paths unmap requests from
+mtu3_req_complete(), but this error path never reaches that
+helper, so the DMA mapping is left active. Unmap the request
+before returning from the failed queue path.
+
+Fixes: df2069acb005 ("usb: Add MediaTek USB3 DRD driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
+Link: https://patch.msgid.link/20260623093325.2105323-1-haoxiang_li2024@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/mtu3/mtu3_gadget.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/mtu3/mtu3_gadget.c
++++ b/drivers/usb/mtu3/mtu3_gadget.c
+@@ -304,6 +304,7 @@ static int mtu3_gadget_queue(struct usb_
+
+ if (mtu3_prepare_transfer(mep)) {
+ ret = -EAGAIN;
++ usb_gadget_unmap_request(&mtu->g, req, mep->is_in);
+ goto error;
+ }
+
--- /dev/null
+From fc591787785b9709a0bb65a7df3ba2537d611c47 Mon Sep 17 00:00:00 2001
+From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
+Date: Tue, 2 Jun 2026 14:45:08 -0600
+Subject: USB: quirks: add NO_LPM for the Samsung T5 EVO Portable SSD
+
+From: Erich E. Hoover <erich.e.hoover@gmail.com>
+
+commit fc591787785b9709a0bb65a7df3ba2537d611c47 upstream.
+
+The Samsung T5 EVO Portable SSD (04e8:6200) exhibit two forms of
+link instability when USB Link Power Management is enabled:
+
+ 1. The units fail to initialize properly on first detection,
+ resulting in a lockup in the drive where it must be power cycled
+ or the kernel will not recognize the presence of the device.
+
+ 2. If used for sustained operations (small amounts of continuous
+ data are transferred to the unit) then the unit will "hiccup"
+ after roughly 8 hours of use and will disconnect and reconnect.
+ This has a certain probability of triggering the first issue,
+ but also causes mount points to become invalid since the device
+ gets issued a new letter.
+
+Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260602204508.48856-1-erich.e.hoover@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/quirks.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -297,6 +297,9 @@ static const struct usb_device_id usb_qu
+ /* CarrolTouch 4500U */
+ { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
+
++ /* Samsung T5 EVO Portable SSD */
++ { USB_DEVICE(0x04e8, 0x6200), .driver_info = USB_QUIRK_NO_LPM },
++
+ /* Samsung Android phone modem - ID conflict with SPH-I500 */
+ { USB_DEVICE(0x04e8, 0x6601), .driver_info =
+ USB_QUIRK_CONFIG_INTF_STRINGS },
--- /dev/null
+From 83a3dfc018943b05b6daf3a6f891833e1aabfa1f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 23 Jun 2026 17:08:15 +0200
+Subject: USB: serial: digi_acceleport: fix broken rx after throttle
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 83a3dfc018943b05b6daf3a6f891833e1aabfa1f upstream.
+
+If the port is closed while throttled, the read urb is never resubmitted
+and the port will not receive any further data until the device is
+reconnected (or the driver is rebound).
+
+Clear the throttle flags and submit the urb if needed when opening the
+port.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+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/digi_acceleport.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -1073,6 +1073,7 @@ static int digi_open(struct tty_struct *
+ unsigned char buf[32];
+ struct digi_port *priv = usb_get_serial_port_data(port);
+ struct ktermios not_termios;
++ int throttled;
+
+ /* be sure the device is started up */
+ if (digi_startup_device(port->serial) != 0)
+@@ -1100,6 +1101,21 @@ static int digi_open(struct tty_struct *
+ not_termios.c_iflag = ~tty->termios.c_iflag;
+ digi_set_termios(tty, port, ¬_termios);
+ }
++
++ spin_lock_irq(&priv->dp_port_lock);
++ throttled = priv->dp_throttle_restart;
++ priv->dp_throttled = 0;
++ priv->dp_throttle_restart = 0;
++ spin_unlock_irq(&priv->dp_port_lock);
++
++ if (throttled) {
++ ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
++ if (ret) {
++ dev_err(&port->dev, "failed to submit read urb: %d\n", ret);
++ return ret;
++ }
++ }
++
+ return 0;
+ }
+
--- /dev/null
+From 5c1ea24b53bf3bfb859f0a05573997487975da23 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 23 Jun 2026 17:11:10 +0200
+Subject: USB: serial: digi_acceleport: fix hard lockup on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5c1ea24b53bf3bfb859f0a05573997487975da23 upstream.
+
+If submitting the OOB write urb fails persistently (e.g if the device is
+being disconnected) the driver would loop indefinitely with interrupts
+disabled.
+
+Check for urb submission errors when sending OOB commands to avoid
+hanging if, for example, open(), set_termios() or close() races with a
+physical disconnect.
+
+This is issue was flagged by Sashiko when reviewing an unrelated change
+to the driver.
+
+Link: https://sashiko.dev/#/patchset/20260610132232.356139-1-johan%40kernel.org?part=1
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/digi_acceleport.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -396,12 +396,14 @@ static int digi_write_oob_command(struct
+ len &= ~3;
+ memcpy(oob_port->write_urb->transfer_buffer, buf, len);
+ oob_port->write_urb->transfer_buffer_length = len;
++
+ ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
+- if (ret == 0) {
+- oob_priv->dp_write_urb_in_use = 1;
+- count -= len;
+- buf += len;
+- }
++ if (ret)
++ break;
++
++ oob_priv->dp_write_urb_in_use = 1;
++ count -= len;
++ buf += len;
+ }
+ spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
+ if (ret)
--- /dev/null
+From 24ca1fea8f2753bf33e1d458ec1ae5d9b7796a65 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 23 Jun 2026 17:12:29 +0200
+Subject: USB: serial: digi_acceleport: fix write buffer corruption
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 24ca1fea8f2753bf33e1d458ec1ae5d9b7796a65 upstream.
+
+The digi_write_inb_command() is supposed to wait for the write urb to
+become available or return an error, but instead it updates the transfer
+buffer and tries to resubmit the urb on timeout.
+
+To make things worse, for commands like break control where no timeout
+is used, the driver would corrupt the urb immediately due to a broken
+jiffies comparison (on 32-bit machines this takes five minutes of uptime
+to trigger due to INITIAL_JIFFIES).
+
+Fix this by adding the missing return on timeout and waiting
+indefinitely when no timeout has been specified as intended.
+
+This issue was (sort of) flagged by Sashiko when reviewing an unrelated
+change to the driver.
+
+Link: https://sashiko.dev/#/patchset/20260610132232.356139-1-johan%40kernel.org?part=11
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/digi_acceleport.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -433,20 +433,22 @@ static int digi_write_inb_command(struct
+ int len;
+ struct digi_port *priv = usb_get_serial_port_data(port);
+ unsigned char *data = port->write_urb->transfer_buffer;
++ unsigned long expire;
+ unsigned long flags;
+
+ dev_dbg(&port->dev, "digi_write_inb_command: TOP: port=%d, count=%d\n",
+ priv->dp_port_num, count);
+
+ if (timeout)
+- timeout += jiffies;
+- else
+- timeout = ULONG_MAX;
++ expire = jiffies + timeout;
+
+ spin_lock_irqsave(&priv->dp_port_lock, flags);
+ while (count > 0 && ret == 0) {
+- while (priv->dp_write_urb_in_use &&
+- time_before(jiffies, timeout)) {
++ while (priv->dp_write_urb_in_use) {
++ if (timeout && time_after(jiffies, expire)) {
++ ret = -ETIMEDOUT;
++ break;
++ }
+ cond_wait_interruptible_timeout_irqrestore(
+ &priv->write_wait, DIGI_RETRY_TIMEOUT,
+ &priv->dp_port_lock, flags);
+@@ -455,6 +457,9 @@ static int digi_write_inb_command(struct
+ spin_lock_irqsave(&priv->dp_port_lock, flags);
+ }
+
++ if (ret)
++ break;
++
+ /* len must be a multiple of 4 and small enough to */
+ /* guarantee the write will send buffered data first, */
+ /* so commands are in order with data and not split */
--- /dev/null
+From 6bfc8d01ac4068eced509f8fc74d0cd205e4dcec Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 29 Jun 2026 14:45:26 +0200
+Subject: USB: serial: keyspan_pda: fix information leak
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 6bfc8d01ac4068eced509f8fc74d0cd205e4dcec upstream.
+
+The write() callback is supposed to return the number of characters
+accepted or a negative errno. Since the addition of write fifo support
+the keyspan_pda implementation will however return the number characters
+submitted to the device if the write urb is not already in use. If this
+number is larger than the number of characters passed to write(), the
+line discipline continues writing data from beyond the tty write buffer.
+
+Fix the information leak by making sure that keyspan_pda_write_start()
+returns zero on success as intended.
+
+Fixes: 034e38e8f687 ("USB: serial: keyspan_pda: add write-fifo support")
+Cc: stable@vger.kernel.org # 5.11
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/keyspan_pda.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/keyspan_pda.c
++++ b/drivers/usb/serial/keyspan_pda.c
+@@ -518,7 +518,7 @@ static int keyspan_pda_write_start(struc
+ if (count == room)
+ schedule_work(&priv->unthrottle_work);
+
+- return count;
++ return 0;
+ }
+
+ static void keyspan_pda_write_bulk_callback(struct urb *urb)
--- /dev/null
+From b33ab1dd80f5c1742f49eb6ec7b337c5ffcf3d32 Mon Sep 17 00:00:00 2001
+From: Fabio Porcedda <fabio.porcedda@gmail.com>
+Date: Fri, 12 Jun 2026 13:39:16 +0200
+Subject: USB: serial: option: add Telit Cinterion FE990D50 compositions
+
+From: Fabio Porcedda <fabio.porcedda@gmail.com>
+
+commit b33ab1dd80f5c1742f49eb6ec7b337c5ffcf3d32 upstream.
+
+Add support for Telit Cinterion FE990D50 compositions:
+
+0x990: RNDIS + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
+ tty (diag) + ADPL + adb
+T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 3 Spd=480 MxCh= 0
+D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=1bc7 ProdID=0990 Rev=06.06
+S: Manufacturer=Telit Cinterion
+S: Product=FE990
+S: SerialNumber=90b6a3ed
+C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA
+I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host
+E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
+I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
+E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
+E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+0x991: rmnet + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
+ tty (diag) + ADPL + adb
+T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 9 Spd=480 MxCh= 0
+D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=1bc7 ProdID=0991 Rev=06.06
+S: Manufacturer=Telit Cinterion
+S: Product=FE990
+S: SerialNumber=90b6a3ed
+C: #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA
+I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=(none)
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
+I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
+E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
+E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+0x992: MBIM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
+ tty (diag) + ADPL + adb
+T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 12 Spd=480 MxCh= 0
+D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=1bc7 ProdID=0992 Rev=06.06
+S: Manufacturer=Telit Cinterion
+S: Product=FE990
+S: SerialNumber=90b6a3ed
+C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA
+I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim
+E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
+E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
+E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+0x993: ECM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
+ tty (diag) + ADPL + adb
+T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 15 Spd=480 MxCh= 0
+D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=1bc7 ProdID=0993 Rev=06.06
+S: Manufacturer=Telit Cinterion
+S: Product=FE990
+S: SerialNumber=90b6a3ed
+C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA
+I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether
+E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
+E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
+E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/option.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1326,6 +1326,22 @@ static const struct usb_device_id option
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x30), /* Telit FE990D50 (RNDIS) */
++ .driver_info = NCTRL(6) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x60) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x30), /* Telit FE990D50 (rmnet) */
++ .driver_info = NCTRL(5) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x60) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x30), /* Telit FE990D50 (MBIM) */
++ .driver_info = NCTRL(6) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x60) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x30), /* Telit FE990D50 (ECM) */
++ .driver_info = NCTRL(6) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x60) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff), /* Telit LE910C1-EUX */
+ .driver_info = NCTRL(0) | RSVD(3) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */
--- /dev/null
+From 4e8ba83ac4d311992e6a4c21de5dd705010df06e Mon Sep 17 00:00:00 2001
+From: Myeonghun Pak <mhun512@gmail.com>
+Date: Wed, 1 Jul 2026 21:16:25 +0900
+Subject: usb: sl811-hcd: disable controller wakeup on remove
+
+From: Myeonghun Pak <mhun512@gmail.com>
+
+commit 4e8ba83ac4d311992e6a4c21de5dd705010df06e upstream.
+
+sl811h_probe() enables the HCD controller device as a wakeup source after
+usb_add_hcd() succeeds, but sl811h_remove() removes the HCD and releases
+the driver resources without disabling that wakeup source.
+
+Disable controller wakeup after usb_remove_hcd() and before usb_put_hcd()
+so the wakeup source object is detached while the controller device pointer
+is still available.
+
+This issue was identified during our ongoing static-analysis research while
+reviewing kernel code.
+
+Fixes: 3c9740a117d4 ("usb: hcd: move controller wakeup setting initialization to individual driver")
+Cc: stable <stable@kernel.org>
+Co-developed-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
+Link: https://patch.msgid.link/20260701121625.96815-1-mhun512@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/sl811-hcd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/host/sl811-hcd.c
++++ b/drivers/usb/host/sl811-hcd.c
+@@ -1590,6 +1590,7 @@ sl811h_remove(struct platform_device *de
+
+ remove_debug_file(sl811);
+ usb_remove_hcd(hcd);
++ device_wakeup_disable(hcd->self.controller);
+
+ /* some platforms may use IORESOURCE_IO */
+ res = platform_get_resource(dev, IORESOURCE_MEM, 1);
--- /dev/null
+From 2c00e09e3f9f06f8434f5ea2ee6179ce46692ee6 Mon Sep 17 00:00:00 2001
+From: Xu Rao <raoxu@uniontech.com>
+Date: Tue, 2 Jun 2026 13:38:42 +0800
+Subject: USB: storage: include US_FL_NO_SAME in quirks mask
+
+From: Xu Rao <raoxu@uniontech.com>
+
+commit 2c00e09e3f9f06f8434f5ea2ee6179ce46692ee6 upstream.
+
+usb_stor_adjust_quirks() parses the usb-storage.quirks module
+parameter into a new flag set and then applies it with the quirk
+mask to override built-in flags.
+
+The mask is meant to cover the flags that can be overridden by
+the module parameter. The 'k' quirk character sets US_FL_NO_SAME,
+but US_FL_NO_SAME is not included in the mask.
+
+As a result, the module parameter can set US_FL_NO_SAME, but it
+cannot clear a built-in US_FL_NO_SAME flag by providing an override
+entry that omits 'k'.
+
+Add US_FL_NO_SAME to the mask so that the module parameter can
+override it in the same way as the other supported flags.
+
+Fixes: 8010622c86ca ("USB: UAS: introduce a quirk to set no_write_same")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Xu Rao <raoxu@uniontech.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://patch.msgid.link/3BCE5880F9A45C2E+20260602053842.2920137-1-raoxu@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/storage/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/usb.c
++++ b/drivers/usb/storage/usb.c
+@@ -488,7 +488,7 @@ void usb_stor_adjust_quirks(struct usb_d
+ US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE |
+ US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES |
+ US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS |
+- US_FL_ALWAYS_SYNC);
++ US_FL_ALWAYS_SYNC | US_FL_NO_SAME);
+
+ p = quirks;
+ while (*p) {
--- /dev/null
+From 0ef7cc27da8b9e315a4a5a665c68c44206f5e559 Mon Sep 17 00:00:00 2001
+From: Myeonghun Pak <mhun512@gmail.com>
+Date: Wed, 1 Jul 2026 20:40:06 +0900
+Subject: usb: typec: anx7411: use devm_pm_runtime_enable()
+
+From: Myeonghun Pak <mhun512@gmail.com>
+
+commit 0ef7cc27da8b9e315a4a5a665c68c44206f5e559 upstream.
+
+anx7411_i2c_probe() enables runtime PM before returning successfully, but
+anx7411_i2c_remove() tears down the Type-C partner state, workqueue, dummy
+I2C device, mux, switch and port without disabling runtime PM.
+
+Use devm_pm_runtime_enable() so runtime PM is disabled automatically on
+driver detach. Since devres action registration can fail, route that
+failure through the existing probe unwind path.
+
+This issue was identified during our ongoing static-analysis research while
+reviewing kernel code.
+
+Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support")
+Cc: stable <stable@kernel.org>
+Co-developed-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260701114006.75738-1-mhun512@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/anx7411.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/anx7411.c
++++ b/drivers/usb/typec/anx7411.c
+@@ -1542,7 +1542,9 @@ static int anx7411_i2c_probe(struct i2c_
+ if (anx7411_typec_check_connection(plat))
+ dev_err(dev, "check status\n");
+
+- pm_runtime_enable(dev);
++ ret = devm_pm_runtime_enable(dev);
++ if (ret)
++ goto free_wq;
+
+ return 0;
+
--- /dev/null
+From 43ae2f90b70cda374c487c1639a01d0f14e5d583 Mon Sep 17 00:00:00 2001
+From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+Date: Thu, 2 Jul 2026 15:13:29 -0400
+Subject: usb: typec: class: drop PD lookup reference
+
+From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+
+commit 43ae2f90b70cda374c487c1639a01d0f14e5d583 upstream.
+
+usb_power_delivery_find() wraps class_find_device_by_name(). That helper
+returns a device reference that must be released by the caller.
+
+select_usb_power_delivery_store() only needs this reference while calling
+the pd_set callback. Drop it once the callback returns. Otherwise the sysfs
+write can pin the selected USB Power Delivery object and prevent it from
+being released on unregister.
+
+Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+Link: https://patch.msgid.link/20260702191329.2648043-1-shuangpeng.kernel@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/class.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/typec/class.c
++++ b/drivers/usb/typec/class.c
+@@ -1277,6 +1277,7 @@ static ssize_t select_usb_power_delivery
+ return -EINVAL;
+
+ ret = port->ops->pd_set(port, pd);
++ put_device(&pd->dev);
+ if (ret)
+ return ret;
+
--- /dev/null
+From 7b681dd5fbf60b24a13c14661e5b7735759fb491 Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Mon, 22 Jun 2026 22:08:03 +0000
+Subject: usb: typec: tcpm: Validate SVID index in svdm_consume_modes()
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit 7b681dd5fbf60b24a13c14661e5b7735759fb491 upstream.
+
+In svdm_consume_modes(), the SVID value is read from pmdata->svids using
+pmdata->svid_index as an array index without bounds validation:
+
+ paltmode->svid = pmdata->svids[pmdata->svid_index];
+
+If pmdata->svid_index is driven beyond SVID_DISCOVERY_MAX (16), it results
+in an out-of-bounds read of the pmdata->svids array. Because pd_mode_data
+is embedded inside struct tcpm_port, indexing past svids reads into
+adjacent fields. In particular:
+- At index 16, it reads the altmodes count.
+- At index 18 and beyond, it reads into altmode_desc[], which contains
+ partner-supplied SVDM Discovery Modes VDOs.
+
+By injecting a chosen SVID into altmode_desc[0].vdo and driving svid_index
+to 20, the partner can force paltmode->svid to be loaded with an arbitrary,
+partner- chosen SVID, which is then registered via
+typec_partner_register_altmode().
+
+Fix this by validating that pmdata->svid_index is non-negative and strictly
+less than pmdata->nsvids before accessing the pmdata->svids array inside
+svdm_consume_modes().
+
+Assisted-by: Antigravity:gemini-3.5-flash
+Fixes: 4ab8c18d4d67 ("usb: typec: Register a device for every mode")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Reviewed-by: RD Babiera <rdbabiera@google.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260622220803.305750-1-badhri@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1555,6 +1555,11 @@ static void svdm_consume_modes(struct tc
+ return;
+ }
+
++ if (pmdata->svid_index < 0 || pmdata->svid_index >= pmdata->nsvids) {
++ tcpm_log(port, "Invalid SVID index %d", pmdata->svid_index);
++ return;
++ }
++
+ for (i = 1; i < cnt; i++) {
+ paltmode = &pmdata->altmode_desc[pmdata->altmodes];
+ memset(paltmode, 0, sizeof(*paltmode));
--- /dev/null
+From 7c4a234bd31a64a8dbd0140dc812da592c5e0787 Mon Sep 17 00:00:00 2001
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+Date: Fri, 3 Jul 2026 13:07:37 +0200
+Subject: usb: typec: ucsi: cancel pending work on system suspend
+
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+
+commit 7c4a234bd31a64a8dbd0140dc812da592c5e0787 upstream.
+
+On a Dell XPS 13 9360 (BIOS 2.21.0), entering system suspend (deep/S3)
+races a pending UCSI connector-change worker against the ACPI EC teardown.
+The worker evaluates the UCSI _DSM (GET_CONNECTOR_STATUS), whose AML
+accesses the Embedded Controller. By that point the ACPI EC has already
+been stopped for suspend, so the EC address space handler rejects the
+access with AE_BAD_PARAMETER, aborting the AML and failing the connector
+query:
+
+ [22314.689495] ACPI: EC: interrupt blocked
+ [22314.711981] ACPI: PM: Preparing to enter system sleep state S3
+ [22314.743260] ACPI: EC: event blocked
+ [22314.743265] ACPI: EC: EC stopped
+ [22314.743267] ACPI: PM: Saving platform NVS memory
+ [22314.744241] ACPI Error: AE_BAD_PARAMETER, Returned by Handler for [EmbeddedControl] (20260408/evregion-303)
+ [22314.744432] ACPI Error: Aborting method \_SB.PCI0.LPCB.ECDV.ECW1 due to previous error (AE_BAD_PARAMETER) (20260408/psparse-543)
+ [22314.744673] ACPI Error: Aborting method \ECWB due to previous error (AE_BAD_PARAMETER) (20260408/psparse-543)
+ [22314.745201] ACPI Error: Aborting method \_SB.UBTC._DSM due to previous error (AE_BAD_PARAMETER) (20260408/psparse-543)
+ [22314.745394] ACPI: \_SB_.UBTC: failed to evaluate _DSM c298836f-a47c-e411-ad36-631042b5008f rev:1 func:1 (0x1001)
+ [22314.745414] ucsi_acpi USBC000:00: ucsi_acpi_dsm: failed to evaluate _DSM 1
+ [22314.745424] ucsi_acpi USBC000:00: ucsi_handle_connector_change: GET_CONNECTOR_STATUS failed (-5)
+
+ucsi_acpi implements a resume callback but no suspend callback, so nothing
+cancels the connector-change work before the firmware/EC is torn down.
+
+Add a `ucsi_suspend()` core helper that cancels the pending init and
+connector-change work, and wire it into ucsi_acpi's PM ops. The connector
+state is re-read on resume by `ucsi_resume()`, so cancelling the work loses
+nothing.
+
+Fixes: 4e3a50293c2b ("usb: typec: ucsi: acpi: Implement resume callback")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Assisted-by: Claude Opus 4.8
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260703110738.8457-2-pmenzel@molgen.mpg.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 20 ++++++++++++++++++++
+ drivers/usb/typec/ucsi/ucsi.h | 1 +
+ drivers/usb/typec/ucsi/ucsi_acpi.c | 10 +++++++++-
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1533,6 +1533,26 @@ static void ucsi_resume_work(struct work
+ }
+ }
+
++int ucsi_suspend(struct ucsi *ucsi)
++{
++ int i;
++
++ /*
++ * Cancel pending work so it cannot access the firmware after the ACPI
++ * EC is stopped for suspend; state is re-read on resume.
++ */
++ cancel_delayed_work_sync(&ucsi->work);
++
++ if (!ucsi->connector)
++ return 0;
++
++ for (i = 0; i < ucsi->cap.num_connectors; i++)
++ cancel_work_sync(&ucsi->connector[i].work);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(ucsi_suspend);
++
+ int ucsi_resume(struct ucsi *ucsi)
+ {
+ if (ucsi->connector)
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -386,6 +386,7 @@ int ucsi_send_command(struct ucsi *ucsi,
+ void *retval, size_t size);
+
+ void ucsi_altmode_update_active(struct ucsi_connector *con);
++int ucsi_suspend(struct ucsi *ucsi);
+ int ucsi_resume(struct ucsi *ucsi);
+
+ #if IS_ENABLED(CONFIG_POWER_SUPPLY)
+--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
++++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
+@@ -288,6 +288,13 @@ static void ucsi_acpi_remove(struct plat
+ ucsi_acpi_notify);
+ }
+
++static int ucsi_acpi_suspend(struct device *dev)
++{
++ struct ucsi_acpi *ua = dev_get_drvdata(dev);
++
++ return ucsi_suspend(ua->ucsi);
++}
++
+ static int ucsi_acpi_resume(struct device *dev)
+ {
+ struct ucsi_acpi *ua = dev_get_drvdata(dev);
+@@ -295,7 +302,8 @@ static int ucsi_acpi_resume(struct devic
+ return ucsi_resume(ua->ucsi);
+ }
+
+-static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, NULL, ucsi_acpi_resume);
++static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, ucsi_acpi_suspend,
++ ucsi_acpi_resume);
+
+ static const struct acpi_device_id ucsi_acpi_match[] = {
+ { "PNP0CA0", 0 },
--- /dev/null
+From 1f0bdc2884b67de337215079bba166df0cdf4ac5 Mon Sep 17 00:00:00 2001
+From: Fan Wu <fanwu01@zju.edu.cn>
+Date: Tue, 16 Jun 2026 13:20:11 +0000
+Subject: usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove
+
+From: Fan Wu <fanwu01@zju.edu.cn>
+
+commit 1f0bdc2884b67de337215079bba166df0cdf4ac5 upstream.
+
+The threaded IRQ handler ccg_irq_handler() calls ucsi_notify_common(),
+which on a connector-change event calls ucsi_connector_change() and
+schedules connector work. In ucsi_ccg_remove(), ucsi_destroy() frees
+uc->ucsi (kfree) before free_irq() is called, so a handler invocation
+already in flight may access the freed object after ucsi_destroy().
+
+ CPU 0 (remove) | CPU 1 (threaded IRQ)
+ ucsi_destroy(uc->ucsi) | ccg_irq_handler()
+ kfree(ucsi) // FREE | ucsi_notify_common(uc->ucsi) // USE
+
+Move free_irq() before ucsi_destroy() in the remove path. It is kept
+after ucsi_unregister(): ucsi_unregister() cancels connector work whose
+handler issues GET_CONNECTOR_STATUS through ucsi_send_command_common(),
+which waits for a completion that is signalled from the IRQ handler, so
+the IRQ must stay active until that work has been cancelled.
+
+The probe error path already orders free_irq() before ucsi_destroy().
+
+This bug was found by static analysis.
+
+Fixes: e32fd989ac1c ("usb: typec: ucsi: ccg: Move to the new API")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260616132011.103279-1-fanwu01@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi_ccg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
+@@ -1440,8 +1440,8 @@ static void ucsi_ccg_remove(struct i2c_c
+ cancel_work_sync(&uc->work);
+ pm_runtime_disable(uc->dev);
+ ucsi_unregister(uc->ucsi);
+- ucsi_destroy(uc->ucsi);
+ free_irq(uc->irq, uc);
++ ucsi_destroy(uc->ucsi);
+ }
+
+ static const struct of_device_id ucsi_ccg_of_match_table[] = {
--- /dev/null
+From d092d7edf8faefa3e27b9fc7f0e7904b06c833a2 Mon Sep 17 00:00:00 2001
+From: Andrei Kuchynski <akuchynski@chromium.org>
+Date: Mon, 1 Jun 2026 14:28:37 +0000
+Subject: usb: typec: ucsi: Invert DisplayPort role assignment
+
+From: Andrei Kuchynski <akuchynski@chromium.org>
+
+commit d092d7edf8faefa3e27b9fc7f0e7904b06c833a2 upstream.
+
+The existing implementation assigned these flags backwards, configuring
+the partner's DisplayPort role to match the port's role instead of
+complementing it.
+This prevents proper configuration during DP altmode activation, often
+causing `pin_assignment` to remain 0 in `dp_altmode_configure()` and
+resulting in VDM negotiation failures:
+
+ [ 583.328246] typec port1.1: VDM 0xff01a150 failed
+
+Additionally, the fix ensures that the `pin_assignment` sysfs attribute
+displays the correct values.
+
+Cc: stable <stable@kernel.org>
+Fixes: af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode")
+Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260601142837.3240207-1-akuchynski@chromium.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/displayport.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/displayport.c
++++ b/drivers/usb/typec/ucsi/displayport.c
+@@ -166,12 +166,12 @@ static int ucsi_displayport_status_updat
+ * that Multi-function is preferred.
+ */
+ if (DP_CAP_CAPABILITY(cap) & DP_CAP_UFP_D) {
+- dp->data.status |= DP_STATUS_CON_UFP_D;
++ dp->data.status |= DP_STATUS_CON_DFP_D;
+
+ if (DP_CAP_UFP_D_PIN_ASSIGN(cap) & BIT(DP_PIN_ASSIGN_D))
+ dp->data.status |= DP_STATUS_PREFER_MULTI_FUNC;
+ } else {
+- dp->data.status |= DP_STATUS_CON_DFP_D;
++ dp->data.status |= DP_STATUS_CON_UFP_D;
+
+ if (DP_CAP_DFP_D_PIN_ASSIGN(cap) & BIT(DP_PIN_ASSIGN_D))
+ dp->data.status |= DP_STATUS_PREFER_MULTI_FUNC;
--- /dev/null
+From 735a461d060d4eeb2f9732aba1295bc32a3982e2 Mon Sep 17 00:00:00 2001
+From: Madhu M <madhu.m@intel.com>
+Date: Fri, 19 Jun 2026 21:03:11 +0530
+Subject: usb: typec: ucsi: Pass full DP config payload in SET_NEW_CAM for DP alt mode
+
+From: Madhu M <madhu.m@intel.com>
+
+commit 735a461d060d4eeb2f9732aba1295bc32a3982e2 upstream.
+
+In the UCSI Specification Revision 3.1 RC1, bits 32-63 of the SET_NEW_CAM
+command hold the 32-bit Alternate Mode Specific (AMSpecific) field.
+
+For DisplayPort Alternate Mode, this field must contain the full
+32-bit DisplayPort configuration VDO payload that the OPM wants the
+connector to operate in, rather than just the pin assignment value.
+This AMSpecific value follows the DisplayPort Configurations defined
+in the DisplayPort Alt Mode on USB Type-C Specification v2.1a,
+Table 5-13: SOP DisplayPort Configurations.
+
+Fixes: af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Madhu M <madhu.m@intel.com>
+Reviewed-by: Jameson Thies <jthies@google.com>
+Reviewed-by: Andrei Kuchynski <akuchynski@chromium.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260619153311.3526083-1-madhu.m@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/displayport.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/displayport.c
++++ b/drivers/usb/typec/ucsi/displayport.c
+@@ -185,13 +185,12 @@ static int ucsi_displayport_status_updat
+
+ static int ucsi_displayport_configure(struct ucsi_dp *dp)
+ {
+- u32 pins = DP_CONF_GET_PIN_ASSIGN(dp->data.conf);
+ u64 command;
+
+ if (!dp->override)
+ return 0;
+
+- command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins);
++ command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, dp->data.conf);
+
+ return ucsi_send_command(dp->con->ucsi, command, NULL, 0);
+ }
--- /dev/null
+From 8af6812795869a66e9b26044f455b13deecdb69c Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 8 Jun 2026 16:58:03 +0200
+Subject: USB: ulpi: fix memory leak on registration failure
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 8af6812795869a66e9b26044f455b13deecdb69c upstream.
+
+The allocated device name is never freed on early ULPI device
+registration failures.
+
+Fix this by initialising the device structure earlier and releasing the
+initial reference whenever registration fails.
+
+Fixes: 289fcff4bcdb ("usb: add bus type for USB ULPI")
+Cc: stable <stable@kernel.org>
+Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260608145803.69360-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/common/ulpi.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/common/ulpi.c
++++ b/drivers/usb/common/ulpi.c
+@@ -281,28 +281,24 @@ static int ulpi_register(struct device *
+ ulpi->dev.parent = dev; /* needed early for ops */
+ ulpi->dev.bus = &ulpi_bus;
+ ulpi->dev.type = &ulpi_dev_type;
++
++ device_initialize(&ulpi->dev);
++
+ dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev));
+
+ ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
+
+ ret = ulpi_of_register(ulpi);
+- if (ret) {
+- kfree(ulpi);
++ if (ret)
+ return ret;
+- }
+
+ ret = ulpi_read_id(ulpi);
+- if (ret) {
+- of_node_put(ulpi->dev.of_node);
+- kfree(ulpi);
++ if (ret)
+ return ret;
+- }
+
+- ret = device_register(&ulpi->dev);
+- if (ret) {
+- put_device(&ulpi->dev);
++ ret = device_add(&ulpi->dev);
++ if (ret)
+ return ret;
+- }
+
+ root = debugfs_create_dir(dev_name(&ulpi->dev), ulpi_root);
+ debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_fops);
+@@ -334,9 +330,10 @@ struct ulpi *ulpi_register_interface(str
+ ulpi->ops = ops;
+
+ ret = ulpi_register(dev, ulpi);
+- if (ret)
++ if (ret) {
++ put_device(&ulpi->dev);
+ return ERR_PTR(ret);
+-
++ }
+
+ return ulpi;
+ }
--- /dev/null
+From 5fc3f333c001f1e308bbcdeecdec0d054d24338b Mon Sep 17 00:00:00 2001
+From: Xu Rao <raoxu@uniontech.com>
+Date: Fri, 26 Jun 2026 15:06:07 +0800
+Subject: USB: usb-storage: ene_ub6250: restore media-ready check
+
+From: Xu Rao <raoxu@uniontech.com>
+
+commit 5fc3f333c001f1e308bbcdeecdec0d054d24338b upstream.
+
+Commit 1892bf90677a ("USB: usb-storage: Fix use of bitfields for
+hardware data in ene_ub6250.c") converted the media status fields from
+bitfields to bit masks.
+
+The original ene_transport() test called ene_init() only when neither
+media type was ready:
+
+ !(sd_ready || ms_ready)
+
+The converted test became:
+
+ !sd_ready || ms_ready
+
+This is not equivalent. Restore the original semantics by testing that
+both ready bits are clear before calling ene_init().
+
+Fixes: 1892bf90677a ("USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Xu Rao <raoxu@uniontech.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://patch.msgid.link/F42641386E32404F+20260626070607.4119527-1-raoxu@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/storage/ene_ub6250.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/ene_ub6250.c
++++ b/drivers/usb/storage/ene_ub6250.c
+@@ -2306,7 +2306,8 @@ static int ene_transport(struct scsi_cmn
+
+ /*US_DEBUG(usb_stor_show_command(us, srb)); */
+ scsi_set_resid(srb, 0);
+- if (unlikely(!(info->SD_Status & SD_Ready) || (info->MS_Status & MS_Ready)))
++ if (unlikely(!(info->SD_Status & SD_Ready) &&
++ !(info->MS_Status & MS_Ready)))
+ result = ene_init(us);
+ if (result == USB_STOR_XFER_GOOD) {
+ result = USB_STOR_TRANSPORT_ERROR;
--- /dev/null
+From 195e667c8719480c320cd48ac0fbf1cb81d6ffe0 Mon Sep 17 00:00:00 2001
+From: Yichong Chen <chenyichong@uniontech.com>
+Date: Wed, 17 Jun 2026 10:06:13 +0800
+Subject: usbip: tools: support SuperSpeedPlus devices
+
+From: Yichong Chen <chenyichong@uniontech.com>
+
+commit 195e667c8719480c320cd48ac0fbf1cb81d6ffe0 upstream.
+
+USB devices running at SuperSpeedPlus report "10000" or "20000" in
+their sysfs speed attribute. usbip currently maps only "5000" to
+USB_SPEED_SUPER, so a SuperSpeedPlus device is imported as
+USB_SPEED_UNKNOWN.
+
+The attach request is then rejected by vhci_hcd:
+
+ vhci_hcd: Failed attach request for unsupported USB speed: UNKNOWN
+
+Map the SuperSpeedPlus sysfs speed values to USB_SPEED_SUPER_PLUS, use
+the SuperSpeed VHCI hub for SuperSpeedPlus devices, and recognize the
+gadget current_speed string used by the kernel.
+
+Fixes: b2316645ca5e ("usb: show speed "10000" in sysfs for USB 3.1 SuperSpeedPlus devices")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
+Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://patch.msgid.link/00C828F338E43447+20260617020613.199086-1-chenyichong@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/usb/usbip/libsrc/usbip_common.c | 2 ++
+ tools/usb/usbip/libsrc/usbip_device_driver.c | 4 ++++
+ tools/usb/usbip/libsrc/vhci_driver.c | 1 +
+ 3 files changed, 7 insertions(+)
+
+--- a/tools/usb/usbip/libsrc/usbip_common.c
++++ b/tools/usb/usbip/libsrc/usbip_common.c
+@@ -29,6 +29,8 @@ static const struct speed_string speed_s
+ { USB_SPEED_HIGH, "480", "High Speed(480Mbps)" },
+ { USB_SPEED_WIRELESS, "53.3-480", "Wireless"},
+ { USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" },
++ { USB_SPEED_SUPER_PLUS, "10000", "Super Speed Plus(10000Mbps)" },
++ { USB_SPEED_SUPER_PLUS, "20000", "Super Speed Plus(20000Mbps)" },
+ { 0, NULL, NULL }
+ };
+
+--- a/tools/usb/usbip/libsrc/usbip_device_driver.c
++++ b/tools/usb/usbip/libsrc/usbip_device_driver.c
+@@ -57,6 +57,10 @@ static struct {
+ .speed = USB_SPEED_SUPER,
+ .name = "super-speed",
+ },
++ {
++ .speed = USB_SPEED_SUPER_PLUS,
++ .name = "super-speed-plus",
++ },
+ };
+
+ static
+--- a/tools/usb/usbip/libsrc/vhci_driver.c
++++ b/tools/usb/usbip/libsrc/vhci_driver.c
+@@ -338,6 +338,7 @@ int usbip_vhci_get_free_port(uint32_t sp
+
+ switch (speed) {
+ case USB_SPEED_SUPER:
++ case USB_SPEED_SUPER_PLUS:
+ if (vhci_driver->idev[i].hub != HUB_SPEED_SUPER)
+ continue;
+ break;
--- /dev/null
+From c5371e0b91b24159a3ebaa61e70b0980bcf03c0a Mon Sep 17 00:00:00 2001
+From: Sam Day <me@samcday.com>
+Date: Fri, 26 Jun 2026 14:29:10 +1000
+Subject: usbip: vudc: fix NULL deref in vep_dequeue()
+
+From: Sam Day <me@samcday.com>
+
+commit c5371e0b91b24159a3ebaa61e70b0980bcf03c0a upstream.
+
+vep_alloc_request() wasn't initializing vrequest->udc, so cancellations
+on the FunctionFS AIO path were arriving in vep_dequeue without a valid
+UDC reference.
+
+Since vrequest->udc is never actually properly used anywhere, we opt to
+remove it, and update vep_dequeue to obtain a reference to the udc with
+ep_to_vudc(), consistent with the other vep_ ops.
+
+AFAICT this bug has existed for ~10 years. Seems that nobody has really
+stressed the FunctionFS AIO path on usbip's vudc.
+
+I tested this fix in a QEMU aarch64 guest driving FunctionFS endpoints
+via AIO. Before the fix, running `usbip attach` from the host would
+cause the guest to oops with the following backtrace:
+
+Call trace:
+ vep_dequeue+0x1c/0xe4 (P)
+ usb_ep_dequeue+0x14/0x20
+ ffs_aio_cancel+0x24/0x34
+ __arm64_sys_io_cancel+0xb0/0x124
+ do_el0_svc+0x68/0x100
+ el0_svc+0x18/0x5c
+ el0t_64_sync_handler+0x98/0xdc
+ el0t_64_sync+0x154/0x158
+
+Assisted-by: opencode:openai/gpt-5.5
+Cc: stable <stable@kernel.org>
+Fixes: b6a0ca111867 ("usbip: vudc: Add UDC specific ops")
+Reviewed-by: Igor Kotrasinski <i.kotrasinsk@samsung.com>
+Signed-off-by: Sam Day <me@samcday.com>
+Link: https://patch.msgid.link/20260626-usbip-vudc-deque-fix-v3-1-98c2dc4d6a48@samcday.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/vudc.h | 1 -
+ drivers/usb/usbip/vudc_dev.c | 4 +---
+ 2 files changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/usb/usbip/vudc.h
++++ b/drivers/usb/usbip/vudc.h
+@@ -38,7 +38,6 @@ struct vep {
+
+ struct vrequest {
+ struct usb_request req;
+- struct vudc *udc;
+ struct list_head req_entry; /* Request queue */
+ };
+
+--- a/drivers/usb/usbip/vudc_dev.c
++++ b/drivers/usb/usbip/vudc_dev.c
+@@ -333,7 +333,6 @@ static int vep_queue(struct usb_ep *_ep,
+ static int vep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+ {
+ struct vep *ep;
+- struct vrequest *req;
+ struct vudc *udc;
+ struct vrequest *lst;
+ unsigned long flags;
+@@ -343,8 +342,7 @@ static int vep_dequeue(struct usb_ep *_e
+ return ret;
+
+ ep = to_vep(_ep);
+- req = to_vrequest(_req);
+- udc = req->udc;
++ udc = ep_to_vudc(ep);
+
+ if (!udc->driver)
+ return -ESHUTDOWN;