--- /dev/null
+From 97b32f0d52a750ff406ecbc485721ca788fbf70f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 16:25:26 +0300
+Subject: bus: imx-weim: fix branch condition evaluates to a garbage value
+
+From: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+
+[ Upstream commit 1adab2922c58e7ff4fa9f0b43695079402cce876 ]
+
+If bus type is other than imx50_weim_devtype and have no child devices,
+variable 'ret' in function weim_parse_dt() will not be initialized, but
+will be used as branch condition and return value. Fix this by
+initializing 'ret' with 0.
+
+This was discovered with help of clang-analyzer, but the situation is
+quite possible in real life.
+
+Fixes: 52c47b63412b ("bus: imx-weim: improve error handling upon child probe-failure")
+Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+Cc: stable@vger.kernel.org
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/imx-weim.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
+index 28bb65a5613fd..201767823edb5 100644
+--- a/drivers/bus/imx-weim.c
++++ b/drivers/bus/imx-weim.c
+@@ -192,8 +192,8 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
+ const struct of_device_id *of_id = of_match_device(weim_id_table,
+ &pdev->dev);
+ const struct imx_weim_devtype *devtype = of_id->data;
++ int ret = 0, have_child = 0;
+ struct device_node *child;
+- int ret, have_child = 0;
+ struct cs_timing_state ts = {};
+ u32 reg;
+
+--
+2.39.2
+
--- /dev/null
+From c3708cee6516c0fc5cbc69525e42c0b2deea2b22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Mar 2023 16:31:32 -0700
+Subject: fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit a075bacde257f755bea0e53400c9f1cdd1b8e8e6 ]
+
+The full pagecache drop at the end of FS_IOC_ENABLE_VERITY is causing
+performance problems and is hindering adoption of fsverity. It was
+intended to solve a race condition where unverified pages might be left
+in the pagecache. But actually it doesn't solve it fully.
+
+Since the incomplete solution for this race condition has too much
+performance impact for it to be worth it, let's remove it for now.
+
+Fixes: 3fda4c617e84 ("fs-verity: implement FS_IOC_ENABLE_VERITY ioctl")
+Cc: stable@vger.kernel.org
+Reviewed-by: Victor Hsieh <victorhsieh@google.com>
+Link: https://lore.kernel.org/r/20230314235332.50270-1-ebiggers@kernel.org
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/verity/enable.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/fs/verity/enable.c b/fs/verity/enable.c
+index 60a4372aa4d75..dfe8acc32df66 100644
+--- a/fs/verity/enable.c
++++ b/fs/verity/enable.c
+@@ -391,25 +391,27 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
+ goto out_drop_write;
+
+ err = enable_verity(filp, &arg);
+- if (err)
+- goto out_allow_write_access;
+
+ /*
+- * Some pages of the file may have been evicted from pagecache after
+- * being used in the Merkle tree construction, then read into pagecache
+- * again by another process reading from the file concurrently. Since
+- * these pages didn't undergo verification against the file digest which
+- * fs-verity now claims to be enforcing, we have to wipe the pagecache
+- * to ensure that all future reads are verified.
++ * We no longer drop the inode's pagecache after enabling verity. This
++ * used to be done to try to avoid a race condition where pages could be
++ * evicted after being used in the Merkle tree construction, then
++ * re-instantiated by a concurrent read. Such pages are unverified, and
++ * the backing storage could have filled them with different content, so
++ * they shouldn't be used to fulfill reads once verity is enabled.
++ *
++ * But, dropping the pagecache has a big performance impact, and it
++ * doesn't fully solve the race condition anyway. So for those reasons,
++ * and also because this race condition isn't very important relatively
++ * speaking (especially for small-ish files, where the chance of a page
++ * being used, evicted, *and* re-instantiated all while enabling verity
++ * is quite small), we no longer drop the inode's pagecache.
+ */
+- filemap_write_and_wait(inode->i_mapping);
+- invalidate_inode_pages2(inode->i_mapping);
+
+ /*
+ * allow_write_access() is needed to pair with deny_write_access().
+ * Regardless, the filesystem won't allow writing to verity files.
+ */
+-out_allow_write_access:
+ allow_write_access(filp);
+ out_drop_write:
+ mnt_drop_write_file(filp);
+--
+2.39.2
+
--- /dev/null
+From d952a98e9995e9a8602b4523c4c1fea7a85d3d74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 23:47:05 +0100
+Subject: kcsan: avoid passing -g for test
+
+From: Marco Elver <elver@google.com>
+
+[ Upstream commit 5eb39cde1e2487ba5ec1802dc5e58a77e700d99e ]
+
+Nathan reported that when building with GNU as and a version of clang that
+defaults to DWARF5, the assembler will complain with:
+
+ Error: non-constant .uleb128 is not supported
+
+This is because `-g` defaults to the compiler debug info default. If the
+assembler does not support some of the directives used, the above errors
+occur. To fix, remove the explicit passing of `-g`.
+
+All the test wants is that stack traces print valid function names, and
+debug info is not required for that. (I currently cannot recall why I
+added the explicit `-g`.)
+
+Link: https://lkml.kernel.org/r/20230316224705.709984-2-elver@google.com
+Fixes: 1fe84fd4a402 ("kcsan: Add test suite")
+Signed-off-by: Marco Elver <elver@google.com>
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kcsan/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/kcsan/Makefile b/kernel/kcsan/Makefile
+index 5936288ee938b..c4ddd189f3e07 100644
+--- a/kernel/kcsan/Makefile
++++ b/kernel/kcsan/Makefile
+@@ -13,6 +13,6 @@ CFLAGS_core.o := $(call cc-option,-fno-conserve-stack) \
+ obj-y := core.o debugfs.o report.o
+ obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o
+
+-CFLAGS_kcsan_test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
++CFLAGS_kcsan_test.o := $(CFLAGS_KCSAN) -fno-omit-frame-pointer
+ CFLAGS_kcsan_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
+ obj-$(CONFIG_KCSAN_KUNIT_TEST) += kcsan_test.o
+--
+2.39.2
+
--- /dev/null
+From 68c64313d57d6fb66818a1cb0aff4a7e2fdb171b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 11:43:58 +0100
+Subject: kernel: kcsan: kcsan_test: build without structleak plugin
+
+From: Anders Roxell <anders.roxell@linaro.org>
+
+[ Upstream commit 6fcd4267a840d0536b8e5334ad5f31e4105fce85 ]
+
+Building kcsan_test with structleak plugin enabled makes the stack frame
+size to grow.
+
+kernel/kcsan/kcsan_test.c:704:1: error: the frame size of 3296 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
+
+Turn off the structleak plugin checks for kcsan_test.
+
+Link: https://lkml.kernel.org/r/20221128104358.2660634-1-anders.roxell@linaro.org
+Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
+Suggested-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Marco Elver <elver@google.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: David Gow <davidgow@google.com>
+Cc: Jason A. Donenfeld <Jason@zx2c4.com>
+Cc: Kees Cook <keescook@chromium.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 5eb39cde1e24 ("kcsan: avoid passing -g for test")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kcsan/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/kcsan/Makefile b/kernel/kcsan/Makefile
+index c2bb07f5bcc72..5936288ee938b 100644
+--- a/kernel/kcsan/Makefile
++++ b/kernel/kcsan/Makefile
+@@ -14,4 +14,5 @@ obj-y := core.o debugfs.o report.o
+ obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o
+
+ CFLAGS_kcsan_test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
++CFLAGS_kcsan_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
+ obj-$(CONFIG_KCSAN_KUNIT_TEST) += kcsan_test.o
+--
+2.39.2
+
--- /dev/null
+From 1c83edba3ec947a1b69826ae299db4e36dc3cd4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 15:25:34 +0900
+Subject: ksmbd: don't terminate inactive sessions after a few seconds
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit be6f42fad5f5fd1fea9d562df82c38ad6ed3bfe9 ]
+
+Steve reported that inactive sessions are terminated after a few
+seconds. ksmbd terminate when receiving -EAGAIN error from
+kernel_recvmsg(). -EAGAIN means there is no data available in timeout.
+So ksmbd should keep connection with unlimited retries instead of
+terminating inactive sessions.
+
+Cc: stable@vger.kernel.org
+Reported-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/connection.c | 4 ++--
+ fs/ksmbd/connection.h | 3 ++-
+ fs/ksmbd/transport_rdma.c | 2 +-
+ fs/ksmbd/transport_tcp.c | 35 +++++++++++++++++++++++------------
+ 4 files changed, 28 insertions(+), 16 deletions(-)
+
+diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c
+index 6105649b4ebb0..610abaadbb677 100644
+--- a/fs/ksmbd/connection.c
++++ b/fs/ksmbd/connection.c
+@@ -292,7 +292,7 @@ int ksmbd_conn_handler_loop(void *p)
+ kvfree(conn->request_buf);
+ conn->request_buf = NULL;
+
+- size = t->ops->read(t, hdr_buf, sizeof(hdr_buf));
++ size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
+ if (size != sizeof(hdr_buf))
+ break;
+
+@@ -335,7 +335,7 @@ int ksmbd_conn_handler_loop(void *p)
+ * We already read 4 bytes to find out PDU size, now
+ * read in PDU
+ */
+- size = t->ops->read(t, conn->request_buf + 4, pdu_size);
++ size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2);
+ if (size < 0) {
+ pr_err("sock_read failed: %d\n", size);
+ break;
+diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h
+index 8694aef482c1a..4b15c5e673d92 100644
+--- a/fs/ksmbd/connection.h
++++ b/fs/ksmbd/connection.h
+@@ -122,7 +122,8 @@ struct ksmbd_conn_ops {
+ struct ksmbd_transport_ops {
+ int (*prepare)(struct ksmbd_transport *t);
+ void (*disconnect)(struct ksmbd_transport *t);
+- int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
++ int (*read)(struct ksmbd_transport *t, char *buf,
++ unsigned int size, int max_retries);
+ int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
+ int size, bool need_invalidate_rkey,
+ unsigned int remote_key);
+diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c
+index 9d67419929d6c..9ca29cdb7898f 100644
+--- a/fs/ksmbd/transport_rdma.c
++++ b/fs/ksmbd/transport_rdma.c
+@@ -663,7 +663,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t,
+ }
+
+ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
+- unsigned int size)
++ unsigned int size, int unused)
+ {
+ struct smb_direct_recvmsg *recvmsg;
+ struct smb_direct_data_transfer *data_transfer;
+diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c
+index e0ca6cc04b91c..d1d7954368a56 100644
+--- a/fs/ksmbd/transport_tcp.c
++++ b/fs/ksmbd/transport_tcp.c
+@@ -291,16 +291,18 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
+
+ /**
+ * ksmbd_tcp_readv() - read data from socket in given iovec
+- * @t: TCP transport instance
+- * @iov_orig: base IO vector
+- * @nr_segs: number of segments in base iov
+- * @to_read: number of bytes to read from socket
++ * @t: TCP transport instance
++ * @iov_orig: base IO vector
++ * @nr_segs: number of segments in base iov
++ * @to_read: number of bytes to read from socket
++ * @max_retries: maximum retry count
+ *
+ * Return: on success return number of bytes read from socket,
+ * otherwise return error number
+ */
+ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+- unsigned int nr_segs, unsigned int to_read)
++ unsigned int nr_segs, unsigned int to_read,
++ int max_retries)
+ {
+ int length = 0;
+ int total_read;
+@@ -308,7 +310,6 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ struct msghdr ksmbd_msg;
+ struct kvec *iov;
+ struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
+- int max_retry = 2;
+
+ iov = get_conn_iovec(t, nr_segs);
+ if (!iov)
+@@ -335,14 +336,23 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
+ total_read = -EAGAIN;
+ break;
+- } else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
+- max_retry) {
++ } else if (length == -ERESTARTSYS || length == -EAGAIN) {
++ /*
++ * If max_retries is negative, Allow unlimited
++ * retries to keep connection with inactive sessions.
++ */
++ if (max_retries == 0) {
++ total_read = length;
++ break;
++ } else if (max_retries > 0) {
++ max_retries--;
++ }
++
+ usleep_range(1000, 2000);
+ length = 0;
+- max_retry--;
+ continue;
+ } else if (length <= 0) {
+- total_read = -EAGAIN;
++ total_read = length;
+ break;
+ }
+ }
+@@ -358,14 +368,15 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ * Return: on success return number of bytes read from socket,
+ * otherwise return error number
+ */
+-static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read)
++static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf,
++ unsigned int to_read, int max_retries)
+ {
+ struct kvec iov;
+
+ iov.iov_base = buf;
+ iov.iov_len = to_read;
+
+- return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read);
++ return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read, max_retries);
+ }
+
+ static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
+--
+2.39.2
+
--- /dev/null
+fsverity-don-t-drop-pagecache-at-end-of-fs_ioc_enabl.patch
+usb-dwc3-gadget-move-cmd_endtransfer-to-extra-functi.patch
+usb-dwc3-gadget-add-1ms-delay-after-end-transfer-com.patch
+kernel-kcsan-kcsan_test-build-without-structleak-plu.patch
+kcsan-avoid-passing-g-for-test.patch
+ksmbd-don-t-terminate-inactive-sessions-after-a-few-.patch
+bus-imx-weim-fix-branch-condition-evaluates-to-a-gar.patch
--- /dev/null
+From 8c9c9333b819ac70930f9abe4aa7d37638979308 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 12:05:57 -0800
+Subject: usb: dwc3: gadget: Add 1ms delay after end transfer command without
+ IOC
+
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+
+[ Upstream commit d8a2bb4eb75866275b5cf7de2e593ac3449643e2 ]
+
+Previously, there was a 100uS delay inserted after issuing an end transfer
+command for specific controller revisions. This was due to the fact that
+there was a GUCTL2 bit field which enabled synchronous completion of the
+end transfer command once the CMDACT bit was cleared in the DEPCMD
+register. Since this bit does not exist for all controller revisions and
+the current implementation heavily relies on utizling the EndTransfer
+command completion interrupt, add the delay back in for uses where the
+interrupt on completion bit is not set, and increase the duration to 1ms
+for the controller to complete the command.
+
+An issue was seen where the USB request buffer was unmapped while the DWC3
+controller was still accessing the TRB. However, it was confirmed that the
+end transfer command was successfully submitted. (no end transfer timeout)
+In situations, such as dwc3_gadget_soft_disconnect() and
+__dwc3_gadget_ep_disable(), the dwc3_remove_request() is utilized, which
+will issue the end transfer command, and follow up with
+dwc3_gadget_giveback(). At least for the USB ep disable path, it is
+required for any pending and started requests to be completed and returned
+to the function driver in the same context of the disable call. Without
+the GUCTL2 bit, it is not ensured that the end transfer is completed before
+the buffers are unmapped.
+
+Fixes: cf2f8b63f7f1 ("usb: dwc3: gadget: Remove END_TRANSFER delay")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20230306200557.29387-1-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 1689c09b937ae..eaf64f33fe077 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1652,6 +1652,7 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
+ */
+ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
+ {
++ struct dwc3 *dwc = dep->dwc;
+ struct dwc3_gadget_ep_cmd_params params;
+ u32 cmd;
+ int ret;
+@@ -1665,10 +1666,13 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
+ WARN_ON_ONCE(ret);
+ dep->resource_index = 0;
+
+- if (!interrupt)
++ if (!interrupt) {
++ if (!DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC3, 310A))
++ mdelay(1);
+ dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+- else if (!ret)
++ } else if (!ret) {
+ dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
++ }
+
+ return ret;
+ }
+@@ -3654,7 +3658,11 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+ * enabled, the EndTransfer command will have completed upon
+ * returning from this function.
+ *
+- * This mode is NOT available on the DWC_usb31 IP.
++ * This mode is NOT available on the DWC_usb31 IP. In this
++ * case, if the IOC bit is not set, then delay by 1ms
++ * after issuing the EndTransfer command. This allows for the
++ * controller to handle the command completely before DWC3
++ * remove requests attempts to unmap USB request buffers.
+ */
+
+ __dwc3_stop_active_transfer(dep, force, interrupt);
+--
+2.39.2
+
--- /dev/null
+From e73ad3c25f36dfbbb332e22c332b224f24bc884c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Mar 2022 22:12:51 +0100
+Subject: usb: dwc3: gadget: move cmd_endtransfer to extra function
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+[ Upstream commit e192cc7b52399d1b073f88cd3ba128b74d3a57f1 ]
+
+This patch adds the extra function __dwc3_stop_active_transfer to
+consolidate the same codepath.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20220306211251.2281335-3-m.grzeschik@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: d8a2bb4eb758 ("usb: dwc3: gadget: Add 1ms delay after end transfer command without IOC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 69 +++++++++++++++++++++------------------
+ 1 file changed, 37 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index a0100d26de8e1..1689c09b937ae 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1639,6 +1639,40 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
+ return DWC3_DSTS_SOFFN(reg);
+ }
+
++/**
++ * __dwc3_stop_active_transfer - stop the current active transfer
++ * @dep: isoc endpoint
++ * @force: set forcerm bit in the command
++ * @interrupt: command complete interrupt after End Transfer command
++ *
++ * When setting force, the ForceRM bit will be set. In that case
++ * the controller won't update the TRB progress on command
++ * completion. It also won't clear the HWO bit in the TRB.
++ * The command will also not complete immediately in that case.
++ */
++static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
++{
++ struct dwc3_gadget_ep_cmd_params params;
++ u32 cmd;
++ int ret;
++
++ cmd = DWC3_DEPCMD_ENDTRANSFER;
++ cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0;
++ cmd |= interrupt ? DWC3_DEPCMD_CMDIOC : 0;
++ cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
++ memset(¶ms, 0, sizeof(params));
++ ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
++ WARN_ON_ONCE(ret);
++ dep->resource_index = 0;
++
++ if (!interrupt)
++ dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
++ else if (!ret)
++ dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
++
++ return ret;
++}
++
+ /**
+ * dwc3_gadget_start_isoc_quirk - workaround invalid frame number
+ * @dep: isoc endpoint
+@@ -1808,21 +1842,8 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
+ * status, issue END_TRANSFER command and retry on the next XferNotReady
+ * event.
+ */
+- if (ret == -EAGAIN) {
+- struct dwc3_gadget_ep_cmd_params params;
+- u32 cmd;
+-
+- cmd = DWC3_DEPCMD_ENDTRANSFER |
+- DWC3_DEPCMD_CMDIOC |
+- DWC3_DEPCMD_PARAM(dep->resource_index);
+-
+- dep->resource_index = 0;
+- memset(¶ms, 0, sizeof(params));
+-
+- ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
+- if (!ret)
+- dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+- }
++ if (ret == -EAGAIN)
++ ret = __dwc3_stop_active_transfer(dep, false, true);
+
+ return ret;
+ }
+@@ -3605,10 +3626,6 @@ static void dwc3_reset_gadget(struct dwc3 *dwc)
+ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+ bool interrupt)
+ {
+- struct dwc3_gadget_ep_cmd_params params;
+- u32 cmd;
+- int ret;
+-
+ if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+ (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+ return;
+@@ -3640,19 +3657,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+ * This mode is NOT available on the DWC_usb31 IP.
+ */
+
+- cmd = DWC3_DEPCMD_ENDTRANSFER;
+- cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0;
+- cmd |= interrupt ? DWC3_DEPCMD_CMDIOC : 0;
+- cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
+- memset(¶ms, 0, sizeof(params));
+- ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
+- WARN_ON_ONCE(ret);
+- dep->resource_index = 0;
+-
+- if (!interrupt)
+- dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+- else
+- dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
++ __dwc3_stop_active_transfer(dep, force, interrupt);
+ }
+
+ static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
+--
+2.39.2
+