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
         * 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;
 }
 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;
         * 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)