Re: [PATCH 4/5] usb: dwc3: Allow end transfer commands to be sent during soft disconnect

From: Wesley Cheng
Date: Tue Jul 12 2022 - 18:09:54 EST


Hi Thinh,

On 7/8/2022 6:58 PM, Thinh Nguyen wrote:
On 7/8/2022, Wesley Cheng wrote:
If soft disconnect is in progress, allow the endxfer command to be sent,
without this, there is an issue where the stop active transfer call
(during pullup disable) wouldn't actually issue the endxfer command,
while clearing the DEP flag.

In addition, if the DWC3_EP_DELAY_STOP flag was set before soft disconnect
started (i.e. from the dequeue path), ensure that when the EP0 transaction
completes during soft disconnect, to issue the endxfer with the force
parameter set, as it does not expect a command complete event.

Signed-off-by: Wesley Cheng <quic_wcheng@xxxxxxxxxxx>
---
drivers/usb/dwc3/ep0.c | 3 +--
drivers/usb/dwc3/gadget.c | 5 ++++-
2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 506ef717fdc0..5851b0e9db0a 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -290,8 +290,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
if (!(dwc3_ep->flags & DWC3_EP_DELAY_STOP))
continue;
- dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP;
- dwc3_stop_active_transfer(dwc3_ep, true, true);
+ dwc3_stop_active_transfer(dwc3_ep, true, dwc->connected);
}
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index bd40608b19df..fba2797ad9ae 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3696,8 +3696,10 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
return;
+ if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
+ return;
+
if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
- (dep->flags & DWC3_EP_DELAY_STOP) ||
(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
return;
@@ -3744,6 +3746,7 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
__dwc3_stop_active_transfer(dep, force, interrupt);
spin_lock(&dwc->lock);
+ dep->flags &= ~DWC3_EP_DELAY_STOP;

Can we clear this flag in __dwc3_stop_active_transfer(). It should apply
if End Transfer command was sent.

I wanted to make sure that we weren't modifying the DEP flags outside of a spin lock. Patch#3 modifies it where we unlock before calling __dwc3_stop_active_transfer(), so we can allow the dwc3 threaded IRQ handle events while the cmd status polling happens.

Maybe we can unlock/lock the dwc3->lock inside __dwc3_stop_active_transfer() and that way we can ensure DEP flags are modified properly?

Thanks
Wesley Cheng