diff options
author | Vitaly Kuzmichev <vkuzmichev@mvista.com> | 2010-09-22 13:13:56 +0400 |
---|---|---|
committer | Remy Bohmer <linux@bohmer.net> | 2010-10-13 12:07:58 +0200 |
commit | 98fae9707fd83a61ec29d9c42c15267a735f9b71 (patch) | |
tree | c2989d7199f826676f6a711d0e150502ea2bfcd2 /drivers/usb/gadget/ether.c | |
parent | ac5d32d15c3f950d983740aed5403f570ac15c62 (diff) | |
download | u-boot-imx-98fae9707fd83a61ec29d9c42c15267a735f9b71.zip u-boot-imx-98fae9707fd83a61ec29d9c42c15267a735f9b71.tar.gz u-boot-imx-98fae9707fd83a61ec29d9c42c15267a735f9b71.tar.bz2 |
USB-CDC: Prevent rx_req being enqueued twice
After gadget reinitializaton (after tftp has been done once)
packet_received may become equal to 1 due to nuking OUT_EP
while disabling it in eth_reset_config.
rx_submit called from usb_eth_init queues rx_req first time.
But the first call of usb_eth_recv from NetLoop queues rx_req
again due to packet_received = 1.
The following flow shows the path of functions calls when
this happens:
net/net.c:NetLoop
|
+-net/eth.c:eth_init
| ether.c:usb_eth_init
| |
| +-udc_driver:usb_gadget_handle_interrupts
| | udc_driver:...
| | ether.c:eth_setup
| | ether.c:eth_set_config
| | ether.c:eth_reset_config
| | udc_driver:usb_ep_disable
| | udc_driver:nuke
| | ether.c:rx_complete
| | ether.c: packet_received = 1;
| |
| +-ether.c:rx_submit
| udc_driver:usb_ep_queue --- The first time when rx_req is queued
|
+-net/eth.c:eth_rx
ether.c:usb_eth_recv
|
+-udc_driver:usb_gadget_handle_interrupts
| udc_driver:... --- no interrupts, returning
+-ether.c: if (packet_received) { ...
ether.c:rx_submit
udc_driver:usb_ep_queue --- The second time!
Signed-off-by: Vitaly Kuzmichev <vkuzmichev@mvista.com>
Diffstat (limited to 'drivers/usb/gadget/ether.c')
-rw-r--r-- | drivers/usb/gadget/ether.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 8f5eec1..b22ca90 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1810,6 +1810,7 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd) usb_gadget_handle_interrupts(); } + packet_received = 0; rx_submit(dev, dev->rx_req, 0); return 0; fail: |