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 <[email protected]>
> ---
> 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html