diff options
| author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-10-10 22:05:51 -0700 | 
|---|---|---|
| committer | Felipe Balbi <balbi@ti.com> | 2011-10-13 20:41:46 +0300 | 
| commit | 6ff5d09bd2fd5943f5b16cb1e3453446a1f575e2 (patch) | |
| tree | 8adfa67adf3e32329be391720da2184272b64e3a | |
| parent | 6e6db82ba9bf2d5912897f77ccf6902cb8543372 (diff) | |
| download | olio-linux-3.10-6ff5d09bd2fd5943f5b16cb1e3453446a1f575e2.tar.xz olio-linux-3.10-6ff5d09bd2fd5943f5b16cb1e3453446a1f575e2.zip  | |
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>
| -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 87f56b60480..1a345c20105 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);  |