From: Greg Kroah-Hartman Date: Mon, 27 Mar 2023 16:56:20 +0000 (+0200) Subject: 6.2-stable patches X-Git-Tag: v5.15.105~57 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bdefb2bbedd0af5d8ac4d287c62f412b3540909d;p=thirdparty%2Fkernel%2Fstable-queue.git 6.2-stable patches added patches: smb3-fix-unusable-share-after-force-unmount-failure.patch smb3-lower-default-deferred-close-timeout-to-address-perf-regression.patch thunderbolt-add-missing-unset_inbound_sbtx-for-retimer-access.patch thunderbolt-add-quirk-to-disable-clx.patch thunderbolt-call-tb_check_quirks-after-initializing-adapters.patch thunderbolt-disable-interrupt-auto-clear-for-rings.patch thunderbolt-fix-memory-leak-in-margining.patch thunderbolt-rename-shadowed-variables-bit-to-interrupt_bit-and-auto_clear_bit.patch thunderbolt-use-const-qualifier-for-ring_interrupt_index.patch thunderbolt-use-scale-field-when-allocating-usb3-bandwidth.patch uas-add-us_fl_no_report_opcodes-for-jmicron-jms583gen-2.patch --- diff --git a/queue-6.2/series b/queue-6.2/series index e5589785b37..79599871f9d 100644 --- a/queue-6.2/series +++ b/queue-6.2/series @@ -112,3 +112,14 @@ hwmon-fix-potential-sensor-registration-fail-if-of_n.patch hwmon-it87-fix-voltage-scaling-for-chips-with-10.9mv.patch scsi-qla2xxx-synchronize-the-iocb-count-to-be-in-order.patch scsi-qla2xxx-perform-lockless-command-completion-in-abort-path.patch +smb3-lower-default-deferred-close-timeout-to-address-perf-regression.patch +smb3-fix-unusable-share-after-force-unmount-failure.patch +uas-add-us_fl_no_report_opcodes-for-jmicron-jms583gen-2.patch +thunderbolt-use-scale-field-when-allocating-usb3-bandwidth.patch +thunderbolt-call-tb_check_quirks-after-initializing-adapters.patch +thunderbolt-add-quirk-to-disable-clx.patch +thunderbolt-fix-memory-leak-in-margining.patch +thunderbolt-disable-interrupt-auto-clear-for-rings.patch +thunderbolt-add-missing-unset_inbound_sbtx-for-retimer-access.patch +thunderbolt-use-const-qualifier-for-ring_interrupt_index.patch +thunderbolt-rename-shadowed-variables-bit-to-interrupt_bit-and-auto_clear_bit.patch diff --git a/queue-6.2/smb3-fix-unusable-share-after-force-unmount-failure.patch b/queue-6.2/smb3-fix-unusable-share-after-force-unmount-failure.patch new file mode 100644 index 00000000000..77e465d7bb6 --- /dev/null +++ b/queue-6.2/smb3-fix-unusable-share-after-force-unmount-failure.patch @@ -0,0 +1,104 @@ +From 491eafce1a51c457701351a4bf40733799745314 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 23 Mar 2023 16:20:02 -0500 +Subject: smb3: fix unusable share after force unmount failure + +From: Steve French + +commit 491eafce1a51c457701351a4bf40733799745314 upstream. + +If user does forced unmount ("umount -f") while files are still open +on the share (as was seen in a Kubernetes example running on SMB3.1.1 +mount) then we were marking the share as "TID_EXITING" in umount_begin() +which caused all subsequent operations (except write) to fail ... but +unfortunately when umount_begin() is called we do not know yet that +there are open files or active references on the share that would prevent +unmount from succeeding. Kubernetes had example when they were doing +umount -f when files were open which caused the share to become +unusable until the files were closed (and the umount retried). + +Fix this so that TID_EXITING is not set until we are about to send +the tree disconnect (not at the beginning of forced umounts in +umount_begin) so that if "umount -f" fails (due to open files or +references) the mount is still usable. + +Cc: stable@vger.kernel.org +Reviewed-by: Shyam Prasad N +Reviewed-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/cifsfs.c | 9 ++++++--- + fs/cifs/cifssmb.c | 6 ++---- + fs/cifs/connect.c | 1 + + fs/cifs/smb2pdu.c | 8 ++------ + 4 files changed, 11 insertions(+), 13 deletions(-) + +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -730,13 +730,16 @@ static void cifs_umount_begin(struct sup + spin_lock(&tcon->tc_lock); + if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) { + /* we have other mounts to same share or we have +- already tried to force umount this and woken up ++ already tried to umount this and woken up + all waiting network requests, nothing to do */ + spin_unlock(&tcon->tc_lock); + spin_unlock(&cifs_tcp_ses_lock); + return; +- } else if (tcon->tc_count == 1) +- tcon->status = TID_EXITING; ++ } ++ /* ++ * can not set tcon->status to TID_EXITING yet since we don't know if umount -f will ++ * fail later (e.g. due to open files). TID_EXITING will be set just before tdis req sent ++ */ + spin_unlock(&tcon->tc_lock); + spin_unlock(&cifs_tcp_ses_lock); + +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -85,13 +85,11 @@ cifs_reconnect_tcon(struct cifs_tcon *tc + + /* + * only tree disconnect, open, and write, (and ulogoff which does not +- * have tcon) are allowed as we start force umount ++ * have tcon) are allowed as we start umount + */ + spin_lock(&tcon->tc_lock); + if (tcon->status == TID_EXITING) { +- if (smb_command != SMB_COM_WRITE_ANDX && +- smb_command != SMB_COM_OPEN_ANDX && +- smb_command != SMB_COM_TREE_DISCONNECT) { ++ if (smb_command != SMB_COM_TREE_DISCONNECT) { + spin_unlock(&tcon->tc_lock); + cifs_dbg(FYI, "can not send cmd %d while umounting\n", + smb_command); +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -2363,6 +2363,7 @@ cifs_put_tcon(struct cifs_tcon *tcon) + WARN_ON(tcon->tc_count < 0); + + list_del_init(&tcon->tcon_list); ++ tcon->status = TID_EXITING; + spin_unlock(&tcon->tc_lock); + spin_unlock(&cifs_tcp_ses_lock); + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -225,13 +225,9 @@ smb2_reconnect(__le16 smb2_command, stru + spin_lock(&tcon->tc_lock); + if (tcon->status == TID_EXITING) { + /* +- * only tree disconnect, open, and write, +- * (and ulogoff which does not have tcon) +- * are allowed as we start force umount. ++ * only tree disconnect allowed when disconnecting ... + */ +- if ((smb2_command != SMB2_WRITE) && +- (smb2_command != SMB2_CREATE) && +- (smb2_command != SMB2_TREE_DISCONNECT)) { ++ if (smb2_command != SMB2_TREE_DISCONNECT) { + spin_unlock(&tcon->tc_lock); + cifs_dbg(FYI, "can not send cmd %d while umounting\n", + smb2_command); diff --git a/queue-6.2/smb3-lower-default-deferred-close-timeout-to-address-perf-regression.patch b/queue-6.2/smb3-lower-default-deferred-close-timeout-to-address-perf-regression.patch new file mode 100644 index 00000000000..530e9171e9f --- /dev/null +++ b/queue-6.2/smb3-lower-default-deferred-close-timeout-to-address-perf-regression.patch @@ -0,0 +1,42 @@ +From 7e0e76d99079be13c9961dde7c93b2d1ee665af4 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 23 Mar 2023 15:10:26 -0500 +Subject: smb3: lower default deferred close timeout to address perf regression + +From: Steve French + +commit 7e0e76d99079be13c9961dde7c93b2d1ee665af4 upstream. + +Performance tests with large number of threads noted that the change +of the default closetimeo (deferred close timeout between when +close is done by application and when client has to send the close +to the server), to 5 seconds from 1 second, significantly degraded +perf in some cases like this (in the filebench example reported, +the stats show close requests on the wire taking twice as long, +and 50% regression in filebench perf). This is stil configurable +via mount parm closetimeo, but to be safe, decrease default back +to its previous value of 1 second. + +Reported-by: Yin Fengwei +Reported-by: kernel test robot +Link: https://lore.kernel.org/lkml/997614df-10d4-af53-9571-edec36b0e2f3@intel.com/ +Fixes: 5efdd9122eff ("smb3: allow deferred close timeout to be configurable") +Cc: stable@vger.kernel.org # 6.0+ +Tested-by: Yin Fengwei +Reviewed-by: Paulo Alcantara (SUSE) +Reviewed-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/fs_context.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/cifs/fs_context.h ++++ b/fs/cifs/fs_context.h +@@ -286,5 +286,5 @@ extern void smb3_update_mnt_flags(struct + * max deferred close timeout (jiffies) - 2^30 + */ + #define SMB3_MAX_DCLOSETIMEO (1 << 30) +-#define SMB3_DEF_DCLOSETIMEO (5 * HZ) /* Can increase later, other clients use larger */ ++#define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */ + #endif diff --git a/queue-6.2/thunderbolt-add-missing-unset_inbound_sbtx-for-retimer-access.patch b/queue-6.2/thunderbolt-add-missing-unset_inbound_sbtx-for-retimer-access.patch new file mode 100644 index 00000000000..409886d6dd0 --- /dev/null +++ b/queue-6.2/thunderbolt-add-missing-unset_inbound_sbtx-for-retimer-access.patch @@ -0,0 +1,140 @@ +From cd0c1e582b055dea615001b8bd8eccaf6f69f7ce Mon Sep 17 00:00:00 2001 +From: Gil Fine +Date: Fri, 3 Mar 2023 00:17:24 +0200 +Subject: thunderbolt: Add missing UNSET_INBOUND_SBTX for retimer access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gil Fine + +commit cd0c1e582b055dea615001b8bd8eccaf6f69f7ce upstream. + +According to USB4 retimer specification, the process of firmware update +sequence requires issuing a SET_INBOUND_SBTX port operation that later +shall be followed by UNSET_INBOUND_SBTX port operation. This last step +is not currently issued by the driver but it is necessary to make sure +the retimers are put back to passthrough mode even during enumeration. + +If this step is missing the link may not come up properly after +soft-reboot for example. + +For this reason issue UNSET_INBOUND_SBTX after SET_INBOUND_SBTX for +enumeration and also when the NVM upgrade is run. + +Reported-by: Christian Schaubschläger +Link: https://lore.kernel.org/linux-usb/b556f5ed-5ee8-9990-9910-afd60db93310@gmx.at/ +Cc: stable@vger.kernel.org +Signed-off-by: Gil Fine +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/retimer.c | 23 +++++++++++++++++++++-- + drivers/thunderbolt/sb_regs.h | 1 + + drivers/thunderbolt/tb.h | 1 + + drivers/thunderbolt/usb4.c | 14 ++++++++++++++ + 4 files changed, 37 insertions(+), 2 deletions(-) + +--- a/drivers/thunderbolt/retimer.c ++++ b/drivers/thunderbolt/retimer.c +@@ -187,6 +187,22 @@ static ssize_t nvm_authenticate_show(str + return ret; + } + ++static void tb_retimer_set_inbound_sbtx(struct tb_port *port) ++{ ++ int i; ++ ++ for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) ++ usb4_port_retimer_set_inbound_sbtx(port, i); ++} ++ ++static void tb_retimer_unset_inbound_sbtx(struct tb_port *port) ++{ ++ int i; ++ ++ for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--) ++ usb4_port_retimer_unset_inbound_sbtx(port, i); ++} ++ + static ssize_t nvm_authenticate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) + { +@@ -213,6 +229,7 @@ static ssize_t nvm_authenticate_store(st + rt->auth_status = 0; + + if (val) { ++ tb_retimer_set_inbound_sbtx(rt->port); + if (val == AUTHENTICATE_ONLY) { + ret = tb_retimer_nvm_authenticate(rt, true); + } else { +@@ -232,6 +249,7 @@ static ssize_t nvm_authenticate_store(st + } + + exit_unlock: ++ tb_retimer_unset_inbound_sbtx(rt->port); + mutex_unlock(&rt->tb->lock); + exit_rpm: + pm_runtime_mark_last_busy(&rt->dev); +@@ -440,8 +458,7 @@ int tb_retimer_scan(struct tb_port *port + * Enable sideband channel for each retimer. We can do this + * regardless whether there is device connected or not. + */ +- for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) +- usb4_port_retimer_set_inbound_sbtx(port, i); ++ tb_retimer_set_inbound_sbtx(port); + + /* + * Before doing anything else, read the authentication status. +@@ -464,6 +481,8 @@ int tb_retimer_scan(struct tb_port *port + break; + } + ++ tb_retimer_unset_inbound_sbtx(port); ++ + if (!last_idx) + return 0; + +--- a/drivers/thunderbolt/sb_regs.h ++++ b/drivers/thunderbolt/sb_regs.h +@@ -20,6 +20,7 @@ enum usb4_sb_opcode { + USB4_SB_OPCODE_ROUTER_OFFLINE = 0x4e45534c, /* "LSEN" */ + USB4_SB_OPCODE_ENUMERATE_RETIMERS = 0x4d554e45, /* "ENUM" */ + USB4_SB_OPCODE_SET_INBOUND_SBTX = 0x5055534c, /* "LSUP" */ ++ USB4_SB_OPCODE_UNSET_INBOUND_SBTX = 0x50555355, /* "USUP" */ + USB4_SB_OPCODE_QUERY_LAST_RETIMER = 0x5453414c, /* "LAST" */ + USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE = 0x53534e47, /* "GNSS" */ + USB4_SB_OPCODE_NVM_SET_OFFSET = 0x53504f42, /* "BOPS" */ +--- a/drivers/thunderbolt/tb.h ++++ b/drivers/thunderbolt/tb.h +@@ -1220,6 +1220,7 @@ int usb4_port_sw_margin(struct tb_port * + int usb4_port_sw_margin_errors(struct tb_port *port, u32 *errors); + + int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index); ++int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index); + int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf, + u8 size); + int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg, +--- a/drivers/thunderbolt/usb4.c ++++ b/drivers/thunderbolt/usb4.c +@@ -1579,6 +1579,20 @@ int usb4_port_retimer_set_inbound_sbtx(s + } + + /** ++ * usb4_port_retimer_unset_inbound_sbtx() - Disable sideband channel transactions ++ * @port: USB4 port ++ * @index: Retimer index ++ * ++ * Disables sideband channel transations on SBTX. The reverse of ++ * usb4_port_retimer_set_inbound_sbtx(). ++ */ ++int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index) ++{ ++ return usb4_port_retimer_op(port, index, ++ USB4_SB_OPCODE_UNSET_INBOUND_SBTX, 500); ++} ++ ++/** + * usb4_port_retimer_read() - Read from retimer sideband registers + * @port: USB4 port + * @index: Retimer index diff --git a/queue-6.2/thunderbolt-add-quirk-to-disable-clx.patch b/queue-6.2/thunderbolt-add-quirk-to-disable-clx.patch new file mode 100644 index 00000000000..569780f31ed --- /dev/null +++ b/queue-6.2/thunderbolt-add-quirk-to-disable-clx.patch @@ -0,0 +1,89 @@ +From 7af9da8ce8f9a16221ecd8ba4280582f5bd452fc Mon Sep 17 00:00:00 2001 +From: Sanjay R Mehta +Date: Tue, 14 Feb 2023 13:13:50 -0600 +Subject: thunderbolt: Add quirk to disable CLx + +From: Sanjay R Mehta + +commit 7af9da8ce8f9a16221ecd8ba4280582f5bd452fc upstream. + +Add QUIRK_NO_CLX to disable the CLx state for hardware which +doesn't supports it. + +AMD Yellow Carp and Pink Sardine don't support CLx state, +hence disabling it using QUIRK_NO_CLX. + +Cc: stable@vger.kernel.org +Signed-off-by: Sanjay R Mehta +Signed-off-by: Basavaraj Natikar +[mw: added debug log when the quirk is run] +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/quirks.c | 13 +++++++++++++ + drivers/thunderbolt/tb.h | 11 ++++++++--- + 2 files changed, 21 insertions(+), 3 deletions(-) + +--- a/drivers/thunderbolt/quirks.c ++++ b/drivers/thunderbolt/quirks.c +@@ -20,6 +20,12 @@ static void quirk_dp_credit_allocation(s + } + } + ++static void quirk_clx_disable(struct tb_switch *sw) ++{ ++ sw->quirks |= QUIRK_NO_CLX; ++ tb_sw_dbg(sw, "disabling CL states\n"); ++} ++ + struct tb_quirk { + u16 hw_vendor_id; + u16 hw_device_id; +@@ -37,6 +43,13 @@ static const struct tb_quirk tb_quirks[] + * DP buffers. + */ + { 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation }, ++ /* ++ * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms. ++ */ ++ { 0x0438, 0x0208, 0x0000, 0x0000, quirk_clx_disable }, ++ { 0x0438, 0x0209, 0x0000, 0x0000, quirk_clx_disable }, ++ { 0x0438, 0x020a, 0x0000, 0x0000, quirk_clx_disable }, ++ { 0x0438, 0x020b, 0x0000, 0x0000, quirk_clx_disable }, + }; + + /** +--- a/drivers/thunderbolt/tb.h ++++ b/drivers/thunderbolt/tb.h +@@ -23,6 +23,11 @@ + #define NVM_MAX_SIZE SZ_512K + #define NVM_DATA_DWORDS 16 + ++/* Keep link controller awake during update */ ++#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0) ++/* Disable CLx if not supported */ ++#define QUIRK_NO_CLX BIT(1) ++ + /** + * struct tb_nvm - Structure holding NVM information + * @dev: Owner of the NVM +@@ -997,6 +1002,9 @@ static inline bool tb_switch_is_clx_enab + */ + static inline bool tb_switch_is_clx_supported(const struct tb_switch *sw) + { ++ if (sw->quirks & QUIRK_NO_CLX) ++ return false; ++ + return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw); + } + +@@ -1254,9 +1262,6 @@ struct usb4_port *usb4_port_device_add(s + void usb4_port_device_remove(struct usb4_port *usb4); + int usb4_port_device_resume(struct usb4_port *usb4); + +-/* Keep link controller awake during update */ +-#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0) +- + void tb_check_quirks(struct tb_switch *sw); + + #ifdef CONFIG_ACPI diff --git a/queue-6.2/thunderbolt-call-tb_check_quirks-after-initializing-adapters.patch b/queue-6.2/thunderbolt-call-tb_check_quirks-after-initializing-adapters.patch new file mode 100644 index 00000000000..1aa84154b14 --- /dev/null +++ b/queue-6.2/thunderbolt-call-tb_check_quirks-after-initializing-adapters.patch @@ -0,0 +1,40 @@ +From d2d6ddf188f609861489d5d188d545856a3ed399 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 3 Feb 2023 15:55:41 +0200 +Subject: thunderbolt: Call tb_check_quirks() after initializing adapters + +From: Mika Westerberg + +commit d2d6ddf188f609861489d5d188d545856a3ed399 upstream. + +In order to apply quirks based on certain adapter types move call to +tb_check_quirks() happen after the adapters are initialized. This should +not affect the existing quirks. + +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/switch.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -2960,8 +2960,6 @@ int tb_switch_add(struct tb_switch *sw) + dev_warn(&sw->dev, "reading DROM failed: %d\n", ret); + tb_sw_dbg(sw, "uid: %#llx\n", sw->uid); + +- tb_check_quirks(sw); +- + ret = tb_switch_set_uuid(sw); + if (ret) { + dev_err(&sw->dev, "failed to set UUID\n"); +@@ -2980,6 +2978,8 @@ int tb_switch_add(struct tb_switch *sw) + } + } + ++ tb_check_quirks(sw); ++ + tb_switch_default_link_ports(sw); + + ret = tb_switch_update_link_attributes(sw); diff --git a/queue-6.2/thunderbolt-disable-interrupt-auto-clear-for-rings.patch b/queue-6.2/thunderbolt-disable-interrupt-auto-clear-for-rings.patch new file mode 100644 index 00000000000..7435625fb63 --- /dev/null +++ b/queue-6.2/thunderbolt-disable-interrupt-auto-clear-for-rings.patch @@ -0,0 +1,125 @@ +From 468c49f44759720a312e52d44a71c3949ed63d7c Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Fri, 10 Mar 2023 11:20:50 -0600 +Subject: thunderbolt: Disable interrupt auto clear for rings + +From: Mario Limonciello + +commit 468c49f44759720a312e52d44a71c3949ed63d7c upstream. + +When interrupt auto clear is programmed, any read to the interrupt +status register will clear all interrupts. If two interrupts have +come in before one can be serviced then this will cause lost interrupts. + +On AMD USB4 routers this has manifested in odd problems particularly +with long strings of control tranfers such as reading the DROM via bit +banging. + +Instead of clearing interrupts automatically, clear the bit corresponding +to the given ring's interrupt in the ISR. + +Fixes: 7a1808f82a37 ("thunderbolt: Handle ring interrupt by reading interrupt status register") +Cc: Sanju Mehta +Cc: stable@vger.kernel.org +Tested-by: Anson Tsao +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/nhi.c | 40 +++++++++++++++++++++++++--------------- + drivers/thunderbolt/nhi_regs.h | 6 ++++-- + 2 files changed, 29 insertions(+), 17 deletions(-) + +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -71,24 +71,31 @@ static void ring_interrupt_active(struct + u32 step, shift, ivr, misc; + void __iomem *ivr_base; + int index; ++ int bit; + + if (ring->is_tx) + index = ring->hop; + else + index = ring->hop + ring->nhi->hop_count; + +- if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) { +- /* +- * Ask the hardware to clear interrupt status +- * bits automatically since we already know +- * which interrupt was triggered. +- */ +- misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); +- if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) { +- misc |= REG_DMA_MISC_INT_AUTO_CLEAR; +- iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC); +- } +- } ++ /* ++ * Intel routers support a bit that isn't part of ++ * the USB4 spec to ask the hardware to clear ++ * interrupt status bits automatically since ++ * we already know which interrupt was triggered. ++ * ++ * Other routers explicitly disable auto-clear ++ * to prevent conditions that may occur where two ++ * MSIX interrupts are simultaneously active and ++ * reading the register clears both of them. ++ */ ++ misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); ++ if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) ++ bit = REG_DMA_MISC_INT_AUTO_CLEAR; ++ else ++ bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR; ++ if (!(misc & bit)) ++ iowrite32(misc | bit, ring->nhi->iobase + REG_DMA_MISC); + + ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE; + step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS; +@@ -393,14 +400,17 @@ EXPORT_SYMBOL_GPL(tb_ring_poll_complete) + + static void ring_clear_msix(const struct tb_ring *ring) + { ++ int bit; ++ + if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) + return; + ++ bit = ring_interrupt_index(ring) & 31; + if (ring->is_tx) +- ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE); ++ iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR); + else +- ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE + +- 4 * (ring->nhi->hop_count / 32)); ++ iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR + ++ 4 * (ring->nhi->hop_count / 32)); + } + + static irqreturn_t ring_msix(int irq, void *data) +--- a/drivers/thunderbolt/nhi_regs.h ++++ b/drivers/thunderbolt/nhi_regs.h +@@ -77,12 +77,13 @@ struct ring_desc { + + /* + * three bitfields: tx, rx, rx overflow +- * Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are +- * cleared on read. New interrupts are fired only after ALL registers have been ++ * Every bitfield contains one bit for every hop (REG_HOP_COUNT). ++ * New interrupts are fired only after ALL registers have been + * read (even those containing only disabled rings). + */ + #define REG_RING_NOTIFY_BASE 0x37800 + #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32) ++#define REG_RING_INT_CLEAR 0x37808 + + /* + * two bitfields: rx, tx +@@ -105,6 +106,7 @@ struct ring_desc { + + #define REG_DMA_MISC 0x39864 + #define REG_DMA_MISC_INT_AUTO_CLEAR BIT(2) ++#define REG_DMA_MISC_DISABLE_AUTO_CLEAR BIT(17) + + #define REG_INMAIL_DATA 0x39900 + diff --git a/queue-6.2/thunderbolt-fix-memory-leak-in-margining.patch b/queue-6.2/thunderbolt-fix-memory-leak-in-margining.patch new file mode 100644 index 00000000000..9637ac6d7c4 --- /dev/null +++ b/queue-6.2/thunderbolt-fix-memory-leak-in-margining.patch @@ -0,0 +1,57 @@ +From acec726473822bc6b585961f4ca2a11fa7f28341 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 3 Mar 2023 11:25:08 +0200 +Subject: thunderbolt: Fix memory leak in margining + +From: Mika Westerberg + +commit acec726473822bc6b585961f4ca2a11fa7f28341 upstream. + +Memory for the usb4->margining needs to be relased for the upstream port +of the router as well, even though the debugfs directory gets released +with the router device removal. Fix this. + +Fixes: d0f1e0c2a699 ("thunderbolt: Add support for receiver lane margining") +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/debugfs.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/thunderbolt/debugfs.c ++++ b/drivers/thunderbolt/debugfs.c +@@ -942,7 +942,8 @@ static void margining_port_remove(struct + + snprintf(dir_name, sizeof(dir_name), "port%d", port->port); + parent = debugfs_lookup(dir_name, port->sw->debugfs_dir); +- debugfs_remove_recursive(debugfs_lookup("margining", parent)); ++ if (parent) ++ debugfs_remove_recursive(debugfs_lookup("margining", parent)); + + kfree(port->usb4->margining); + port->usb4->margining = NULL; +@@ -967,19 +968,18 @@ static void margining_switch_init(struct + + static void margining_switch_remove(struct tb_switch *sw) + { ++ struct tb_port *upstream, *downstream; + struct tb_switch *parent_sw; +- struct tb_port *downstream; + u64 route = tb_route(sw); + + if (!route) + return; + +- /* +- * Upstream is removed with the router itself but we need to +- * remove the downstream port margining directory. +- */ ++ upstream = tb_upstream_port(sw); + parent_sw = tb_switch_parent(sw); + downstream = tb_port_at(route, parent_sw); ++ ++ margining_port_remove(upstream); + margining_port_remove(downstream); + } + diff --git a/queue-6.2/thunderbolt-rename-shadowed-variables-bit-to-interrupt_bit-and-auto_clear_bit.patch b/queue-6.2/thunderbolt-rename-shadowed-variables-bit-to-interrupt_bit-and-auto_clear_bit.patch new file mode 100644 index 00000000000..d3badeab0ce --- /dev/null +++ b/queue-6.2/thunderbolt-rename-shadowed-variables-bit-to-interrupt_bit-and-auto_clear_bit.patch @@ -0,0 +1,78 @@ +From 58cdfe6f58b35f17f56386f5fcf937168a423ad1 Mon Sep 17 00:00:00 2001 +From: Tom Rix +Date: Wed, 15 Mar 2023 18:04:50 -0400 +Subject: thunderbolt: Rename shadowed variables bit to interrupt_bit and auto_clear_bit + +From: Tom Rix + +commit 58cdfe6f58b35f17f56386f5fcf937168a423ad1 upstream. + +cppcheck reports +drivers/thunderbolt/nhi.c:74:7: style: Local variable 'bit' shadows outer variable [shadowVariable] + int bit; + ^ +drivers/thunderbolt/nhi.c:66:6: note: Shadowed declaration + int bit = ring_interrupt_index(ring) & 31; + ^ +drivers/thunderbolt/nhi.c:74:7: note: Shadow variable + int bit; + ^ +For readablity rename the outer to interrupt_bit and the innner +to auto_clear_bit. + +Fixes: 468c49f44759 ("thunderbolt: Disable interrupt auto clear for ring") +Cc: stable@vger.kernel.org +Signed-off-by: Tom Rix +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/nhi.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -63,15 +63,15 @@ static void ring_interrupt_active(struct + { + int reg = REG_RING_INTERRUPT_BASE + + ring_interrupt_index(ring) / 32 * 4; +- int bit = ring_interrupt_index(ring) & 31; +- int mask = 1 << bit; ++ int interrupt_bit = ring_interrupt_index(ring) & 31; ++ int mask = 1 << interrupt_bit; + u32 old, new; + + if (ring->irq > 0) { + u32 step, shift, ivr, misc; + void __iomem *ivr_base; ++ int auto_clear_bit; + int index; +- int bit; + + if (ring->is_tx) + index = ring->hop; +@@ -91,11 +91,12 @@ static void ring_interrupt_active(struct + */ + misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); + if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) +- bit = REG_DMA_MISC_INT_AUTO_CLEAR; ++ auto_clear_bit = REG_DMA_MISC_INT_AUTO_CLEAR; + else +- bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR; +- if (!(misc & bit)) +- iowrite32(misc | bit, ring->nhi->iobase + REG_DMA_MISC); ++ auto_clear_bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR; ++ if (!(misc & auto_clear_bit)) ++ iowrite32(misc | auto_clear_bit, ++ ring->nhi->iobase + REG_DMA_MISC); + + ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE; + step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS; +@@ -115,7 +116,7 @@ static void ring_interrupt_active(struct + + dev_dbg(&ring->nhi->pdev->dev, + "%s interrupt at register %#x bit %d (%#x -> %#x)\n", +- active ? "enabling" : "disabling", reg, bit, old, new); ++ active ? "enabling" : "disabling", reg, interrupt_bit, old, new); + + if (new == old) + dev_WARN(&ring->nhi->pdev->dev, diff --git a/queue-6.2/thunderbolt-use-const-qualifier-for-ring_interrupt_index.patch b/queue-6.2/thunderbolt-use-const-qualifier-for-ring_interrupt_index.patch new file mode 100644 index 00000000000..d9191e6b8be --- /dev/null +++ b/queue-6.2/thunderbolt-use-const-qualifier-for-ring_interrupt_index.patch @@ -0,0 +1,33 @@ +From 1716efdb07938bd6510e1127d02012799112c433 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Fri, 10 Mar 2023 11:20:49 -0600 +Subject: thunderbolt: Use const qualifier for `ring_interrupt_index` + +From: Mario Limonciello + +commit 1716efdb07938bd6510e1127d02012799112c433 upstream. + +`ring_interrupt_index` doesn't change the data for `ring` so mark it as +const. This is needed by the following patch that disables interrupt +auto clear for rings. + +Cc: Sanju Mehta +Cc: stable@vger.kernel.org +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/nhi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -46,7 +46,7 @@ + #define QUIRK_AUTO_CLEAR_INT BIT(0) + #define QUIRK_E2E BIT(1) + +-static int ring_interrupt_index(struct tb_ring *ring) ++static int ring_interrupt_index(const struct tb_ring *ring) + { + int bit = ring->hop; + if (!ring->is_tx) diff --git a/queue-6.2/thunderbolt-use-scale-field-when-allocating-usb3-bandwidth.patch b/queue-6.2/thunderbolt-use-scale-field-when-allocating-usb3-bandwidth.patch new file mode 100644 index 00000000000..a3cb840f463 --- /dev/null +++ b/queue-6.2/thunderbolt-use-scale-field-when-allocating-usb3-bandwidth.patch @@ -0,0 +1,60 @@ +From c82510b1d87bdebfe916048857d2ef46f1778aa5 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Tue, 27 Dec 2022 11:55:26 +0200 +Subject: thunderbolt: Use scale field when allocating USB3 bandwidth + +From: Mika Westerberg + +commit c82510b1d87bdebfe916048857d2ef46f1778aa5 upstream. + +When tunneling aggregated USB3 (20 Gb/s) the bandwidth values that are +programmed to the ADP_USB3_CS_2 go higher than 4096 and that does not +fit anymore to the 12-bit field. Fix this by scaling the value using +the scale field accordingly. + +Fixes: 3b1d8d577ca8 ("thunderbolt: Implement USB3 bandwidth negotiation routines") +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/usb4.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +--- a/drivers/thunderbolt/usb4.c ++++ b/drivers/thunderbolt/usb4.c +@@ -2067,18 +2067,30 @@ static int usb4_usb3_port_write_allocate + int downstream_bw) + { + u32 val, ubw, dbw, scale; +- int ret; ++ int ret, max_bw; + +- /* Read the used scale, hardware default is 0 */ +- ret = tb_port_read(port, &scale, TB_CFG_PORT, +- port->cap_adap + ADP_USB3_CS_3, 1); ++ /* Figure out suitable scale */ ++ scale = 0; ++ max_bw = max(upstream_bw, downstream_bw); ++ while (scale < 64) { ++ if (mbps_to_usb3_bw(max_bw, scale) < 4096) ++ break; ++ scale++; ++ } ++ ++ if (WARN_ON(scale >= 64)) ++ return -EINVAL; ++ ++ ret = tb_port_write(port, &scale, TB_CFG_PORT, ++ port->cap_adap + ADP_USB3_CS_3, 1); + if (ret) + return ret; + +- scale &= ADP_USB3_CS_3_SCALE_MASK; + ubw = mbps_to_usb3_bw(upstream_bw, scale); + dbw = mbps_to_usb3_bw(downstream_bw, scale); + ++ tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale); ++ + ret = tb_port_read(port, &val, TB_CFG_PORT, + port->cap_adap + ADP_USB3_CS_2, 1); + if (ret) diff --git a/queue-6.2/uas-add-us_fl_no_report_opcodes-for-jmicron-jms583gen-2.patch b/queue-6.2/uas-add-us_fl_no_report_opcodes-for-jmicron-jms583gen-2.patch new file mode 100644 index 00000000000..72b55eacc9a --- /dev/null +++ b/queue-6.2/uas-add-us_fl_no_report_opcodes-for-jmicron-jms583gen-2.patch @@ -0,0 +1,36 @@ +From a37eb61b6ec064ac794b8a1e89fd33eb582fe51d Mon Sep 17 00:00:00 2001 +From: Yaroslav Furman +Date: Sun, 12 Mar 2023 11:07:45 +0200 +Subject: uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2 + +From: Yaroslav Furman + +commit a37eb61b6ec064ac794b8a1e89fd33eb582fe51d upstream. + +Just like other JMicron JMS5xx enclosures, it chokes on report-opcodes, +let's avoid them. + +Signed-off-by: Yaroslav Furman +Cc: stable +Link: https://lore.kernel.org/r/20230312090745.47962-1-yaro330@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -111,6 +111,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x99 + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA), + ++/* Reported by: Yaroslav Furman */ ++UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999, ++ "JMicron", ++ "JMS583Gen 2", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_REPORT_OPCODES), ++ + /* Reported-by: Thinh Nguyen */ + UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, + "PNY",