forked from len0rd/rockbox
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
This commit is contained in:
parent
1e1b21591d
commit
204668db89
1 changed files with 20 additions and 8 deletions
|
@ -168,6 +168,7 @@ static const struct usb_string_descriptor* const usb_strings[] =
|
||||||
|
|
||||||
static int usb_address = 0;
|
static int usb_address = 0;
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
|
static bool drivers_connected = false;
|
||||||
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
||||||
|
|
||||||
#ifdef HAVE_USB_CHARGING_ENABLE
|
#ifdef HAVE_USB_CHARGING_ENABLE
|
||||||
|
@ -413,12 +414,16 @@ void usb_core_init(void)
|
||||||
void usb_core_exit(void)
|
void usb_core_exit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < USB_NUM_DRIVERS; i++)
|
if(drivers_connected)
|
||||||
if(drivers[i].enabled && drivers[i].disconnect != NULL)
|
{
|
||||||
{
|
for(i = 0; i < USB_NUM_DRIVERS; i++)
|
||||||
drivers[i].disconnect();
|
if(drivers[i].enabled && drivers[i].disconnect != NULL)
|
||||||
drivers[i].enabled = false;
|
{
|
||||||
}
|
drivers[i].disconnect();
|
||||||
|
drivers[i].enabled = false;
|
||||||
|
}
|
||||||
|
drivers_connected = false;
|
||||||
|
}
|
||||||
|
|
||||||
if(initialized) {
|
if(initialized) {
|
||||||
usb_drv_exit();
|
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)
|
static void usb_core_do_set_config(uint8_t config)
|
||||||
{
|
{
|
||||||
logf("usb_core: SET_CONFIG");
|
logf("usb_core: SET_CONFIG %d",config);
|
||||||
if(config) {
|
if(config) {
|
||||||
usb_state = CONFIGURED;
|
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++)
|
for(int i = 0; i < USB_NUM_DRIVERS; i++)
|
||||||
if(drivers[i].enabled && drivers[i].init_connection)
|
if(drivers[i].enabled && drivers[i].init_connection)
|
||||||
drivers[i].init_connection();
|
drivers[i].init_connection();
|
||||||
|
drivers_connected = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
usb_state = ADDRESS;
|
usb_state = ADDRESS;
|
||||||
|
@ -718,7 +730,6 @@ static void request_handler_device(struct usb_ctrlrequest* req)
|
||||||
}
|
}
|
||||||
case USB_REQ_SET_ADDRESS: {
|
case USB_REQ_SET_ADDRESS: {
|
||||||
unsigned char address = req->wValue;
|
unsigned char address = req->wValue;
|
||||||
logf("usb_core: SET_ADR %d", address);
|
|
||||||
usb_drv_send(EP_CONTROL, NULL, 0);
|
usb_drv_send(EP_CONTROL, NULL, 0);
|
||||||
usb_drv_cancel_all_transfers();
|
usb_drv_cancel_all_transfers();
|
||||||
usb_drv_set_address(address);
|
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() */
|
/* called by usb_drv_int() */
|
||||||
void usb_core_bus_reset(void)
|
void usb_core_bus_reset(void)
|
||||||
{
|
{
|
||||||
|
logf("usb_core: bus reset");
|
||||||
usb_address = 0;
|
usb_address = 0;
|
||||||
usb_state = DEFAULT;
|
usb_state = DEFAULT;
|
||||||
#ifdef HAVE_USB_CHARGING_ENABLE
|
#ifdef HAVE_USB_CHARGING_ENABLE
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue