From dee6b369235e3440f9237ae0e74f81edca95f6b7 Mon Sep 17 00:00:00 2001 From: Roman Leonov Date: Wed, 11 Dec 2024 11:35:52 +0100 Subject: [PATCH 1/2] feature(tusb): Added teardown API --- src/tusb.c | 34 ++++++++++++++++++++++++++++++++++ src/tusb.h | 14 ++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/tusb.c b/src/tusb.c index 85ab1d6ae..1549419c8 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -136,6 +136,40 @@ void tusb_int_handler(uint8_t rhport, bool in_isr) { #endif } +bool tusb_rhport_teardown(uint8_t rhport) { + // backward compatible call with tusb_init(void) + #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) + #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) + // deinit device stack, CFG_TUSB_RHPORTx_MODE must be defined + TU_ASSERT( tud_deinit(TUD_OPT_RHPORT) ); + _tusb_rhport_role[TUD_OPT_RHPORT] = TUSB_ROLE_INVALID; + #endif + + #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) + // deinit host stack CFG_TUSB_RHPORTx_MODE must be defined + TU_ASSERT( tuh_deinit(TUH_OPT_RHPORT) ); + _tusb_rhport_role[TUH_OPT_RHPORT] = TUSB_ROLE_INVALID; + #endif + + return true; + #endif + + // new API with explicit rhport and role + TU_ASSERT(rhport < TUP_USBIP_CONTROLLER_NUM); + + #if CFG_TUD_ENABLED + TU_ASSERT( tud_deinit(rhport) ); + _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; + #endif + + #if CFG_TUH_ENABLED + TU_ASSERT( tuh_deinit(rhport) ); + _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; + #endif + + return true; +} + //--------------------------------------------------------------------+ // Descriptor helper //--------------------------------------------------------------------+ diff --git a/src/tusb.h b/src/tusb.h index cb6021b33..2b122c302 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -154,14 +154,24 @@ bool tusb_inited(void); // Called to handle usb interrupt/event. tusb_init(rhport, role) must be called before void tusb_int_handler(uint8_t rhport, bool in_isr); -// TODO -// bool tusb_teardown(void); +// Internal helper for backward compatibility with tusb_init(void) +bool tusb_rhport_teardown(uint8_t rhport); + +#if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) + #define _tusb_teardown_arg0() tusb_rhport_teardown(0) +#else + #define _tusb_teardown_arg0() TU_VERIFY_STATIC(false, "CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE must be defined") +#endif + +#define _tusb_teardown_arg1(_rhport) tusb_rhport_teardown(_rhport) +#define tusb_teardown(...) TU_FUNC_OPTIONAL_ARG(_tusb_teardown, __VA_ARGS__) #else #define tusb_init(...) (false) #define tusb_int_handler(...) do {}while(0) #define tusb_inited() (false) +#define tusb_teardown(...) (false) #endif From f14fcaa84d44855ac3718eb2a786114385b53657 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Jul 2025 17:36:45 +0700 Subject: [PATCH 2/2] rename to tusb_deinit() to match other namingg --- src/tusb.c | 39 ++++++++++++++------------------------- src/tusb.h | 17 ++++------------- 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/src/tusb.c b/src/tusb.c index 5d366aeda..5a3ea356b 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -136,38 +136,27 @@ void tusb_int_handler(uint8_t rhport, bool in_isr) { #endif } -bool tusb_rhport_teardown(uint8_t rhport) { - // backward compatible call with tusb_init(void) - #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) - #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) - // deinit device stack, CFG_TUSB_RHPORTx_MODE must be defined - TU_ASSERT( tud_deinit(TUD_OPT_RHPORT) ); - _tusb_rhport_role[TUD_OPT_RHPORT] = TUSB_ROLE_INVALID; - #endif - - #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) - // deinit host stack CFG_TUSB_RHPORTx_MODE must be defined - TU_ASSERT( tuh_deinit(TUH_OPT_RHPORT) ); - _tusb_rhport_role[TUH_OPT_RHPORT] = TUSB_ROLE_INVALID; - #endif - - return true; - #endif - - // new API with explicit rhport and role - TU_ASSERT(rhport < TUP_USBIP_CONTROLLER_NUM); +bool tusb_deinit(uint8_t rhport) { + TU_VERIFY(rhport < TUP_USBIP_CONTROLLER_NUM); + bool ret = false; #if CFG_TUD_ENABLED - TU_ASSERT( tud_deinit(rhport) ); - _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; + if (_tusb_rhport_role[rhport] == TUSB_ROLE_DEVICE) { + TU_ASSERT(tud_deinit(rhport)); + _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; + ret = true; + } #endif #if CFG_TUH_ENABLED - TU_ASSERT( tuh_deinit(rhport) ); - _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; + if (_tusb_rhport_role[rhport] == TUSB_ROLE_HOST) { + TU_ASSERT(tuh_deinit(rhport)); + _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; + ret = true; + } #endif - return true; + return ret; } //--------------------------------------------------------------------+ diff --git a/src/tusb.h b/src/tusb.h index 83f5993d0..e794a8b0b 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -140,7 +140,7 @@ bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Initialize roothub port with device/host role // Note: when using with RTOS, this should be called after scheduler/kernel is started. -// Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. +// Since USB IRQ handler does use RTOS queue API. // Note2: defined as macro for backward compatible with tusb_init(void), can be changed to function in the future. #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) #define _tusb_init_arg0() tusb_rhport_init(0, NULL) @@ -158,24 +158,15 @@ bool tusb_inited(void); // Called to handle usb interrupt/event. tusb_init(rhport, role) must be called before void tusb_int_handler(uint8_t rhport, bool in_isr); -// Internal helper for backward compatibility with tusb_init(void) -bool tusb_rhport_teardown(uint8_t rhport); - -#if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) - #define _tusb_teardown_arg0() tusb_rhport_teardown(0) -#else - #define _tusb_teardown_arg0() TU_VERIFY_STATIC(false, "CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE must be defined") -#endif - -#define _tusb_teardown_arg1(_rhport) tusb_rhport_teardown(_rhport) -#define tusb_teardown(...) TU_FUNC_OPTIONAL_ARG(_tusb_teardown, __VA_ARGS__) +// Deinit usb stack on roothub port +bool tusb_deinit(uint8_t rhport); #else #define tusb_init(...) (false) #define tusb_int_handler(...) do {}while(0) #define tusb_inited() (false) -#define tusb_teardown(...) (false) +#define tusb_deinit(...) (false) #endif