From 14ebd6c4d92bacc9e4289c23286ab9246eea7275 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 1 Oct 2013 11:29:25 +0700 Subject: [PATCH] refractor hub --- tinyusb/host/ehci/ehci.c | 2 +- tinyusb/host/usbh.c | 73 ++++++++++++++-------------------------- tinyusb/host/usbh_hcd.h | 2 +- 3 files changed, 28 insertions(+), 49 deletions(-) diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 56fad4b4..9cebff79 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -567,7 +567,7 @@ static void port_connect_status_change_isr(uint8_t hostid) usbh_device_plugged_isr(hostid, 0, 0); }else // device unplugged { - usbh_device_unplugged_isr(hostid); + usbh_hcd_rhport_unplugged_isr(hostid); regs->usb_cmd_bit.advacne_async = 1; // Async doorbell check EHCI 4.8.2 for operational details } } diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 8a153aae..b623584d 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -279,42 +279,48 @@ void usbh_device_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) &(usbh_enumerate_t){ .core_id = hostid, .hub_addr = hub_addr, .hub_port = hub_port} ); } - -void usbh_device_unplugged_isr(uint8_t hostid) +// a device unplugged on hostid, hub_addr, hub_port +// return true if found and unmounted device, false if cannot find +bool usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) { //------------- find the device address that is unplugged -------------// uint8_t dev_addr = 0; while ( dev_addr <= TUSB_CFG_HOST_DEVICE_MAX && - !(usbh_devices[dev_addr].core_id == hostid && - usbh_devices[dev_addr].hub_addr == 0 && - usbh_devices[dev_addr].hub_port == 0 && + !(usbh_devices[dev_addr].core_id == hostid && + usbh_devices[dev_addr].hub_addr == hub_addr && + usbh_devices[dev_addr].hub_port == hub_port && usbh_devices[dev_addr].state != TUSB_DEVICE_STATE_UNPLUG ) ) { dev_addr++; } if (dev_addr > TUSB_CFG_HOST_DEVICE_MAX) // unplug unmounted device - return; - - if (dev_addr > 0) // device can still be unplugged when not set new address { - // if device unplugged is not a hub TODO handle hub unplugged - for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++) - { - if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) && - usbh_class_drivers[class_index].close) - { - usbh_class_drivers[class_index].close(dev_addr); - } - } + return false; } + // if device unplugged is not a hub TODO handle hub unplugged + for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++) + { + if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) && + usbh_class_drivers[class_index].close) + { + usbh_class_drivers[class_index].close(dev_addr); + } + } usbh_pipe_control_close(dev_addr); // set to REMOVING to allow HCD to clean up its cached data for this device // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING; usbh_devices[dev_addr].flag_supported_class = 0; + + return true; +} + +void usbh_hcd_rhport_unplugged_isr(uint8_t hostid) +{ + (void) usbh_device_unplugged(hostid, 0, 0); } //--------------------------------------------------------------------+ @@ -351,6 +357,7 @@ tusb_error_t enumeration_body_subtask(void) usbh_devices[0].core_id = enum_entry.core_id; // TODO refractor integrate to device_pool usbh_devices[0].hub_addr = enum_entry.hub_addr; usbh_devices[0].hub_port = enum_entry.hub_port; + usbh_devices[0].state = TUSB_DEVICE_STATE_UNPLUG; if ( usbh_devices[0].hub_addr != 0) // connected/disconnected via hub { @@ -371,39 +378,11 @@ tusb_error_t enumeration_body_subtask(void) if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_current.connect_status ) { // Device is disconnected via Hub - uint8_t dev_addr = 1; - while ( dev_addr <= TUSB_CFG_HOST_DEVICE_MAX && - !(usbh_devices[dev_addr].core_id == usbh_devices[0].core_id && - usbh_devices[dev_addr].hub_addr == usbh_devices[0].hub_addr && - usbh_devices[dev_addr].hub_port == usbh_devices[0].hub_port && - usbh_devices[dev_addr].state != TUSB_DEVICE_STATE_UNPLUG ) ) + if ( usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port) ) { - dev_addr++; + hcd_hub_advance_asyn(usbh_devices[0].core_id); // TODO hack } - if (dev_addr > TUSB_CFG_HOST_DEVICE_MAX) // unplug unmounted device - { - SUBTASK_EXIT(TUSB_ERROR_NONE); - } - - // if device unplugged is not a hub TODO handle hub unplugged - for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++) - { - if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) && - usbh_class_drivers[class_index].close) - { - usbh_class_drivers[class_index].close(dev_addr); - } - } - usbh_pipe_control_close(dev_addr); - - // set to REMOVING to allow HCD to clean up its cached data for this device - // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done - usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING; - usbh_devices[dev_addr].flag_supported_class = 0; - - hcd_hub_advance_asyn(usbh_devices[0].core_id); // TODO hack - (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task } diff --git a/tinyusb/host/usbh_hcd.h b/tinyusb/host/usbh_hcd.h index ebc1d962..856633e5 100644 --- a/tinyusb/host/usbh_hcd.h +++ b/tinyusb/host/usbh_hcd.h @@ -116,7 +116,7 @@ extern usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; // including //--------------------------------------------------------------------+ void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event, uint32_t xferred_bytes); void usbh_device_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port); -void usbh_device_unplugged_isr(uint8_t hostid); +void usbh_hcd_rhport_unplugged_isr(uint8_t hostid); #ifdef __cplusplus }