diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2014-01-05 22:54:10 +0100 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2014-01-05 22:57:04 +0100 |
commit | 204668db894f7c26db6c56e94aba33ecd022cdb4 (patch) | |
tree | cd20c62a8287b99b28b140f60e8a8ba2a5b7b6ef /firmware/usbstack | |
parent | 1e1b21591d931ed66450c2c810e1fce89e5c039f (diff) |
Make sure usb class driver disconnect() functions are called properly.
disconnect() needs to be called exactly once per call to init_connection().
In case of bus resets, disconnect() was not called, which led to leaking
alloc_maximum() allocated buflib handles, which led to buflib running out
of memory to allocate.
Change-Id: I03025da578dc54e48b6de6bd3e3f40feae7220a6
Diffstat (limited to 'firmware/usbstack')
-rw-r--r-- | firmware/usbstack/usb_core.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 130111cdfe..e4ecc90e63 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -168,6 +168,7 @@ static const struct usb_string_descriptor* const usb_strings[] = static int usb_address = 0; static bool initialized = false; +static bool drivers_connected = false; static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; #ifdef HAVE_USB_CHARGING_ENABLE @@ -413,12 +414,16 @@ void usb_core_init(void) void usb_core_exit(void) { int i; - for(i = 0; i < USB_NUM_DRIVERS; i++) - if(drivers[i].enabled && drivers[i].disconnect != NULL) - { - drivers[i].disconnect(); - drivers[i].enabled = false; - } + if(drivers_connected) + { + for(i = 0; i < USB_NUM_DRIVERS; i++) + if(drivers[i].enabled && drivers[i].disconnect != NULL) + { + drivers[i].disconnect(); + drivers[i].enabled = false; + } + drivers_connected = false; + } if(initialized) { usb_drv_exit(); @@ -676,12 +681,19 @@ static void usb_core_do_set_addr(uint8_t address) static void usb_core_do_set_config(uint8_t config) { - logf("usb_core: SET_CONFIG"); + logf("usb_core: SET_CONFIG %d",config); if(config) { usb_state = CONFIGURED; + + if(drivers_connected) + for(int i = 0; i < USB_NUM_DRIVERS; i++) + if(drivers[i].enabled && drivers[i].disconnect != NULL) + drivers[i].disconnect(); + for(int i = 0; i < USB_NUM_DRIVERS; i++) if(drivers[i].enabled && drivers[i].init_connection) drivers[i].init_connection(); + drivers_connected = true; } else usb_state = ADDRESS; @@ -718,7 +730,6 @@ static void request_handler_device(struct usb_ctrlrequest* req) } case USB_REQ_SET_ADDRESS: { unsigned char address = req->wValue; - logf("usb_core: SET_ADR %d", address); usb_drv_send(EP_CONTROL, NULL, 0); usb_drv_cancel_all_transfers(); usb_drv_set_address(address); @@ -906,6 +917,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) /* called by usb_drv_int() */ void usb_core_bus_reset(void) { + logf("usb_core: bus reset"); usb_address = 0; usb_state = DEFAULT; #ifdef HAVE_USB_CHARGING_ENABLE |