From 6ff5d09bd2fd5943f5b16cb1e3453446a1f575e2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 10 Oct 2011 22:05:51 -0700 Subject: [PATCH] usb: gadget: renesas_usbhs: disable pipe on top of interrupt When data read interrupt happened, the pipe is BUF which means "enable". then, next un-necessary interrupt/token might be issued again when all data were popped from fifo. It will cause un-understandable bug. This patch decides pipe disable on top of read interrupt. Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 87f56b60480..1a345c20105 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -475,6 +475,20 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) len = min(len, rcv_len); total_len = len; + /* + * update actual length first here to decide disable pipe. + * if this pipe keeps BUF status and all data were popped, + * then, next interrupt/token will be issued again + */ + pkt->actual += total_len; + + if ((pkt->actual == pkt->length) || /* receive all data */ + (total_len < maxp)) { /* short packet */ + *is_done = 1; + usbhsf_rx_irq_ctrl(pipe, 0); + usbhs_pipe_disable(pipe); /* disable pipe first */ + } + /* * Buffer clear if Zero-Length packet * @@ -505,16 +519,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; } - pkt->actual += total_len; - usbhs_fifo_read_end: - if ((pkt->actual == pkt->length) || /* receive all data */ - (total_len < maxp)) { /* short packet */ - *is_done = 1; - usbhsf_rx_irq_ctrl(pipe, 0); - usbhs_pipe_disable(pipe); - } - dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n", usbhs_pipe_number(pipe), pkt->length, pkt->actual, *is_done, pkt->zero); -- 2.41.0