[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