From: Greg Kroah-Hartman Date: Tue, 8 Jul 2025 09:10:41 +0000 (+0200) Subject: 6.15-stable patches X-Git-Tag: v5.15.187~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=043ca7961e3af6c20f38630b503f8916e60c03d3;p=thirdparty%2Fkernel%2Fstable-queue.git 6.15-stable patches added patches: hid-appletb-kbd-fix-memory-corruption-of-input_handler_list.patch input-iqs7222-explicitly-define-number-of-external-channels.patch input-xpad-support-acer-ngr-200-controller.patch revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch usb-acpi-fix-device-link-removal.patch usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch usb-dwc3-gadget-fix-trb-reclaim-logic-for-short-transfers-and-zlps.patch usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch xhci-dbc-flush-queued-requests-before-stopping-dbc.patch xhci-dbctty-disable-echo-flag-by-default.patch xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch --- diff --git a/queue-6.15/hid-appletb-kbd-fix-memory-corruption-of-input_handler_list.patch b/queue-6.15/hid-appletb-kbd-fix-memory-corruption-of-input_handler_list.patch new file mode 100644 index 0000000000..e28b6003b7 --- /dev/null +++ b/queue-6.15/hid-appletb-kbd-fix-memory-corruption-of-input_handler_list.patch @@ -0,0 +1,147 @@ +From c80f2b047d5cc42fbd2dff9d1942d4ba7545100f Mon Sep 17 00:00:00 2001 +From: Qasim Ijaz +Date: Fri, 27 Jun 2025 12:01:21 +0100 +Subject: HID: appletb-kbd: fix memory corruption of input_handler_list + +From: Qasim Ijaz + +commit c80f2b047d5cc42fbd2dff9d1942d4ba7545100f upstream. + +In appletb_kbd_probe an input handler is initialised and then registered +with input core through input_register_handler(). When this happens input +core will add the input handler (specifically its node) to the global +input_handler_list. The input_handler_list is central to the functionality +of input core and is traversed in various places in input core. An example +of this is when a new input device is plugged in and gets registered with +input core. + +The input_handler in probe is allocated as device managed memory. If a +probe failure occurs after input_register_handler() the input_handler +memory is freed, yet it will remain in the input_handler_list. This +effectively means the input_handler_list contains a dangling pointer +to data belonging to a freed input handler. + +This causes an issue when any other input device is plugged in - in my +case I had an old PixArt HP USB optical mouse and I decided to +plug it in after a failure occurred after input_register_handler(). +This lead to the registration of this input device via +input_register_device which involves traversing over every handler +in the corrupted input_handler_list and calling input_attach_handler(), +giving each handler a chance to bind to newly registered device. + +The core of this bug is a UAF which causes memory corruption of +input_handler_list and to fix it we must ensure the input handler is +unregistered from input core, this is done through +input_unregister_handler(). + +[ 63.191597] ================================================================== +[ 63.192094] BUG: KASAN: slab-use-after-free in input_attach_handler.isra.0+0x1a9/0x1e0 +[ 63.192094] Read of size 8 at addr ffff888105ea7c80 by task kworker/0:2/54 +[ 63.192094] +[ 63.192094] CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.16.0-rc2-00321-g2aa6621d +[ 63.192094] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.164 +[ 63.192094] Workqueue: usb_hub_wq hub_event +[ 63.192094] Call Trace: +[ 63.192094] +[ 63.192094] dump_stack_lvl+0x53/0x70 +[ 63.192094] print_report+0xce/0x670 +[ 63.192094] kasan_report+0xce/0x100 +[ 63.192094] input_attach_handler.isra.0+0x1a9/0x1e0 +[ 63.192094] input_register_device+0x76c/0xd00 +[ 63.192094] hidinput_connect+0x686d/0xad60 +[ 63.192094] hid_connect+0xf20/0x1b10 +[ 63.192094] hid_hw_start+0x83/0x100 +[ 63.192094] hid_device_probe+0x2d1/0x680 +[ 63.192094] really_probe+0x1c3/0x690 +[ 63.192094] __driver_probe_device+0x247/0x300 +[ 63.192094] driver_probe_device+0x49/0x210 +[ 63.192094] __device_attach_driver+0x160/0x320 +[ 63.192094] bus_for_each_drv+0x10f/0x190 +[ 63.192094] __device_attach+0x18e/0x370 +[ 63.192094] bus_probe_device+0x123/0x170 +[ 63.192094] device_add+0xd4d/0x1460 +[ 63.192094] hid_add_device+0x30b/0x910 +[ 63.192094] usbhid_probe+0x920/0xe00 +[ 63.192094] usb_probe_interface+0x363/0x9a0 +[ 63.192094] really_probe+0x1c3/0x690 +[ 63.192094] __driver_probe_device+0x247/0x300 +[ 63.192094] driver_probe_device+0x49/0x210 +[ 63.192094] __device_attach_driver+0x160/0x320 +[ 63.192094] bus_for_each_drv+0x10f/0x190 +[ 63.192094] __device_attach+0x18e/0x370 +[ 63.192094] bus_probe_device+0x123/0x170 +[ 63.192094] device_add+0xd4d/0x1460 +[ 63.192094] usb_set_configuration+0xd14/0x1880 +[ 63.192094] usb_generic_driver_probe+0x78/0xb0 +[ 63.192094] usb_probe_device+0xaa/0x2e0 +[ 63.192094] really_probe+0x1c3/0x690 +[ 63.192094] __driver_probe_device+0x247/0x300 +[ 63.192094] driver_probe_device+0x49/0x210 +[ 63.192094] __device_attach_driver+0x160/0x320 +[ 63.192094] bus_for_each_drv+0x10f/0x190 +[ 63.192094] __device_attach+0x18e/0x370 +[ 63.192094] bus_probe_device+0x123/0x170 +[ 63.192094] device_add+0xd4d/0x1460 +[ 63.192094] usb_new_device+0x7b4/0x1000 +[ 63.192094] hub_event+0x234d/0x3fa0 +[ 63.192094] process_one_work+0x5bf/0xfe0 +[ 63.192094] worker_thread+0x777/0x13a0 +[ 63.192094] +[ 63.192094] +[ 63.192094] Allocated by task 54: +[ 63.192094] kasan_save_stack+0x33/0x60 +[ 63.192094] kasan_save_track+0x14/0x30 +[ 63.192094] __kasan_kmalloc+0x8f/0xa0 +[ 63.192094] __kmalloc_node_track_caller_noprof+0x195/0x420 +[ 63.192094] devm_kmalloc+0x74/0x1e0 +[ 63.192094] appletb_kbd_probe+0x39/0x440 +[ 63.192094] hid_device_probe+0x2d1/0x680 +[ 63.192094] really_probe+0x1c3/0x690 +[ 63.192094] __driver_probe_device+0x247/0x300 +[ 63.192094] driver_probe_device+0x49/0x210 +[ 63.192094] __device_attach_driver+0x160/0x320 +[...] +[ 63.192094] +[ 63.192094] Freed by task 54: +[ 63.192094] kasan_save_stack+0x33/0x60 +[ 63.192094] kasan_save_track+0x14/0x30 +[ 63.192094] kasan_save_free_info+0x3b/0x60 +[ 63.192094] __kasan_slab_free+0x37/0x50 +[ 63.192094] kfree+0xcf/0x360 +[ 63.192094] devres_release_group+0x1f8/0x3c0 +[ 63.192094] hid_device_probe+0x315/0x680 +[ 63.192094] really_probe+0x1c3/0x690 +[ 63.192094] __driver_probe_device+0x247/0x300 +[ 63.192094] driver_probe_device+0x49/0x210 +[ 63.192094] __device_attach_driver+0x160/0x320 +[...] + +Fixes: 7d62ba8deacf ("HID: hid-appletb-kbd: add support for fn toggle between media and function mode") +Cc: stable@vger.kernel.org +Reviewed-by: Aditya Garg +Signed-off-by: Qasim Ijaz +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-appletb-kbd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/hid/hid-appletb-kbd.c ++++ b/drivers/hid/hid-appletb-kbd.c +@@ -427,13 +427,15 @@ static int appletb_kbd_probe(struct hid_ + ret = appletb_kbd_set_mode(kbd, appletb_tb_def_mode); + if (ret) { + dev_err_probe(dev, ret, "Failed to set touchbar mode\n"); +- goto close_hw; ++ goto unregister_handler; + } + + hid_set_drvdata(hdev, kbd); + + return 0; + ++unregister_handler: ++ input_unregister_handler(&kbd->inp_handler); + close_hw: + if (kbd->backlight_dev) + put_device(&kbd->backlight_dev->dev); diff --git a/queue-6.15/input-iqs7222-explicitly-define-number-of-external-channels.patch b/queue-6.15/input-iqs7222-explicitly-define-number-of-external-channels.patch new file mode 100644 index 0000000000..3c713f6b8a --- /dev/null +++ b/queue-6.15/input-iqs7222-explicitly-define-number-of-external-channels.patch @@ -0,0 +1,71 @@ +From 63f4970a1219b5256e8ea952096c86dab666d312 Mon Sep 17 00:00:00 2001 +From: Jeff LaBundy +Date: Sun, 29 Jun 2025 18:33:30 -0700 +Subject: Input: iqs7222 - explicitly define number of external channels + +From: Jeff LaBundy + +commit 63f4970a1219b5256e8ea952096c86dab666d312 upstream. + +The number of external channels is assumed to be a multiple of 10, +but this is not the case for IQS7222D. As a result, some CRx pins +are wrongly prevented from being assigned to some channels. + +Address this problem by explicitly defining the number of external +channels for cases in which the number of external channels is not +equal to the total number of available channels. + +Fixes: dd24e202ac72 ("Input: iqs7222 - add support for Azoteq IQS7222D") +Signed-off-by: Jeff LaBundy +Link: https://lore.kernel.org/r/aGHVf6HkyFZrzTPy@nixie71 +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/iqs7222.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/input/misc/iqs7222.c ++++ b/drivers/input/misc/iqs7222.c +@@ -301,6 +301,7 @@ struct iqs7222_dev_desc { + int allow_offset; + int event_offset; + int comms_offset; ++ int ext_chan; + bool legacy_gesture; + struct iqs7222_reg_grp_desc reg_grps[IQS7222_NUM_REG_GRPS]; + }; +@@ -315,6 +316,7 @@ static const struct iqs7222_dev_desc iqs + .allow_offset = 9, + .event_offset = 10, + .comms_offset = 12, ++ .ext_chan = 10, + .reg_grps = { + [IQS7222_REG_GRP_STAT] = { + .base = IQS7222_SYS_STATUS, +@@ -373,6 +375,7 @@ static const struct iqs7222_dev_desc iqs + .allow_offset = 9, + .event_offset = 10, + .comms_offset = 12, ++ .ext_chan = 10, + .legacy_gesture = true, + .reg_grps = { + [IQS7222_REG_GRP_STAT] = { +@@ -2244,7 +2247,7 @@ static int iqs7222_parse_chan(struct iqs + const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc; + struct i2c_client *client = iqs7222->client; + int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row; +- int ext_chan = rounddown(num_chan, 10); ++ int ext_chan = dev_desc->ext_chan ? : num_chan; + int error, i; + u16 *chan_setup = iqs7222->chan_setup[chan_index]; + u16 *sys_setup = iqs7222->sys_setup; +@@ -2445,7 +2448,7 @@ static int iqs7222_parse_sldr(struct iqs + const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc; + struct i2c_client *client = iqs7222->client; + int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row; +- int ext_chan = rounddown(num_chan, 10); ++ int ext_chan = dev_desc->ext_chan ? : num_chan; + int count, error, reg_offset, i; + u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset]; + u16 *sldr_setup = iqs7222->sldr_setup[sldr_index]; diff --git a/queue-6.15/input-xpad-support-acer-ngr-200-controller.patch b/queue-6.15/input-xpad-support-acer-ngr-200-controller.patch new file mode 100644 index 0000000000..52f6fbefbf --- /dev/null +++ b/queue-6.15/input-xpad-support-acer-ngr-200-controller.patch @@ -0,0 +1,38 @@ +From 22c69d786ef8fb789c61ca75492a272774221324 Mon Sep 17 00:00:00 2001 +From: Nilton Perim Neto +Date: Fri, 27 Jun 2025 16:29:40 -0700 +Subject: Input: xpad - support Acer NGR 200 Controller + +From: Nilton Perim Neto + +commit 22c69d786ef8fb789c61ca75492a272774221324 upstream. + +Add the NGR 200 Xbox 360 to the list of recognized controllers. + +Signed-off-by: Nilton Perim Neto +Link: https://lore.kernel.org/r/20250608060517.14967-1-niltonperimneto@gmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/joystick/xpad.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -174,6 +174,7 @@ static const struct xpad_device { + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, + { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX }, + { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX }, ++ { 0x0502, 0x1305, "Acer NGR200", 0, XTYPE_XBOX }, + { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX }, + { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX }, + { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX }, +@@ -520,6 +521,7 @@ static const struct usb_device_id xpad_t + XPAD_XBOX360_VENDOR(0x045e), /* Microsoft Xbox 360 controllers */ + XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft Xbox One controllers */ + XPAD_XBOX360_VENDOR(0x046d), /* Logitech Xbox 360-style controllers */ ++ XPAD_XBOX360_VENDOR(0x0502), /* Acer Inc. Xbox 360 style controllers */ + XPAD_XBOX360_VENDOR(0x056e), /* Elecom JC-U3613M */ + XPAD_XBOX360_VENDOR(0x06a3), /* Saitek P3600 */ + XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz Xbox 360 controllers */ diff --git a/queue-6.15/revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch b/queue-6.15/revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch new file mode 100644 index 0000000000..955b287f0b --- /dev/null +++ b/queue-6.15/revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch @@ -0,0 +1,112 @@ +From 7aed15379db9c6ec67999cdaf5c443b7be06ea73 Mon Sep 17 00:00:00 2001 +From: Roy Luo +Date: Thu, 22 May 2025 19:09:12 +0000 +Subject: Revert "usb: xhci: Implement xhci_handshake_check_state() helper" + +From: Roy Luo + +commit 7aed15379db9c6ec67999cdaf5c443b7be06ea73 upstream. + +This reverts commit 6ccb83d6c4972ebe6ae49de5eba051de3638362c. + +Commit 6ccb83d6c497 ("usb: xhci: Implement xhci_handshake_check_state() +helper") was introduced to workaround watchdog timeout issues on some +platforms, allowing xhci_reset() to bail out early without waiting +for the reset to complete. + +Skipping the xhci handshake during a reset is a dangerous move. The +xhci specification explicitly states that certain registers cannot +be accessed during reset in section 5.4.1 USB Command Register (USBCMD), +Host Controller Reset (HCRST) field: +"This bit is cleared to '0' by the Host Controller when the reset +process is complete. Software cannot terminate the reset process +early by writinga '0' to this bit and shall not write any xHC +Operational or Runtime registers until while HCRST is '1'." + +This behavior causes a regression on SNPS DWC3 USB controller with +dual-role capability. When the DWC3 controller exits host mode and +removes xhci while a reset is still in progress, and then tries to +configure its hardware for device mode, the ongoing reset leads to +register access issues; specifically, all register reads returns 0. +These issues extend beyond the xhci register space (which is expected +during a reset) and affect the entire DWC3 IP block, causing the DWC3 +device mode to malfunction. + +Cc: stable +Fixes: 6ccb83d6c497 ("usb: xhci: Implement xhci_handshake_check_state() helper") +Signed-off-by: Roy Luo +Link: https://lore.kernel.org/r/20250522190912.457583-3-royluo@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-ring.c | 5 ++--- + drivers/usb/host/xhci.c | 26 +------------------------- + drivers/usb/host/xhci.h | 2 -- + 3 files changed, 3 insertions(+), 30 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -518,9 +518,8 @@ static int xhci_abort_cmd_ring(struct xh + * In the future we should distinguish between -ENODEV and -ETIMEDOUT + * and try to recover a -ETIMEDOUT with a host controller reset. + */ +- ret = xhci_handshake_check_state(xhci, &xhci->op_regs->cmd_ring, +- CMD_RING_RUNNING, 0, 5 * 1000 * 1000, +- XHCI_STATE_REMOVING); ++ ret = xhci_handshake(&xhci->op_regs->cmd_ring, ++ CMD_RING_RUNNING, 0, 5 * 1000 * 1000); + if (ret < 0) { + xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret); + xhci_halt(xhci); +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -84,29 +84,6 @@ int xhci_handshake(void __iomem *ptr, u3 + } + + /* +- * xhci_handshake_check_state - same as xhci_handshake but takes an additional +- * exit_state parameter, and bails out with an error immediately when xhc_state +- * has exit_state flag set. +- */ +-int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr, +- u32 mask, u32 done, int usec, unsigned int exit_state) +-{ +- u32 result; +- int ret; +- +- ret = readl_poll_timeout_atomic(ptr, result, +- (result & mask) == done || +- result == U32_MAX || +- xhci->xhc_state & exit_state, +- 1, usec); +- +- if (result == U32_MAX || xhci->xhc_state & exit_state) +- return -ENODEV; +- +- return ret; +-} +- +-/* + * Disable interrupts and begin the xHCI halting process. + */ + void xhci_quiesce(struct xhci_hcd *xhci) +@@ -226,8 +203,7 @@ int xhci_reset(struct xhci_hcd *xhci, u6 + if (xhci->quirks & XHCI_INTEL_HOST) + udelay(1000); + +- ret = xhci_handshake_check_state(xhci, &xhci->op_regs->command, +- CMD_RESET, 0, timeout_us, XHCI_STATE_REMOVING); ++ ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us); + if (ret) + return ret; + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1855,8 +1855,6 @@ void xhci_remove_secondary_interrupter(s + /* xHCI host controller glue */ + typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); + int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us); +-int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr, +- u32 mask, u32 done, int usec, unsigned int exit_state); + void xhci_quiesce(struct xhci_hcd *xhci); + int xhci_halt(struct xhci_hcd *xhci); + int xhci_start(struct xhci_hcd *xhci); diff --git a/queue-6.15/series b/queue-6.15/series index c974e338a5..47e214daa9 100644 --- a/queue-6.15/series +++ b/queue-6.15/series @@ -138,3 +138,18 @@ wifi-ath6kl-remove-warn-on-bad-firmware-input.patch acpica-refuse-to-evaluate-a-method-if-arguments-are-.patch mtd-spinand-fix-memory-leak-of-ecc-engine-conf.patch rcu-return-early-if-callback-is-not-specified.patch +usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch +revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch +usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch +xhci-dbctty-disable-echo-flag-by-default.patch +xhci-dbc-flush-queued-requests-before-stopping-dbc.patch +xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch +hid-appletb-kbd-fix-memory-corruption-of-input_handler_list.patch +input-xpad-support-acer-ngr-200-controller.patch +input-iqs7222-explicitly-define-number-of-external-channels.patch +usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch +usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch +usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch +usb-dwc3-gadget-fix-trb-reclaim-logic-for-short-transfers-and-zlps.patch +usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch +usb-acpi-fix-device-link-removal.patch diff --git a/queue-6.15/usb-acpi-fix-device-link-removal.patch b/queue-6.15/usb-acpi-fix-device-link-removal.patch new file mode 100644 index 0000000000..8e11edce7b --- /dev/null +++ b/queue-6.15/usb-acpi-fix-device-link-removal.patch @@ -0,0 +1,74 @@ +From 3b18405763c1ebb1efc15feef5563c9cdb2cc3a7 Mon Sep 17 00:00:00 2001 +From: Heikki Krogerus +Date: Wed, 11 Jun 2025 14:14:15 +0300 +Subject: usb: acpi: fix device link removal + +From: Heikki Krogerus + +commit 3b18405763c1ebb1efc15feef5563c9cdb2cc3a7 upstream. + +The device link to the USB4 host interface has to be removed +manually since it's no longer auto removed. + +Fixes: 623dae3e7084 ("usb: acpi: fix boot hang due to early incorrect 'tunneled' USB3 device links") +Cc: stable +Signed-off-by: Heikki Krogerus +Reviewed-by: Mika Westerberg +Link: https://lore.kernel.org/r/20250611111415.2707865-1-heikki.krogerus@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 3 +++ + drivers/usb/core/usb-acpi.c | 4 +++- + include/linux/usb.h | 2 ++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2337,6 +2337,9 @@ void usb_disconnect(struct usb_device ** + usb_remove_ep_devs(&udev->ep0); + usb_unlock_device(udev); + ++ if (udev->usb4_link) ++ device_link_del(udev->usb4_link); ++ + /* Unregister the device. The device driver is responsible + * for de-configuring the device and invoking the remove-device + * notifier chain (used by usbfs and possibly others). +--- a/drivers/usb/core/usb-acpi.c ++++ b/drivers/usb/core/usb-acpi.c +@@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(usb_acpi_set_power_sta + */ + static int usb_acpi_add_usb4_devlink(struct usb_device *udev) + { +- const struct device_link *link; ++ struct device_link *link; + struct usb_port *port_dev; + struct usb_hub *hub; + +@@ -188,6 +188,8 @@ static int usb_acpi_add_usb4_devlink(str + dev_dbg(&port_dev->dev, "Created device link from %s to %s\n", + dev_name(&port_dev->child->dev), dev_name(nhi_fwnode->dev)); + ++ udev->usb4_link = link; ++ + return 0; + } + +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -614,6 +614,7 @@ struct usb3_lpm_parameters { + * FIXME -- complete doc + * @authenticated: Crypto authentication passed + * @tunnel_mode: Connection native or tunneled over USB4 ++ * @usb4_link: device link to the USB4 host interface + * @lpm_capable: device supports LPM + * @lpm_devinit_allow: Allow USB3 device initiated LPM, exit latency is in range + * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM +@@ -724,6 +725,7 @@ struct usb_device { + unsigned reset_resume:1; + unsigned port_is_suspended:1; + enum usb_link_tunnel_mode tunnel_mode; ++ struct device_link *usb4_link; + + int slot_id; + struct usb2_lpm_parameters l1_params; diff --git a/queue-6.15/usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch b/queue-6.15/usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch new file mode 100644 index 0000000000..b666f3d978 --- /dev/null +++ b/queue-6.15/usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch @@ -0,0 +1,36 @@ +From 7e2c421ef88e9da9c39e01496b7f5b0b354b42bc Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Thu, 19 Jun 2025 09:34:13 +0800 +Subject: usb: cdnsp: do not disable slot for disabled slot + +From: Peter Chen + +commit 7e2c421ef88e9da9c39e01496b7f5b0b354b42bc upstream. + +It doesn't need to do it, and the related command event returns +'Slot Not Enabled Error' status. + +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Cc: stable +Suggested-by: Hongliang Yang +Reviewed-by: Fugang Duan +Signed-off-by: Peter Chen +Link: https://lore.kernel.org/r/20250619013413.35817-1-peter.chen@cixtech.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdnsp-ring.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/cdnsp-ring.c ++++ b/drivers/usb/cdns3/cdnsp-ring.c +@@ -772,7 +772,9 @@ static int cdnsp_update_port_id(struct c + } + + if (port_id != old_port) { +- cdnsp_disable_slot(pdev); ++ if (pdev->slot_id) ++ cdnsp_disable_slot(pdev); ++ + pdev->active_port = port; + cdnsp_enable_slot(pdev); + } diff --git a/queue-6.15/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch b/queue-6.15/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch new file mode 100644 index 0000000000..9f84555150 --- /dev/null +++ b/queue-6.15/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch @@ -0,0 +1,109 @@ +From 2831a81077f5162f104ba5a97a7d886eb371c21c Mon Sep 17 00:00:00 2001 +From: Pawel Laszczak +Date: Fri, 20 Jun 2025 08:23:12 +0000 +Subject: usb: cdnsp: Fix issue with CV Bad Descriptor test + +From: Pawel Laszczak + +commit 2831a81077f5162f104ba5a97a7d886eb371c21c upstream. + +The SSP2 controller has extra endpoint state preserve bit (ESP) which +setting causes that endpoint state will be preserved during +Halt Endpoint command. It is used only for EP0. +Without this bit the Command Verifier "TD 9.10 Bad Descriptor Test" +failed. +Setting this bit doesn't have any impact for SSP controller. + +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Cc: stable +Signed-off-by: Pawel Laszczak +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/PH7PR07MB95382CCD50549DABAEFD6156DD7CA@PH7PR07MB9538.namprd07.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdnsp-debug.h | 5 +++-- + drivers/usb/cdns3/cdnsp-ep0.c | 18 +++++++++++++++--- + drivers/usb/cdns3/cdnsp-gadget.h | 6 ++++++ + drivers/usb/cdns3/cdnsp-ring.c | 3 ++- + 4 files changed, 26 insertions(+), 6 deletions(-) + +--- a/drivers/usb/cdns3/cdnsp-debug.h ++++ b/drivers/usb/cdns3/cdnsp-debug.h +@@ -327,12 +327,13 @@ static inline const char *cdnsp_decode_t + case TRB_RESET_EP: + case TRB_HALT_ENDPOINT: + ret = scnprintf(str, size, +- "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c", ++ "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c %c", + cdnsp_trb_type_string(type), + ep_num, ep_id % 2 ? "out" : "in", + TRB_TO_EP_INDEX(field3), field1, field0, + TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ field3 & TRB_CYCLE ? 'C' : 'c', ++ field3 & TRB_ESP ? 'P' : 'p'); + break; + case TRB_STOP_RING: + ret = scnprintf(str, size, +--- a/drivers/usb/cdns3/cdnsp-ep0.c ++++ b/drivers/usb/cdns3/cdnsp-ep0.c +@@ -414,6 +414,7 @@ static int cdnsp_ep0_std_request(struct + void cdnsp_setup_analyze(struct cdnsp_device *pdev) + { + struct usb_ctrlrequest *ctrl = &pdev->setup; ++ struct cdnsp_ep *pep; + int ret = -EINVAL; + u16 len; + +@@ -427,10 +428,21 @@ void cdnsp_setup_analyze(struct cdnsp_de + goto out; + } + ++ pep = &pdev->eps[0]; ++ + /* Restore the ep0 to Stopped/Running state. */ +- if (pdev->eps[0].ep_state & EP_HALTED) { +- trace_cdnsp_ep0_halted("Restore to normal state"); +- cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0); ++ if (pep->ep_state & EP_HALTED) { ++ if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_HALTED) ++ cdnsp_halt_endpoint(pdev, pep, 0); ++ ++ /* ++ * Halt Endpoint Command for SSP2 for ep0 preserve current ++ * endpoint state and driver has to synchronize the ++ * software endpoint state with endpoint output context ++ * state. ++ */ ++ pep->ep_state &= ~EP_HALTED; ++ pep->ep_state |= EP_STOPPED; + } + + /* +--- a/drivers/usb/cdns3/cdnsp-gadget.h ++++ b/drivers/usb/cdns3/cdnsp-gadget.h +@@ -987,6 +987,12 @@ enum cdnsp_setup_dev { + #define STREAM_ID_FOR_TRB(p) ((((p)) << 16) & GENMASK(31, 16)) + #define SCT_FOR_TRB(p) (((p) << 1) & 0x7) + ++/* ++ * Halt Endpoint Command TRB field. ++ * The ESP bit only exists in the SSP2 controller. ++ */ ++#define TRB_ESP BIT(9) ++ + /* Link TRB specific fields. */ + #define TRB_TC BIT(1) + +--- a/drivers/usb/cdns3/cdnsp-ring.c ++++ b/drivers/usb/cdns3/cdnsp-ring.c +@@ -2485,7 +2485,8 @@ void cdnsp_queue_halt_endpoint(struct cd + { + cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_HALT_ENDPOINT) | + SLOT_ID_FOR_TRB(pdev->slot_id) | +- EP_ID_FOR_TRB(ep_index)); ++ EP_ID_FOR_TRB(ep_index) | ++ (!ep_index ? TRB_ESP : 0)); + } + + void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num) diff --git a/queue-6.15/usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch b/queue-6.15/usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch new file mode 100644 index 0000000000..5d0527991f --- /dev/null +++ b/queue-6.15/usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch @@ -0,0 +1,70 @@ +From 31a6afbe86e8e9deba9ab53876ec49eafc7fd901 Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Sat, 14 Jun 2025 20:49:14 +0800 +Subject: usb: chipidea: udc: disconnect/reconnect from host when do suspend/resume + +From: Xu Yang + +commit 31a6afbe86e8e9deba9ab53876ec49eafc7fd901 upstream. + +Shawn and John reported a hang issue during system suspend as below: + + - USB gadget is enabled as Ethernet + - There is data transfer over USB Ethernet (scp a big file between host + and device) + - Device is going in/out suspend (echo mem > /sys/power/state) + +The root cause is the USB device controller is suspended but the USB bus +is still active which caused the USB host continues to transfer data with +device and the device continues to queue USB requests (in this case, a +delayed TCP ACK packet trigger the issue) after controller is suspended, +however the USB controller clock is already gated off. Then if udc driver +access registers after that point, the system will hang. + +The correct way to avoid such issue is to disconnect device from host when +the USB bus is not at suspend state. Then the host will receive disconnect +event and stop data transfer in time. To continue make USB gadget device +work after system resume, this will reconnect device automatically. + +To make usb wakeup work if USB bus is already at suspend state, this will +keep connection for it only when USB device controller has enabled wakeup +capability. + +Reported-by: Shawn Guo +Reported-by: John Ernberg +Closes: https://lore.kernel.org/linux-usb/aEZxmlHmjeWcXiF3@dragon/ +Tested-by: John Ernberg # iMX8QXP +Fixes: 235ffc17d014 ("usb: chipidea: udc: add suspend/resume support for device controller") +Cc: stable +Reviewed-by: Jun Li +Signed-off-by: Xu Yang +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20250614124914.207540-1-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/chipidea/udc.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -2374,6 +2374,10 @@ static void udc_suspend(struct ci_hdrc * + */ + if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0) + hw_write(ci, OP_ENDPTLISTADDR, ~0, ~0); ++ ++ if (ci->gadget.connected && ++ (!ci->suspended || !device_may_wakeup(ci->dev))) ++ usb_gadget_disconnect(&ci->gadget); + } + + static void udc_resume(struct ci_hdrc *ci, bool power_lost) +@@ -2384,6 +2388,9 @@ static void udc_resume(struct ci_hdrc *c + OTGSC_BSVIS | OTGSC_BSVIE); + if (ci->vbus_active) + usb_gadget_vbus_disconnect(&ci->gadget); ++ } else if (ci->vbus_active && ci->driver && ++ !ci->gadget.connected) { ++ usb_gadget_connect(&ci->gadget); + } + + /* Restore value 0 if it was set for power lost check */ diff --git a/queue-6.15/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch b/queue-6.15/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch new file mode 100644 index 0000000000..5ed14d1c8f --- /dev/null +++ b/queue-6.15/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch @@ -0,0 +1,100 @@ +From 630a1dec3b0eba2a695b9063f1c205d585cbfec9 Mon Sep 17 00:00:00 2001 +From: Kuen-Han Tsai +Date: Wed, 28 May 2025 18:03:11 +0800 +Subject: usb: dwc3: Abort suspend on soft disconnect failure + +From: Kuen-Han Tsai + +commit 630a1dec3b0eba2a695b9063f1c205d585cbfec9 upstream. + +When dwc3_gadget_soft_disconnect() fails, dwc3_suspend_common() keeps +going with the suspend, resulting in a period where the power domain is +off, but the gadget driver remains connected. Within this time frame, +invoking vbus_event_work() will cause an error as it attempts to access +DWC3 registers for endpoint disabling after the power domain has been +completely shut down. + +Abort the suspend sequence when dwc3_gadget_suspend() cannot halt the +controller and proceeds with a soft connect. + +Fixes: 9f8a67b65a49 ("usb: dwc3: gadget: fix gadget suspend/resume") +Cc: stable +Acked-by: Thinh Nguyen +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250528100315.2162699-1-khtsai@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 9 +++++++-- + drivers/usb/dwc3/gadget.c | 22 +++++++++------------- + 2 files changed, 16 insertions(+), 15 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -2388,6 +2388,7 @@ static int dwc3_suspend_common(struct dw + { + u32 reg; + int i; ++ int ret; + + if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) { + dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & +@@ -2406,7 +2407,9 @@ static int dwc3_suspend_common(struct dw + case DWC3_GCTL_PRTCAP_DEVICE: + if (pm_runtime_suspended(dwc->dev)) + break; +- dwc3_gadget_suspend(dwc); ++ ret = dwc3_gadget_suspend(dwc); ++ if (ret) ++ return ret; + synchronize_irq(dwc->irq_gadget); + dwc3_core_exit(dwc); + break; +@@ -2441,7 +2444,9 @@ static int dwc3_suspend_common(struct dw + break; + + if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { +- dwc3_gadget_suspend(dwc); ++ ret = dwc3_gadget_suspend(dwc); ++ if (ret) ++ return ret; + synchronize_irq(dwc->irq_gadget); + } + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -4821,26 +4821,22 @@ int dwc3_gadget_suspend(struct dwc3 *dwc + int ret; + + ret = dwc3_gadget_soft_disconnect(dwc); +- if (ret) +- goto err; +- +- spin_lock_irqsave(&dwc->lock, flags); +- if (dwc->gadget_driver) +- dwc3_disconnect_gadget(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); +- +- return 0; +- +-err: + /* + * Attempt to reset the controller's state. Likely no + * communication can be established until the host + * performs a port reset. + */ +- if (dwc->softconnect) ++ if (ret && dwc->softconnect) { + dwc3_gadget_soft_connect(dwc); ++ return -EAGAIN; ++ } + +- return ret; ++ spin_lock_irqsave(&dwc->lock, flags); ++ if (dwc->gadget_driver) ++ dwc3_disconnect_gadget(dwc); ++ spin_unlock_irqrestore(&dwc->lock, flags); ++ ++ return 0; + } + + int dwc3_gadget_resume(struct dwc3 *dwc) diff --git a/queue-6.15/usb-dwc3-gadget-fix-trb-reclaim-logic-for-short-transfers-and-zlps.patch b/queue-6.15/usb-dwc3-gadget-fix-trb-reclaim-logic-for-short-transfers-and-zlps.patch new file mode 100644 index 0000000000..6d637a82a2 --- /dev/null +++ b/queue-6.15/usb-dwc3-gadget-fix-trb-reclaim-logic-for-short-transfers-and-zlps.patch @@ -0,0 +1,51 @@ +From 80e08394377559ed5a2ccadd861e62d24b826911 Mon Sep 17 00:00:00 2001 +From: SCHNEIDER Johannes +Date: Wed, 25 Jun 2025 07:49:16 +0000 +Subject: usb: dwc3: gadget: Fix TRB reclaim logic for short transfers and ZLPs + +From: SCHNEIDER Johannes + +commit 80e08394377559ed5a2ccadd861e62d24b826911 upstream. + +Commit 96c7bf8f6b3e ("usb: dwc3: gadget: Cleanup SG handling") updated +the TRB reclaim path to use the TRB CHN (Chain) bit to determine whether +a TRB was part of a chain. However, this inadvertently changed the +behavior of reclaiming the final TRB in some scatter-gather or short +transfer cases. + +In particular, if the final TRB did not have the CHN bit set, the +cleanup path could incorrectly skip clearing the HWO (Hardware Own) +bit, leaving stale TRBs in the ring. This resulted in broken data +transfer completions in userspace, notably for MTP over FunctionFS. + +Fix this by unconditionally clearing the HWO bit during TRB reclaim, +regardless of the CHN bit state. This restores correct behavior +especially for transfers that require ZLPs or end on non-CHN TRBs. + +Fixes: 61440628a4ff ("usb: dwc3: gadget: Cleanup SG handling") +Signed-off-by: Johannes Schneider +Acked-by: Thinh Nguyen +Cc: stable +Link: https://lore.kernel.org/r/AM8PR06MB7521A29A8863C838B54987B6BC7BA@AM8PR06MB7521.eurprd06.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index b6b63b530148..74968f93d4a3 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -3516,7 +3516,7 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, + * We're going to do that here to avoid problems of HW trying + * to use bogus TRBs for transfers. + */ +- if (chain && (trb->ctrl & DWC3_TRB_CTRL_HWO)) ++ if (trb->ctrl & DWC3_TRB_CTRL_HWO) + trb->ctrl &= ~DWC3_TRB_CTRL_HWO; + + /* +-- +2.50.0 + diff --git a/queue-6.15/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch b/queue-6.15/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch new file mode 100644 index 0000000000..1468637616 --- /dev/null +++ b/queue-6.15/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch @@ -0,0 +1,110 @@ +From cbc889ab0122366f6cdbe3c28d477c683ebcebc2 Mon Sep 17 00:00:00 2001 +From: Raju Rangoju +Date: Fri, 27 Jun 2025 17:41:19 +0300 +Subject: usb: xhci: quirk for data loss in ISOC transfers + +From: Raju Rangoju + +commit cbc889ab0122366f6cdbe3c28d477c683ebcebc2 upstream. + +During the High-Speed Isochronous Audio transfers, xHCI +controller on certain AMD platforms experiences momentary data +loss. This results in Missed Service Errors (MSE) being +generated by the xHCI. + +The root cause of the MSE is attributed to the ISOC OUT endpoint +being omitted from scheduling. This can happen when an IN +endpoint with a 64ms service interval either is pre-scheduled +prior to the ISOC OUT endpoint or the interval of the ISOC OUT +endpoint is shorter than that of the IN endpoint. Consequently, +the OUT service is neglected when an IN endpoint with a service +interval exceeding 32ms is scheduled concurrently (every 64ms in +this scenario). + +This issue is particularly seen on certain older AMD platforms. +To mitigate this problem, it is recommended to adjust the service +interval of the IN endpoint to not exceed 32ms (interval 8). This +adjustment ensures that the OUT endpoint will not be bypassed, +even if a smaller interval value is utilized. + +Cc: stable +Signed-off-by: Raju Rangoju +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250627144127.3889714-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-mem.c | 4 ++++ + drivers/usb/host/xhci-pci.c | 25 +++++++++++++++++++++++++ + drivers/usb/host/xhci.h | 1 + + 3 files changed, 30 insertions(+) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1420,6 +1420,10 @@ int xhci_endpoint_init(struct xhci_hcd * + /* Periodic endpoint bInterval limit quirk */ + if (usb_endpoint_xfer_int(&ep->desc) || + usb_endpoint_xfer_isoc(&ep->desc)) { ++ if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_9) && ++ interval >= 9) { ++ interval = 8; ++ } + if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) && + udev->speed >= USB_SPEED_HIGH && + interval >= 7) { +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -71,12 +71,22 @@ + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0 + ++#define PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI 0x13ed ++#define PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI 0x13ee ++#define PCI_DEVICE_ID_AMD_STARSHIP_XHCI 0x148c ++#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI 0x15d4 ++#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI 0x15d5 ++#define PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI 0x15e0 ++#define PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI 0x15e1 ++#define PCI_DEVICE_ID_AMD_RAVEN2_XHCI 0x15e5 + #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba + #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb + #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc + ++#define PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI 0x7316 ++ + #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 + #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 + #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 +@@ -280,6 +290,21 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; + ++ if (pdev->vendor == PCI_VENDOR_ID_AMD && ++ (pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_STARSHIP_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_RAVEN2_XHCI)) ++ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9; ++ ++ if (pdev->vendor == PCI_VENDOR_ID_ATI && ++ pdev->device == PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI) ++ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9; ++ + if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96) + xhci->quirks |= XHCI_AMD_0x96_HOST; + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1637,6 +1637,7 @@ struct xhci_hcd { + #define XHCI_WRITE_64_HI_LO BIT_ULL(47) + #define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48) + #define XHCI_ETRON_HOST BIT_ULL(49) ++#define XHCI_LIMIT_ENDPOINT_INTERVAL_9 BIT_ULL(50) + + unsigned int num_active_eps; + unsigned int limit_active_eps; diff --git a/queue-6.15/usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch b/queue-6.15/usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch new file mode 100644 index 0000000000..9591956725 --- /dev/null +++ b/queue-6.15/usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch @@ -0,0 +1,49 @@ +From 3eff494f6e17abf932699483f133a708ac0355dc Mon Sep 17 00:00:00 2001 +From: Roy Luo +Date: Thu, 22 May 2025 19:09:11 +0000 +Subject: usb: xhci: Skip xhci_reset in xhci_resume if xhci is being removed + +From: Roy Luo + +commit 3eff494f6e17abf932699483f133a708ac0355dc upstream. + +xhci_reset() currently returns -ENODEV if XHCI_STATE_REMOVING is +set, without completing the xhci handshake, unless the reset completes +exceptionally quickly. This behavior causes a regression on Synopsys +DWC3 USB controllers with dual-role capabilities. + +Specifically, when a DWC3 controller exits host mode and removes xhci +while a reset is still in progress, and then attempts to configure its +hardware for device mode, the ongoing, incomplete reset leads to +critical register access issues. All register reads return zero, not +just within the xHCI register space (which might be expected during a +reset), but across the entire DWC3 IP block. + +This patch addresses the issue by preventing xhci_reset() from being +called in xhci_resume() and bailing out early in the reinit flow when +XHCI_STATE_REMOVING is set. + +Cc: stable +Fixes: 6ccb83d6c497 ("usb: xhci: Implement xhci_handshake_check_state() helper") +Suggested-by: Mathias Nyman +Signed-off-by: Roy Luo +Link: https://lore.kernel.org/r/20250522190912.457583-2-royluo@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1084,7 +1084,10 @@ int xhci_resume(struct xhci_hcd *xhci, b + xhci_dbg(xhci, "Stop HCD\n"); + xhci_halt(xhci); + xhci_zero_64b_regs(xhci); +- retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC); ++ if (xhci->xhc_state & XHCI_STATE_REMOVING) ++ retval = -ENODEV; ++ else ++ retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC); + spin_unlock_irq(&xhci->lock); + if (retval) + return retval; diff --git a/queue-6.15/xhci-dbc-flush-queued-requests-before-stopping-dbc.patch b/queue-6.15/xhci-dbc-flush-queued-requests-before-stopping-dbc.patch new file mode 100644 index 0000000000..ae3181db3b --- /dev/null +++ b/queue-6.15/xhci-dbc-flush-queued-requests-before-stopping-dbc.patch @@ -0,0 +1,37 @@ +From efe3e3ae5a66cb38ef29c909e951b4039044bae9 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 27 Jun 2025 17:41:22 +0300 +Subject: xhci: dbc: Flush queued requests before stopping dbc + +From: Mathias Nyman + +commit efe3e3ae5a66cb38ef29c909e951b4039044bae9 upstream. + +Flush dbc requests when dbc is stopped and transfer rings are freed. +Failure to flush them lead to leaking memory and dbc completing odd +requests after resuming from suspend, leading to error messages such as: + +[ 95.344392] xhci_hcd 0000:00:0d.0: no matched request + +Cc: stable +Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250627144127.3889714-5-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -652,6 +652,10 @@ static void xhci_dbc_stop(struct xhci_db + case DS_DISABLED: + return; + case DS_CONFIGURED: ++ spin_lock(&dbc->lock); ++ xhci_dbc_flush_requests(dbc); ++ spin_unlock(&dbc->lock); ++ + if (dbc->driver->disconnect) + dbc->driver->disconnect(dbc); + break; diff --git a/queue-6.15/xhci-dbctty-disable-echo-flag-by-default.patch b/queue-6.15/xhci-dbctty-disable-echo-flag-by-default.patch new file mode 100644 index 0000000000..ad7f6accf5 --- /dev/null +++ b/queue-6.15/xhci-dbctty-disable-echo-flag-by-default.patch @@ -0,0 +1,39 @@ +From 2b857d69a5e116150639a0c6c39c86cc329939ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= +Date: Fri, 27 Jun 2025 17:41:21 +0300 +Subject: xhci: dbctty: disable ECHO flag by default +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Łukasz Bartosik + +commit 2b857d69a5e116150639a0c6c39c86cc329939ee upstream. + +When /dev/ttyDBC0 device is created then by default ECHO flag +is set for the terminal device. However if data arrives from +a peer before application using /dev/ttyDBC0 applies its set +of terminal flags then the arriving data will be echoed which +might not be desired behavior. + +Fixes: 4521f1613940 ("xhci: dbctty: split dbc tty driver registration and unregistration functions.") +Cc: stable +Signed-off-by: Łukasz Bartosik +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/stable/20250610111802.18742-1-ukaszb%40chromium.org +Link: https://lore.kernel.org/r/20250627144127.3889714-4-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgtty.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/host/xhci-dbgtty.c ++++ b/drivers/usb/host/xhci-dbgtty.c +@@ -617,6 +617,7 @@ int dbc_tty_init(void) + dbc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + dbc_tty_driver->subtype = SERIAL_TYPE_NORMAL; + dbc_tty_driver->init_termios = tty_std_termios; ++ dbc_tty_driver->init_termios.c_lflag &= ~ECHO; + dbc_tty_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + dbc_tty_driver->init_termios.c_ispeed = 9600; diff --git a/queue-6.15/xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch b/queue-6.15/xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch new file mode 100644 index 0000000000..6b3938be8a --- /dev/null +++ b/queue-6.15/xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch @@ -0,0 +1,33 @@ +From cd65ee81240e8bc3c3119b46db7f60c80864b90b Mon Sep 17 00:00:00 2001 +From: Hongyu Xie +Date: Fri, 27 Jun 2025 17:41:20 +0300 +Subject: xhci: Disable stream for xHC controller with XHCI_BROKEN_STREAMS + +From: Hongyu Xie + +commit cd65ee81240e8bc3c3119b46db7f60c80864b90b upstream. + +Disable stream for platform xHC controller with broken stream. + +Fixes: 14aec589327a6 ("storage: accept some UAS devices if streams are unavailable") +Cc: stable +Signed-off-by: Hongyu Xie +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250627144127.3889714-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-plat.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -326,7 +326,8 @@ int xhci_plat_probe(struct platform_devi + } + + usb3_hcd = xhci_get_usb3_hcd(xhci); +- if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4) ++ if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && ++ !(xhci->quirks & XHCI_BROKEN_STREAMS)) + usb3_hcd->can_do_streams = 1; + + if (xhci->shared_hcd) {