[PATCH 1/3] USB: DWC3: Do not stop active transfers if already stopped

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It might happen that dwc3_remove_requests is called when req_queued list
is not empty but end transfer command was issued. It will occur if
dwc3_remove_requests is called again before interrupt for end transfer
command is received.

This situation can be reproduced when cable is physically disconnected after
some isoc in transfer (testusb case 16).

Signed-off-by: Pratyush Anand <pratyush.anand@xxxxxx>
---
 drivers/usb/dwc3/core.h   |    2 ++
 drivers/usb/dwc3/gadget.c |    5 ++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1210dae..5c6cd18 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -357,6 +357,7 @@ struct dwc3_event_buffer {
  * @name: a human readable name e.g. ep1out-bulk
  * @direction: true for TX, false for RX
  * @stream_capable: true when streams are enabled
+ * @end_xfer_issued: true when EndTransfer command has been issued
  */
 struct dwc3_ep {
 	struct usb_ep		endpoint;
@@ -394,6 +395,7 @@ struct dwc3_ep {
 
 	unsigned		direction:1;
 	unsigned		stream_capable:1;
+	unsigned		end_xfer_issued:1;
 };
 
 enum dwc3_phy {
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 322b62e..fe2f4f9 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -530,7 +530,7 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
 	struct dwc3_request		*req;
 
-	if (!list_empty(&dep->req_queued))
+	if (!list_empty(&dep->req_queued) && !dep->end_xfer_issued)
 		dwc3_stop_active_transfer(dwc, dep->number);
 
 	while (!list_empty(&dep->request_list)) {
@@ -1762,6 +1762,7 @@ static void dwc3_ep_cmd_compl(struct dwc3_ep *dep,
 
 	switch (cmd_type) {
 	case DWC3_DEPCMD_ENDTRANSFER:
+		dep->end_xfer_issued = false;
 		dwc3_process_ep_cmd_complete(dep, event);
 		break;
 	case DWC3_DEPCMD_STARTTRANSFER:
@@ -1885,6 +1886,8 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
 		cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx);
 		memset(&params, 0, sizeof(params));
 		ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
+		if (!ret)
+			dep->end_xfer_issued = true;
 		WARN_ON_ONCE(ret);
 		dep->res_trans_idx = 0;
 	}
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux