| From 8c1efbc74942c8584c0e9343993f401869c45538 Mon Sep 17 00:00:00 2001 |
| From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| Date: Fri, 22 Aug 2014 20:14:10 +0900 |
| Subject: usb: renesas_usbhs: fix the condition of is_done in |
| usbhsf_dma_push_done |
| |
| This patch fixes the condition of is_done in usbhsf_dma_push_done(). |
| This function will be called after a transmission finished by DMAC. |
| So, the function should check if the transmission packet is short packet |
| or not. Also the function should call try_run to send the zero packet |
| by the pio handler if the "*is_done" is not set. Otherwize, the |
| transaction will not finish if a gadget driver sets the "zero" flag |
| in a transmission. |
| |
| Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| Signed-off-by: Felipe Balbi <balbi@ti.com> |
| (cherry picked from commit c0ed8b23b257a84d103764cdbd490ee5e2749da3) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/renesas_usbhs/fifo.c | 17 +++++++++++++++-- |
| 1 file changed, 15 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c |
| index 3efece3c72a3..1564829951c0 100644 |
| --- a/drivers/usb/renesas_usbhs/fifo.c |
| +++ b/drivers/usb/renesas_usbhs/fifo.c |
| @@ -889,16 +889,29 @@ usbhsf_pio_prepare_push: |
| static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done) |
| { |
| struct usbhs_pipe *pipe = pkt->pipe; |
| + int is_short = pkt->trans % usbhs_pipe_get_maxpacket(pipe); |
| |
| - pkt->actual = pkt->trans; |
| + pkt->actual += pkt->trans; |
| + |
| + if (pkt->actual < pkt->length) |
| + *is_done = 0; /* there are remainder data */ |
| + else if (is_short) |
| + *is_done = 1; /* short packet */ |
| + else |
| + *is_done = !pkt->zero; /* send zero packet? */ |
| |
| - *is_done = !pkt->zero; /* send zero packet ? */ |
| usbhs_pipe_running(pipe, !*is_done); |
| |
| usbhsf_dma_stop(pipe, pipe->fifo); |
| usbhsf_dma_unmap(pkt); |
| usbhsf_fifo_unselect(pipe, pipe->fifo); |
| |
| + if (!*is_done) { |
| + /* change handler to PIO */ |
| + pkt->handler = &usbhs_fifo_pio_push_handler; |
| + return pkt->handler->try_run(pkt, is_done); |
| + } |
| + |
| return 0; |
| } |
| |
| -- |
| 2.1.2 |
| |