From f7617168e2ce2e7ea2e49cba5962b69aed04900e Mon Sep 17 00:00:00 2001 From: renjie Date: Sun, 21 Jun 2026 14:06:23 +0800 Subject: fix(host): release spinlock in tuh_deinit to fix multi-rebuild panic tuh_rhport_init() calls osal_spin_init(&_usbh_spin), which under OPT_OS_PICO claims a hardware spinlock via critical_section_init(). There was no osal_spin_deinit(), so tuh_deinit() never released it: every host init/deinit cycle leaked one spinlock. RP2350 has a small spinlock pool, so a few usb_host rebuilds exhaust it and hw_claim_unused_from_range() panics (the long-standing "crashes on the 4th rebuild" bug). Add osal_spin_deinit() to all OSAL backends (critical_section_deinit for pico; no-op for none/freertos) and call it in tuh_deinit(). Verified 20/20 deinit+rebuild cycles on RP2350-Zero and Waveshare RP2350-USB-A (previously panicked on the 4th). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/osal/osal_none.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/osal/osal_none.h') diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 3e397ef35..0893bb55c 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -46,6 +46,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_deinit(osal_spinlock_t *ctx) { + (void) ctx; +} + TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!in_isr) { ctx->interrupt_set(false); -- cgit v1.3.1