[PATCH v2 1/2] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

From: Baolin Wang
Date: Fri Sep 09 2016 - 03:17:56 EST


When system has stpped the gadget, we should avoid queuing any requests
which will cause tranfer failed. Thus adding some disconnect checking to
avoid this situation.

Signed-off-by: Baolin Wang <baolin.wang@xxxxxxxxxx>
---
Changes since v1:
- Split into 2 separate ptaches.
- Choose complete mechanism instead of polling.
---
drivers/usb/dwc3/ep0.c | 8 ++++++++
drivers/usb/dwc3/gadget.c | 12 +++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d77..632e5a4 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -228,6 +228,14 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
int ret;

spin_lock_irqsave(&dwc->lock, flags);
+ if (!dwc->pullups_connected) {
+ dwc3_trace(trace_dwc3_ep0,
+ "queuing request %p to %s when gadget is disconnected",
+ request, dep->name);
+ ret = -ESHUTDOWN;
+ goto out;
+ }
+
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_ep0,
"trying to queue request %p to disabled %s",
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1783406..1a33308 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1040,6 +1040,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
struct dwc3 *dwc = dep->dwc;
int ret;

+ if (!dwc->pullups_connected) {
+ dwc3_trace(trace_dwc3_gadget,
+ "queuing request %p to %s when gadget is disconnected",
+ &req->request, dep->endpoint.name);
+ return -ESHUTDOWN;
+ }
+
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_gadget,
"trying to queue request %p to disabled %s",
@@ -1984,13 +1991,12 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
if (ret)
break;
}
-
/*
* Our endpoint might get disabled by another thread during
* dwc3_gadget_giveback(). If that happens, we're just gonna return 1
* early on so DWC3_EP_BUSY flag gets cleared
*/
- if (!dep->endpoint.desc)
+ if (!dep->endpoint.desc || !dwc->pullups_connected)
return 1;

if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
@@ -2064,7 +2070,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
* dwc3_gadget_giveback(). If that happens, we're just gonna return 1
* early on so DWC3_EP_BUSY flag gets cleared
*/
- if (!dep->endpoint.desc)
+ if (!dep->endpoint.desc || !dwc->pullups_connected)
return;

if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
--
1.7.9.5