Index: firmware/target/arm/usb-drv-arc.c =================================================================== --- firmware/target/arm/usb-drv-arc.c (Revision 30624) +++ firmware/target/arm/usb-drv-arc.c (Arbeitskopie) @@ -428,31 +428,9 @@ } } -#ifdef LOGF_ENABLE -#define XFER_DIR_STR(dir) ((dir) ? "IN" : "OUT") -#define XFER_TYPE_STR(type) \ - ((type) == USB_ENDPOINT_XFER_CONTROL ? "CTRL" : \ - ((type) == USB_ENDPOINT_XFER_ISOC ? "ISOC" : \ - ((type) == USB_ENDPOINT_XFER_BULK ? "BULK" : \ - ((type) == USB_ENDPOINT_XFER_INT ? "INTR" : "INVL")))) - -static void log_ep(int ep_num, int ep_dir, char* prefix) -{ - usb_endpoint_t* endpoint = &endpoints[ep_num]; - - logf("%s: ep%d %s %s %d", prefix, ep_num, XFER_DIR_STR(ep_dir), - XFER_TYPE_STR(endpoint->type[ep_dir]), - endpoint->max_pkt_size[ep_dir]); -} -#else -#undef log_ep -#define log_ep(...) -#endif - /* manual: 32.14.1 Device Controller Initialization */ -void usb_drv_init(void) +static void _usb_drv_init(bool attach) { - /* USB core decides */ usb_drv_reset(); REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; @@ -469,12 +447,19 @@ REG_ENDPOINTLISTADDR = (unsigned int)qh_array; REG_DEVICEADDR = 0; - /* enable USB interrupts */ - REG_USBINTR = - USBINTR_INT_EN | - USBINTR_ERR_INT_EN | - USBINTR_PTC_DETECT_EN | - USBINTR_RESET_EN; + if (!attach) { + /* enable RESET interrupt */ + REG_USBINTR = USBINTR_RESET_EN; + } + else + { + /* enable USB interrupts */ + REG_USBINTR = + USBINTR_INT_EN | + USBINTR_ERR_INT_EN | + USBINTR_PTC_DETECT_EN | + USBINTR_RESET_EN; + } usb_drv_int_enable(true); @@ -487,12 +472,49 @@ logf("usb dccparams %x", REG_DCCPARAMS); /* now a bus reset will occur. see bus_reset() */ + (void)attach; } +#ifdef LOGF_ENABLE +#define XFER_DIR_STR(dir) ((dir) ? "IN" : "OUT") +#define XFER_TYPE_STR(type) \ + ((type) == USB_ENDPOINT_XFER_CONTROL ? "CTRL" : \ + ((type) == USB_ENDPOINT_XFER_ISOC ? "ISOC" : \ + ((type) == USB_ENDPOINT_XFER_BULK ? "BULK" : \ + ((type) == USB_ENDPOINT_XFER_INT ? "INTR" : "INVL")))) + +static void log_ep(int ep_num, int ep_dir, char* prefix) +{ + usb_endpoint_t* endpoint = &endpoints[ep_num]; + + logf("%s: ep%d %s %s %d", prefix, ep_num, XFER_DIR_STR(ep_dir), + XFER_TYPE_STR(endpoint->type[ep_dir]), + endpoint->max_pkt_size[ep_dir]); +} +#else +#undef log_ep +#define log_ep(...) +#endif + +void usb_drv_init(void) +{ +#if 0//def USB_DETECT_BY_CORE + /* USB core decides */ + _usb_drv_init(true); +#else + /* Use bus reset condition */ + _usb_drv_init(false); +#endif +} + /* fully enable driver */ void usb_drv_attach(void) { logf("usb_drv_attach"); +#if 1//ndef USB_DETECT_BY_CORE + sleep(HZ/10); + _usb_drv_init(true); +#endif } void usb_drv_exit(void) @@ -541,8 +563,17 @@ /* reset interrupt */ if (status & USBSTS_RESET) { REG_USBSTS = USBSTS_RESET; - bus_reset(); - usb_core_bus_reset(); /* tell mom */ + + if (UNLIKELY(usbintr == USBINTR_RESET_EN)) { + /* USB detected - detach and inform */ + usb_drv_stop(); + usb_drv_usb_detect_event(); + } + else + { + bus_reset(); + usb_core_bus_reset(); /* tell mom */ + } } /* port change */