Skip to content

Commit 75a41ce

Browse files
pelwellgregkh
authored andcommitted
usb: dwc2: Fix gadget DMA unmap direction
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: fe0b94a ("usb: dwc2: gadget: manage ep0 state in software") Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Phil Elwell <phil@raspberrypi.com> Link: https://lore.kernel.org/r/20210506112200.2893922-1-phil@raspberrypi.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6f26ebb commit 75a41ce

2 files changed

Lines changed: 4 additions & 1 deletion

File tree

drivers/usb/dwc2/core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct dwc2_hsotg_req;
113113
* @debugfs: File entry for debugfs file for this endpoint.
114114
* @dir_in: Set to true if this endpoint is of the IN direction, which
115115
* means that it is sending data to the Host.
116+
* @map_dir: Set to the value of dir_in when the DMA buffer is mapped.
116117
* @index: The index for the endpoint registers.
117118
* @mc: Multi Count - number of transactions per microframe
118119
* @interval: Interval for periodic endpoints, in frames or microframes.
@@ -162,6 +163,7 @@ struct dwc2_hsotg_ep {
162163
unsigned short fifo_index;
163164

164165
unsigned char dir_in;
166+
unsigned char map_dir;
165167
unsigned char index;
166168
unsigned char mc;
167169
u16 interval;

drivers/usb/dwc2/gadget.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
422422
{
423423
struct usb_request *req = &hs_req->req;
424424

425-
usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in);
425+
usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->map_dir);
426426
}
427427

428428
/*
@@ -1242,6 +1242,7 @@ static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg,
12421242
{
12431243
int ret;
12441244

1245+
hs_ep->map_dir = hs_ep->dir_in;
12451246
ret = usb_gadget_map_request(&hsotg->gadget, req, hs_ep->dir_in);
12461247
if (ret)
12471248
goto dma_error;

0 commit comments

Comments
 (0)