[PATCH] usb: dwc2: Fix gadget DMA unmap direction

Minas Harutyunyan Minas.Harutyunyan at synopsys.com
Sat May 8 07:10:21 BST 2021


On 5/6/2021 3:22 PM, Phil Elwell wrote:
> The dwc2 gadget support maps and unmaps DMA buffers as necessary. When
> mapping and unmapping it uses the direction of the endpoint to select
> the direction of the DMA transfer, but this fails for Control OUT
> transfers because the unmap occurs after the endpoint direction has
> been reversed for the status phase.
> 
> A possible solution would be to unmap the buffer before the direction
> is changed, but a safer, less invasive fix is to remember the buffer
> direction independently of the endpoint direction.
> 
> Fixes: fe0b94abcdf6 ("usb: dwc2: gadget: manage ep0 state in software")
> Signed-off-by: Phil Elwell <phil at raspberrypi.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan at synopsys.com>

> ---
>   drivers/usb/dwc2/core.h   | 2 ++
>   drivers/usb/dwc2/gadget.c | 3 ++-
>   2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index da5ac4a4595b..ab6b815e0089 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -113,6 +113,7 @@ struct dwc2_hsotg_req;
>    * @debugfs: File entry for debugfs file for this endpoint.
>    * @dir_in: Set to true if this endpoint is of the IN direction, which
>    *          means that it is sending data to the Host.
> + * @map_dir: Set to the value of dir_in when the DMA buffer is mapped.
>    * @index: The index for the endpoint registers.
>    * @mc: Multi Count - number of transactions per microframe
>    * @interval: Interval for periodic endpoints, in frames or microframes.
> @@ -162,6 +163,7 @@ struct dwc2_hsotg_ep {
>   	unsigned short		fifo_index;
>   
>   	unsigned char           dir_in;
> +	unsigned char           map_dir;
>   	unsigned char           index;
>   	unsigned char           mc;
>   	u16                     interval;
> diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
> index e6bb1bdb2760..184964174dc0 100644
> --- a/drivers/usb/dwc2/gadget.c
> +++ b/drivers/usb/dwc2/gadget.c
> @@ -422,7 +422,7 @@ static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
>   {
>   	struct usb_request *req = &hs_req->req;
>   
> -	usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in);
> +	usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->map_dir);
>   }
>   
>   /*
> @@ -1242,6 +1242,7 @@ static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg,
>   {
>   	int ret;
>   
> +	hs_ep->map_dir = hs_ep->dir_in;
>   	ret = usb_gadget_map_request(&hsotg->gadget, req, hs_ep->dir_in);
>   	if (ret)
>   		goto dma_error;
> 



More information about the linux-rpi-kernel mailing list