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 | |
parent | 1e1b21591d931ed66450c2c810e1fce89e5c039f (diff) | |
download | rockbox-204668db894f7c26db6c56e94aba33ecd022cdb4.tar.gz rockbox-204668db894f7c26db6c56e94aba33ecd022cdb4.zip |
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')
-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[] = | |||
168 | 168 | ||
169 | static int usb_address = 0; | 169 | static int usb_address = 0; |
170 | static bool initialized = false; | 170 | static bool initialized = false; |
171 | static bool drivers_connected = false; | ||
171 | static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; | 172 | static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; |
172 | 173 | ||
173 | #ifdef HAVE_USB_CHARGING_ENABLE | 174 | #ifdef HAVE_USB_CHARGING_ENABLE |
@@ -413,12 +414,16 @@ void usb_core_init(void) | |||
413 | void usb_core_exit(void) | 414 | void usb_core_exit(void) |
414 | { | 415 | { |
415 | int i; | 416 | int i; |
416 | for(i = 0; i < USB_NUM_DRIVERS; i++) | 417 | if(drivers_connected) |
417 | if(drivers[i].enabled && drivers[i].disconnect != NULL) | 418 | { |
418 | { | 419 | for(i = 0; i < USB_NUM_DRIVERS; i++) |
419 | drivers[i].disconnect(); | 420 | if(drivers[i].enabled && drivers[i].disconnect != NULL) |
420 | drivers[i].enabled = false; | 421 | { |
421 | } | 422 | drivers[i].disconnect(); |
423 | drivers[i].enabled = false; | ||
424 | } | ||
425 | drivers_connected = false; | ||
426 | } | ||
422 | 427 | ||
423 | if(initialized) { | 428 | if(initialized) { |
424 | usb_drv_exit(); | 429 | usb_drv_exit(); |
@@ -676,12 +681,19 @@ static void usb_core_do_set_addr(uint8_t address) | |||
676 | 681 | ||
677 | static void usb_core_do_set_config(uint8_t config) | 682 | static void usb_core_do_set_config(uint8_t config) |
678 | { | 683 | { |
679 | logf("usb_core: SET_CONFIG"); | 684 | logf("usb_core: SET_CONFIG %d",config); |
680 | if(config) { | 685 | if(config) { |
681 | usb_state = CONFIGURED; | 686 | usb_state = CONFIGURED; |
687 | |||
688 | if(drivers_connected) | ||
689 | for(int i = 0; i < USB_NUM_DRIVERS; i++) | ||
690 | if(drivers[i].enabled && drivers[i].disconnect != NULL) | ||
691 | drivers[i].disconnect(); | ||
692 | |||
682 | for(int i = 0; i < USB_NUM_DRIVERS; i++) | 693 | for(int i = 0; i < USB_NUM_DRIVERS; i++) |
683 | if(drivers[i].enabled && drivers[i].init_connection) | 694 | if(drivers[i].enabled && drivers[i].init_connection) |
684 | drivers[i].init_connection(); | 695 | drivers[i].init_connection(); |
696 | drivers_connected = true; | ||
685 | } | 697 | } |
686 | else | 698 | else |
687 | usb_state = ADDRESS; | 699 | usb_state = ADDRESS; |
@@ -718,7 +730,6 @@ static void request_handler_device(struct usb_ctrlrequest* req) | |||
718 | } | 730 | } |
719 | case USB_REQ_SET_ADDRESS: { | 731 | case USB_REQ_SET_ADDRESS: { |
720 | unsigned char address = req->wValue; | 732 | unsigned char address = req->wValue; |
721 | logf("usb_core: SET_ADR %d", address); | ||
722 | usb_drv_send(EP_CONTROL, NULL, 0); | 733 | usb_drv_send(EP_CONTROL, NULL, 0); |
723 | usb_drv_cancel_all_transfers(); | 734 | usb_drv_cancel_all_transfers(); |
724 | usb_drv_set_address(address); | 735 | usb_drv_set_address(address); |
@@ -906,6 +917,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) | |||
906 | /* called by usb_drv_int() */ | 917 | /* called by usb_drv_int() */ |
907 | void usb_core_bus_reset(void) | 918 | void usb_core_bus_reset(void) |
908 | { | 919 | { |
920 | logf("usb_core: bus reset"); | ||
909 | usb_address = 0; | 921 | usb_address = 0; |
910 | usb_state = DEFAULT; | 922 | usb_state = DEFAULT; |
911 | #ifdef HAVE_USB_CHARGING_ENABLE | 923 | #ifdef HAVE_USB_CHARGING_ENABLE |