diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-10-11 09:05:51 +0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-10-13 21:41:46 +0400 |
commit | 6ff5d09bd2fd5943f5b16cb1e3453446a1f575e2 (patch) | |
tree | 8adfa67adf3e32329be391720da2184272b64e3a /drivers/usb/renesas_usbhs/fifo.c | |
parent | 6e6db82ba9bf2d5912897f77ccf6902cb8543372 (diff) | |
download | linux-6ff5d09bd2fd5943f5b16cb1e3453446a1f575e2.tar.xz |
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 <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/renesas_usbhs/fifo.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 87f56b604809..1a345c20105f 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -476,6 +476,20 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) 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 * * see @@ -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); |