commit 7c3addd6690b9b0e0c0abd7f6e8645840ae76e99
Author: sideral <asieoniezi@gmx.net>
Date: Mon Jan 24 14:05:34 2011 +0100
Do not reset driver on USB bus reset. Rather, simply cancel ongoing
transfers.
I suspect the USB reset leads to some kind of IRQ race (a new IRQ
arriving and reentering INT_USB while the driver is reset), leaving
the controller in a weird state. cancel_all_transfers is my attempt
at fixing the root of the problem that led to the driver-reset
workaround being introduced in the first place.
diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.c b/firmware/target/arm/as3525/usb-drv-as3525v2.c
index eb6d1bb..060c90a 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525v2.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525v2.c
@@ -90,7 +90,7 @@ static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS][2];
static struct usb_ctrlrequest _ep0_setup_pkt __attribute__((aligned(32)));
static struct usb_ctrlrequest *ep0_setup_pkt = AS3525_UNCACHED_ADDR(&_ep0_setup_pkt);
-static int g_usbreset_count = 0;
+// static int g_usbreset_count = 0;
/* state of EP0 */
static enum ep0state ep0_state;
@@ -452,7 +452,7 @@ void usb_drv_init(void)
/* Enable global interrupts */
enable_global_interrupts();
- g_usbreset_count = 0;
+// g_usbreset_count = 0;
}
void usb_drv_exit(void)
@@ -591,6 +591,8 @@ void INT_USB(void)
{
logf("usb-drv: bus reset");
+ cancel_all_transfers(true); /* XXX */
+#if 0 /* XXX */
g_usbreset_count++;
if(g_usbreset_count == 2)
@@ -603,7 +605,7 @@ void INT_USB(void)
usb_drv_exit();
usb_drv_init(); /* reset g_usbreset_count here */
}
-
+#endif
/* Clear the Remote Wakeup Signalling */
DCTL &= ~DCTL_rmtwkupsig;