commit 7c3addd6690b9b0e0c0abd7f6e8645840ae76e99 Author: sideral 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;