diff options
author | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 2018-02-05 17:12:35 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-02-28 10:17:23 +0100 |
commit | 8565e4005e2dce71b49bb0ddb18c10e2b2416071 (patch) | |
tree | 0eb2a6d1b675575d1a6602878c6c1f6ecf29c2f3 | |
parent | 7a67ec752f2bc707563b66f7b5b5cef8e2fe67de (diff) |
usb: renesas_usbhs: missed the "running" flag in usb_dmac with rx path
commit 17aa31f13cad25daa19d3f923323f552e87bc874 upstream.
This fixes an issue that a gadget driver (usb_f_fs) is possible to
stop rx transactions after the usb-dmac is used because the following
functions missed to set/check the "running" flag.
- usbhsf_dma_prepare_pop_with_usb_dmac()
- usbhsf_dma_pop_done_with_usb_dmac()
So, if next transaction uses pio, the usbhsf_prepare_pop() can not
start the transaction because the "running" flag is 0.
Fixes: 8355b2b3082d ("usb: renesas_usbhs: fix the behavior of some usbhs_pkt_handle")
Cc: <stable@vger.kernel.org> # v3.19+
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 8bb9367ada45..6f37966ea54b 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -999,6 +999,10 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt, if ((uintptr_t)pkt->buf & (USBHS_USB_DMAC_XFER_SIZE - 1)) goto usbhsf_pio_prepare_pop; + /* return at this time if the pipe is running */ + if (usbhs_pipe_is_running(pipe)) + return 0; + usbhs_pipe_config_change_bfre(pipe, 1); ret = usbhsf_fifo_select(pipe, fifo, 0); @@ -1189,6 +1193,7 @@ static int usbhsf_dma_pop_done_with_usb_dmac(struct usbhs_pkt *pkt, usbhsf_fifo_clear(pipe, fifo); pkt->actual = usbhs_dma_calc_received_size(pkt, chan, rcv_len); + usbhs_pipe_running(pipe, 0); usbhsf_dma_stop(pipe, fifo); usbhsf_dma_unmap(pkt); usbhsf_fifo_unselect(pipe, pipe->fifo); |