From 688a3a0cc2ba23c671df453257fdf3e601934588 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 13:58:10 +0930 Subject: [PATCH 1/6] Fix non-trivial designated initializers compile error --- src/host/hcd.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index 036394c72..5d61dcd88 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -204,13 +204,11 @@ void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred .rhport = 0, // TODO correct rhport .event_id = HCD_EVENT_XFER_COMPLETE, .dev_addr = dev_addr, - .xfer_complete = - { - .ep_addr = ep_addr, - .result = result, - .len = xferred_bytes - } }; + event.xfer_complete.ep_addr = ep_addr; + event.xfer_complete.result = result; + event.xfer_complete.len = xferred_bytes; + hcd_event_handler(&event, in_isr); } From 9e30ec4f160e4816e3c43a0590e6c58832a66cac Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 13:58:50 +0930 Subject: [PATCH 2/6] Hub: Retry port status transfer if failed --- src/host/hub.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index 9e546f6f7..5c0fd9166 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -169,7 +169,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(&xfer) ); + TU_VERIFY( tuh_control_xfer(&xfer) ); return true; } @@ -332,7 +332,11 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 { if ( tu_bit_test(p_hub->status_change, port) ) { - hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0); + if (hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0) == false) + { + //Hub status control transfer failed, retry + hub_edpt_status_xfer(dev_addr); + } break; } } From b7c8cb3c41ba0fc7f9c0db9379d5c65871f6374d Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 14:00:36 +0930 Subject: [PATCH 3/6] Hub: Unplug downstream devices on non-root hub disconnect --- src/host/usbh.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/host/usbh.c b/src/host/usbh.c index e0e41a8d1..af2ad0575 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1107,6 +1107,12 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h { TU_LOG2(" Address = %u\r\n", dev_addr); + // If the device itself is a usb hub, unplug downstream devices. + if (dev_addr > CFG_TUH_DEVICE_MAX) + { + process_device_unplugged(rhport, dev_addr, 0); + } + // Invoke callback before close driver if (tuh_umount_cb) tuh_umount_cb(dev_addr); From 7df7590f7f96f0647e3164c7c7b368decffc87a2 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 14:01:24 +0930 Subject: [PATCH 4/6] Hub: Remove multi-level hub bypass --- src/host/usbh.c | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index af2ad0575..908230c83 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1513,40 +1513,31 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); - if (desc_itf->bInterfaceClass == TUSB_CLASS_HUB && dev->hub_addr != 0) + // Find driver for this interface + uint8_t drv_id; + for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - // TODO Attach hub to Hub is not currently supported - // skip this interface - TU_LOG(USBH_DBG_LVL, "Only 1 level of HUB is supported\r\n"); - } - else - { - // Find driver for this interface - uint8_t drv_id; - for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + + if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + // open successfully + TU_LOG2(" %s opened\r\n", driver->name); - if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) + // bind (associated) interfaces to found driver + for(uint8_t i=0; iname); + uint8_t const itf_num = desc_itf->bInterfaceNumber+i; - // bind (associated) interfaces to found driver - for(uint8_t i=0; ibInterfaceNumber+i; - - // Interface number must not be used already - TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] ); - dev->itf2drv[itf_num] = drv_id; - } - - // bind all endpoints to found driver - tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id); - - break; // exit driver find loop + // Interface number must not be used already + TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] ); + dev->itf2drv[itf_num] = drv_id; } + + // bind all endpoints to found driver + tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id); + + break; // exit driver find loop } if( drv_id >= USBH_CLASS_DRIVER_COUNT ) From f4a7b5b80c86777b62842e19f9bd6236161f2e8d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 16 Jun 2022 14:37:57 +0700 Subject: [PATCH 5/6] add note for recursive calls of process_device_unplugged() in case of hub --- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- src/host/usbh.c | 37 +++++++++++---------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index e9e68cf5a..c469ec813 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -81,7 +81,7 @@ // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 -#define CFG_TUH_HUB 1 +#define CFG_TUH_HUB 1 // number of supported hubs #define CFG_TUH_CDC 1 #define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 diff --git a/src/host/usbh.c b/src/host/usbh.c index 908230c83..04d969ce6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1089,6 +1089,12 @@ uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_i // //--------------------------------------------------------------------+ +TU_ATTR_ALWAYS_INLINE +static inline bool is_hub_addr(uint8_t daddr) +{ + return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); +} + // a device unplugged from rhport:hub_addr:hub_port static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { @@ -1101,21 +1107,24 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h // TODO Hub multiple level if (dev->rhport == rhport && - (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub - (hub_port == 0 || dev->hub_port == hub_port) && + (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr = 0 means roothub + (hub_port == 0 || dev->hub_port == hub_port) && // hub_port = 0 means all devices of downstream hub dev->connected) { TU_LOG2(" Address = %u\r\n", dev_addr); - // If the device itself is a usb hub, unplug downstream devices. - if (dev_addr > CFG_TUH_DEVICE_MAX) + if (is_hub_addr(dev_addr)) { + TU_LOG(USBH_DBG_LVL, "HUB address = %u is unmounted\r\n", dev_addr); + // If the device itself is a usb hub, unplug downstream devices. + // FIXME un-roll recursive calls to prevent potential stack overflow process_device_unplugged(rhport, dev_addr, 0); + }else + { + // Invoke callback before closing driver + if (tuh_umount_cb) tuh_umount_cb(dev_addr); } - // Invoke callback before close driver - if (tuh_umount_cb) tuh_umount_cb(dev_addr); - // Close class driver for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { @@ -1395,12 +1404,6 @@ static bool enum_new_device(hcd_event_t* event) return true; } -TU_ATTR_ALWAYS_INLINE -static inline bool is_hub_addr(uint8_t daddr) -{ - return daddr > CFG_TUH_DEVICE_MAX; -} - static uint8_t get_new_address(bool is_hub) { uint8_t start; @@ -1577,10 +1580,10 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { enum_full_complete(); -#if CFG_TUH_HUB - // skip device mount callback for hub - if ( !is_hub_addr(dev_addr) ) -#endif + if (is_hub_addr(dev_addr)) + { + TU_LOG(USBH_DBG_LVL, "HUB address = %u is mounted\r\n", dev_addr); + }else { // Invoke callback if available if (tuh_mount_cb) tuh_mount_cb(dev_addr); From 2036a0b62a709168d80d2b314e580ee1d1eda0bf Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 16 Jun 2022 14:41:10 +0700 Subject: [PATCH 6/6] update readme --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 5b994c357..1a96f6e16 100644 --- a/README.rst +++ b/README.rst @@ -82,7 +82,7 @@ Host Stack - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) -- Hub currently only supports 1 level of hub (due to my laziness) +- Hub with multiple-level support OS Abstraction layer ====================