diff options
author | Vitaly Kuzmichev <vkuzmichev@mvista.com> | 2011-02-11 18:18:35 +0300 |
---|---|---|
committer | Remy Bohmer <linux@bohmer.net> | 2011-02-19 20:32:38 +0100 |
commit | e4ae66608bbf8b7be9162e5933a98905dcf52d6b (patch) | |
tree | 8f07caef2a6be9ceef8a560aabd4795ec2ef61aa /drivers/usb/gadget/ether.c | |
parent | 7612a43d0803ebd70071894658291300d4acc615 (diff) | |
download | u-boot-imx-e4ae66608bbf8b7be9162e5933a98905dcf52d6b.zip u-boot-imx-e4ae66608bbf8b7be9162e5933a98905dcf52d6b.tar.gz u-boot-imx-e4ae66608bbf8b7be9162e5933a98905dcf52d6b.tar.bz2 |
USB-RNDIS: Send RNDIS state on disconnecting
Add waiting for receiving Ethernet gadget state on the Windows host
side before dropping pullup, but keep it for debug.
Signed-off-by: Vitaly Kuzmichev <vkuzmichev@mvista.com>
Diffstat (limited to 'drivers/usb/gadget/ether.c')
-rw-r--r-- | drivers/usb/gadget/ether.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index f909267..9fb0e80 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1921,10 +1921,22 @@ static void eth_start(struct eth_dev *dev, gfp_t gfp_flags) static int eth_stop(struct eth_dev *dev) { +#ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT + unsigned long ts; + unsigned long timeout = CONFIG_SYS_HZ; /* 1 sec to stop RNDIS */ +#endif + if (rndis_active(dev)) { rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0); rndis_signal_disconnect(dev->rndis_config); +#ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT + /* Wait until host receives OID_GEN_MEDIA_CONNECT_STATUS */ + ts = get_timer(0); + while (get_timer(ts) < timeout) + usb_gadget_handle_interrupts(); +#endif + rndis_uninit(dev->rndis_config); dev->rndis = 0; } @@ -2486,6 +2498,17 @@ void usb_eth_halt(struct eth_device *netdev) if (!dev->gadget) return; + /* + * Some USB controllers may need additional deinitialization here + * before dropping pull-up (also due to hardware issues). + * For example: unhandled interrupt with status stage started may + * bring the controller to fully broken state (until board reset). + * There are some variants to debug and fix such cases: + * 1) In the case of RNDIS connection eth_stop can perform additional + * interrupt handling. See RNDIS_COMPLETE_SIGNAL_DISCONNECT definition. + * 2) 'pullup' callback in your UDC driver can be improved to perform + * this deinitialization. + */ eth_stop(dev); usb_gadget_disconnect(dev->gadget); |