Hi, On 6/29/2017 12:54 AM, Jack Pham wrote: > A recent optimization was made so that a request put on the > pending_list wouldn't get mapped for DMA until just before > preparing a TRB for it. However, this poses a problem in case > the request is dequeued or the endpoint is disabled before the > mapping is done as that would lead to dwc3_gadget_giveback() > unconditionally calling usb_gadget_unmap_request_for_dev() with > an invalid request->dma handle. Depending on the platform's DMA > implementation the unmap operation could result in a panic. > > Since we know a successful mapping is a prerequisite for getting > a TRB, the unmap can be conditionally called only when req->trb > is non-NULL. > > Fixes: cdb55b39fab8 ("usb: dwc3: gadget: lazily map requests for DMA") > Signed-off-by: Jack Pham <jackp@xxxxxxxxxxxxxx> > --- > drivers/usb/dwc3/gadget.c | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index 9e41605a..6b299c7 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -191,14 +191,16 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, > > req->started = false; > list_del(&req->list); > - req->trb = NULL; > req->remaining = 0; > > if (req->request.status == -EINPROGRESS) > req->request.status = status; > > - usb_gadget_unmap_request_by_dev(dwc->sysdev, > - &req->request, req->direction); > + if (req->trb) This check does not account for control data transfer. TRBs for ep0 are not set to its req->trb. ep0out request needs to be unmapped, otherwise device will receive bogus data. Our internal test showed that the device failed to interpret control data from host. I bisected to this patch. > + usb_gadget_unmap_request_by_dev(dwc->sysdev, > + &req->request, req->direction); > + > + req->trb = NULL; > > trace_dwc3_gadget_giveback(req); > > BR, Thinh -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html