Patchwork [U-Boot,1/5] USB-CDC: handle interrupt after dropped pullup

login
register
mail settings
Submitter Vitaly Kuzmichev
Date Feb. 11, 2011, 3:18 p.m.
Message ID <1297437515-4069-2-git-send-email-vkuzmichev@mvista.com>
Download mbox | patch
Permalink /patch/82769/
State Accepted
Commit b3649f3bbfdb2686eceb40a629cef8d4d257f5fa
Delegated to: Remy Bohmer
Headers show

Comments

Vitaly Kuzmichev - Feb. 11, 2011, 3:18 p.m.
Disconnecting USB gadget with pending interrupt may cause its wrong
handling in the next time when interface will be started again
(especially actual for RNDIS). This interrupt may force the gadget
to queue unexpected response before setup stage.
Despite the fact that such interrupt handled after dropped pullup
also may add pending response, this will not bring to any issues due to
usb_ep_disable (which clears the queue) called on gadget unregistering.

Signed-off-by: Vitaly Kuzmichev <vkuzmichev@mvista.com>
---
 drivers/usb/gadget/ether.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
Remy Bohmer - Feb. 17, 2011, 6:55 p.m.
Hi,

2011/2/11 Vitaly Kuzmichev <vkuzmichev@mvista.com>:
> Disconnecting USB gadget with pending interrupt may cause its wrong
> handling in the next time when interface will be started again
> (especially actual for RNDIS). This interrupt may force the gadget
> to queue unexpected response before setup stage.
> Despite the fact that such interrupt handled after dropped pullup
> also may add pending response, this will not bring to any issues due to
> usb_ep_disable (which clears the queue) called on gadget unregistering.
>
> Signed-off-by: Vitaly Kuzmichev <vkuzmichev@mvista.com>
> ---
>  drivers/usb/gadget/ether.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)

Applied to u-boot-usb. Thanks!

Kind regards,

Remy

Patch

diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 01deeb1..079acea 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -1926,6 +1926,13 @@  void usb_eth_halt(struct eth_device *netdev)
 		return;
 
 	usb_gadget_disconnect(dev->gadget);
+
+	/* Clear pending interrupt */
+	if (dev->network_started) {
+		usb_gadget_handle_interrupts();
+		dev->network_started = 0;
+	}
+
 	usb_gadget_unregister_driver(&eth_driver);
 }