From: Greg Kroah-Hartman Date: Tue, 8 Jul 2025 09:10:35 +0000 (+0200) Subject: 6.12-stable patches X-Git-Tag: v5.15.187~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2c172f77930f0f9a234e7028003f81444250320f;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: 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-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.12/input-iqs7222-explicitly-define-number-of-external-channels.patch b/queue-6.12/input-iqs7222-explicitly-define-number-of-external-channels.patch new file mode 100644 index 0000000000..6cec583146 --- /dev/null +++ b/queue-6.12/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; +@@ -2448,7 +2451,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.12/input-xpad-support-acer-ngr-200-controller.patch b/queue-6.12/input-xpad-support-acer-ngr-200-controller.patch new file mode 100644 index 0000000000..748f065652 --- /dev/null +++ b/queue-6.12/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 }, +@@ -515,6 +516,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.12/revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch b/queue-6.12/revert-usb-xhci-implement-xhci_handshake_check_state-helper.patch new file mode 100644 index 0000000000..5223852ff3 --- /dev/null +++ b/queue-6.12/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 +@@ -461,9 +461,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 +@@ -83,29 +83,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) +@@ -225,8 +202,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 +@@ -1846,8 +1846,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.12/series b/queue-6.12/series index 937ff7a2e5..f96e6ba849 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -197,3 +197,16 @@ ib-mlx5-fix-potential-deadlock-in-mr-deregistration.patch drm-xe-bmg-update-wa_22019338487.patch drm-xe-allow-dropping-kunit-dependency-as-built-in.patch nfsv4-flexfiles-fix-handling-of-nfs-level-errors-in-.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 +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-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch +usb-acpi-fix-device-link-removal.patch diff --git a/queue-6.12/usb-acpi-fix-device-link-removal.patch b/queue-6.12/usb-acpi-fix-device-link-removal.patch new file mode 100644 index 0000000000..628be3e699 --- /dev/null +++ b/queue-6.12/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 +@@ -2336,6 +2336,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 +@@ -612,6 +612,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 +@@ -722,6 +723,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.12/usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch b/queue-6.12/usb-cdnsp-do-not-disable-slot-for-disabled-slot.patch new file mode 100644 index 0000000000..b666f3d978 --- /dev/null +++ b/queue-6.12/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.12/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch b/queue-6.12/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch new file mode 100644 index 0000000000..9f84555150 --- /dev/null +++ b/queue-6.12/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.12/usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch b/queue-6.12/usb-chipidea-udc-disconnect-reconnect-from-host-when-do-suspend-resume.patch new file mode 100644 index 0000000000..4cb33b7cef --- /dev/null +++ b/queue-6.12/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 +@@ -2362,6 +2362,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) +@@ -2372,6 +2376,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.12/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch b/queue-6.12/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch new file mode 100644 index 0000000000..146e2bd0eb --- /dev/null +++ b/queue-6.12/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 +@@ -2364,6 +2364,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)) & +@@ -2382,7 +2383,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; +@@ -2417,7 +2420,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 +@@ -4788,26 +4788,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.12/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch b/queue-6.12/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch new file mode 100644 index 0000000000..11e77765f9 --- /dev/null +++ b/queue-6.12/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 +@@ -1426,6 +1426,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 +@@ -286,6 +296,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 +@@ -1626,6 +1626,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.12/usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch b/queue-6.12/usb-xhci-skip-xhci_reset-in-xhci_resume-if-xhci-is-being-removed.patch new file mode 100644 index 0000000000..0abc55d06c --- /dev/null +++ b/queue-6.12/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 +@@ -1094,7 +1094,10 @@ int xhci_resume(struct xhci_hcd *xhci, p + 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.12/xhci-dbc-flush-queued-requests-before-stopping-dbc.patch b/queue-6.12/xhci-dbc-flush-queued-requests-before-stopping-dbc.patch new file mode 100644 index 0000000000..e634c98aa0 --- /dev/null +++ b/queue-6.12/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 +@@ -651,6 +651,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.12/xhci-dbctty-disable-echo-flag-by-default.patch b/queue-6.12/xhci-dbctty-disable-echo-flag-by-default.patch new file mode 100644 index 0000000000..23af62e321 --- /dev/null +++ b/queue-6.12/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 +@@ -585,6 +585,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.12/xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch b/queue-6.12/xhci-disable-stream-for-xhc-controller-with-xhci_broken_streams.patch new file mode 100644 index 0000000000..6b3938be8a --- /dev/null +++ b/queue-6.12/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) {