summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorVitaly Kuzmichev <vkuzmichev@mvista.com>2010-09-22 13:13:56 +0400
committerRemy Bohmer <linux@bohmer.net>2010-10-13 12:07:58 +0200
commit98fae9707fd83a61ec29d9c42c15267a735f9b71 (patch)
treec2989d7199f826676f6a711d0e150502ea2bfcd2 /drivers/usb
parentac5d32d15c3f950d983740aed5403f570ac15c62 (diff)
downloadu-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')
-rw-r--r--drivers/usb/gadget/ether.c1
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: