From 1fd81463a9309ebbd64d545dcf6678ea398b6847 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Sat, 14 Jan 2017 16:40:39 +0800 Subject: [PATCH] UPSTREAM: usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase When handing the SETUP packet by composite_setup(), we will release the dwc->lock. If we get the 'USB_GADGET_DELAYED_STATUS' result from setup function, which means we need to delay handling the STATUS phase. But during the lock release period, maybe the request for handling delay STATUS phase has been queued into list before we set 'dwc->delayed_status' flag or entering 'EP0_STATUS_PHASE' phase, then we will miss the chance to handle the STATUS phase. Thus we should check if the request for delay STATUS phase has been enqueued when entering 'EP0_STATUS_PHASE' phase in dwc3_ep0_xfernotready(), if so, we should handle it. Signed-off-by: Baolin Wang Signed-off-by: Felipe Balbi (cherry picked from commit 538967983b883a6059292a9f4f096357302ce1e5) Change-Id: I75b28733518ad97f94a2f5564b53b7b6909741d5 Signed-off-by: David Wu --- drivers/usb/dwc3/ep0.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 302e54ba223d..8257ec1a23a2 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -1107,8 +1107,22 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, dwc->ep0state = EP0_STATUS_PHASE; if (dwc->delayed_status) { + struct dwc3_ep *dep = dwc->eps[0]; + WARN_ON_ONCE(event->endpoint_number != 1); dwc3_trace(trace_dwc3_ep0, "Delayed Status"); + /* + * We should handle the delay STATUS phase here if the + * request for handling delay STATUS has been queued + * into the list. + */ + if (!list_empty(&dep->pending_list)) { + dwc->delayed_status = false; + usb_gadget_set_state(&dwc->gadget, + USB_STATE_CONFIGURED); + dwc3_ep0_do_control_status(dwc, event); + } + return; }