Message ID | VI1PR04MB5327779C65037389EB8400148BA10@VI1PR04MB5327.eurprd04.prod.outlook.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | NULL pointer issue due to .pullup timeout at dwc3 | expand |
Hi, Peter Chen <peter.chen@nxp.com> writes: > Hi Balbi, > > When do configfs function add and remove stress test, I find dwc3 > gadget .pullup will timeout if there is a request on the way. Even I what do you mean by "a request on the way"? > enlarge the delay, there is still timeout for .pullup. > > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index f13bef950951..e95955b6a225 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -1827,6 +1827,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) > do { > reg = dwc3_readl(dwc->regs, DWC3_DSTS); > reg &= DWC3_DSTS_DEVCTRLHLT; > + udelay(1); > } while (--timeout && !(!is_on ^ !reg)); > > if (!timeout) > @@ -1861,6 +1862,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) > spin_lock_irqsave(&dwc->lock, flags); > ret = dwc3_gadget_run_stop(dwc, is_on, false); > spin_unlock_irqrestore(&dwc->lock, flags); > + if (ret) > + dev_err(dwc->dev, "%s:ret = %d\n", __func__, ret); > > return ret; > } > > This timeout causes the NULL pointer issue for ethernet gadget, eg. NCM, the reason > is ncm->notify_req is NULL, but the ncm_notify_complete is not called before .unbind is > called. See below oops: sounds like a bug in ncm. If we haven't connected to host side yet, we can't really complete the request. > It is very easy to reproduce it, just create ncm function, > and sleep 1 second, then, remove it. > > I am not sure if it is the common issue for dwc3, there is no such > requirement for chipidea and cadence3. Would you please have a check? could you capture tracepoints of what's happening here?
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f13bef950951..e95955b6a225 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1827,6 +1827,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) do { reg = dwc3_readl(dwc->regs, DWC3_DSTS); reg &= DWC3_DSTS_DEVCTRLHLT; + udelay(1); } while (--timeout && !(!is_on ^ !reg)); if (!timeout) @@ -1861,6 +1862,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) spin_lock_irqsave(&dwc->lock, flags); ret = dwc3_gadget_run_stop(dwc, is_on, false); spin_unlock_irqrestore(&dwc->lock, flags); + if (ret) + dev_err(dwc->dev, "%s:ret = %d\n", __func__, ret); return ret; }