Skip to contentSkip to conversation

usb: dwc3: gadget: Fix END_TRANSFER handling

PATCH New Thinh Nguyen 1 participant 3 messages Nov 27, 2019

Subsystems (3)
lore
Share & tools
lore

Thinh Nguyen

author maintainer
#0 lore raw

cover usb: dwc3: gadget: Fix END_TRANSFER handling

This patch series adds a couple of fixes related to handling END_TRANSFER command.

Thinh Nguyen (2):
usb: dwc3: gadget: Clear started flag for non-IOC
usb: dwc3: ep0: Clear started flag on completion

 drivers/usb/dwc3/ep0.c    | 8 ++++++++
 drivers/usb/dwc3/gadget.c | 3 +++
 2 files changed, 11 insertions(+)
Signature · 1 line
2.11.0
author maintainer
#1 lore raw

PATCH 1/2 usb: dwc3: gadget: Clear started flag for non-IOC

Normally the END_TRANSFER command completion handler will clear the DWC3_EP_TRANSFER_STARTED flag. However, if the command was sent without interrupt on completion, then the flag will not be cleared. Make sure to clear the flag in this case.

---
 drivers/usb/dwc3/gadget.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/usb/dwc3/gadget.c +3 -0
index 7f97856e6b20..95a0b2e7ecea 100644
@@ -2716,6 +2716,9 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 	WARN_ON_ONCE(ret);
 	dep->resource_index = 0;
 
+	if (!interrupt)
+		dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+
 	if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
 		udelay(100);
 }
Signature · 1 line
2.11.0
author maintainer
#2 lore raw

PATCH 2/2 usb: dwc3: ep0: Clear started flag on completion

In reply to Thinh Nguyen

Clear ep0's DWC3_EP_TRANSFER_STARTED flag if the END_TRANSFER command is completed. Otherwise, we can't start control transfer again after END_TRANSFER.

---
 drivers/usb/dwc3/ep0.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/usb/dwc3/ep0.c +8 -0
index 3996b9c4ff8d..fd1b100d2927 100644
@@ -1117,6 +1117,9 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 void dwc3_ep0_interrupt(struct dwc3 *dwc,
 		const struct dwc3_event_depevt *event)
 {
+	struct dwc3_ep	*dep = dwc->eps[event->endpoint_number];
+	u8		cmd;
+
 	switch (event->endpoint_event) {
 	case DWC3_DEPEVT_XFERCOMPLETE:
 		dwc3_ep0_xfer_complete(dwc, event);
@@ -1129,7 +1132,12 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc,
 	case DWC3_DEPEVT_XFERINPROGRESS:
 	case DWC3_DEPEVT_RXTXFIFOEVT:
 	case DWC3_DEPEVT_STREAMEVT:
+		break;
 	case DWC3_DEPEVT_EPCMDCMPLT:
+		cmd = DEPEVT_PARAMETER_CMD(event->parameters);
+
+		if (cmd == DWC3_DEPCMD_ENDTRANSFER)
+			dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
 		break;
 	}
 }
Signature · 1 line
2.11.0