/*
 * SPDX-FileCopyrightText: Copyright (c) 2019 Ha Thach (tinyusb.org)
 * SPDX-License-Identifier: MIT
 *
 * This file is part of the TinyUSB stack.
 */

#include "tusb_option.h"

#if CFG_TUH_ENABLED

#include "hcd.h"
#include "tusb.h"
#include "usbh_pvt.h"
#include "hub.h"

//--------------------------------------------------------------------+
// Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUH_TASK_QUEUE_SZ
  #define CFG_TUH_TASK_QUEUE_SZ   16
#endif

#ifndef CFG_TUH_CONTROL_PENDING_QUEUE_SZ
  #if CFG_TUH_HUB
    #define CFG_TUH_CONTROL_PENDING_QUEUE_SZ 4
  #else
    #define CFG_TUH_CONTROL_PENDING_QUEUE_SZ 2
  #endif
#endif

#ifndef CFG_TUH_INTERFACE_MAX
  #define CFG_TUH_INTERFACE_MAX   8
#endif

enum {
  USBH_CONTROL_RETRY_MAX = 3,
};

//--------------------------------------------------------------------+
// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) {
  (void) rhport; return false;
}

TU_ATTR_WEAK bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
  (void) rhport; (void) cfg_id; (void) cfg_param;
  return false;
}

TU_ATTR_WEAK void tuh_enum_descriptor_device_cb(uint8_t daddr, const tusb_desc_device_t *desc_device) {
  (void) daddr; (void) desc_device;
}

TU_ATTR_WEAK bool tuh_enum_descriptor_configuration_cb(uint8_t daddr, uint8_t cfg_index, const tusb_desc_configuration_t *desc_config) {
  (void) daddr; (void) cfg_index; (void) desc_config;
  return true;
}

TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
  (void) rhport; (void) eventid; (void) in_isr;
}

TU_ATTR_WEAK bool hcd_dcache_clean(const void* addr, uint32_t data_size) {
  (void) addr; (void) data_size;
  return false;
}

TU_ATTR_WEAK bool hcd_dcache_invalidate(const void* addr, uint32_t data_size) {
  (void) addr; (void) data_size;
  return false;
}

TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
  (void) addr; (void) data_size;
  return false;
}

TU_ATTR_WEAK usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count) {
  *driver_count = 0;
  return NULL;
}

TU_ATTR_WEAK void tuh_mount_cb(uint8_t daddr) {
  (void) daddr;
}

TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr) {
  (void) daddr;
}

//--------------------------------------------------------------------+
// Data Structure
//--------------------------------------------------------------------+

// Device Descriptor (without bLength and bDescriptorType header)
typedef struct TU_ATTR_PACKED {
  uint16_t bcdUSB;
  uint8_t  bDeviceClass;
  uint8_t  bDeviceSubClass;
  uint8_t  bDeviceProtocol;
  uint8_t  bMaxPacketSize0;
  uint16_t idVendor;
  uint16_t idProduct;
  uint16_t bcdDevice;
  uint8_t  iManufacturer;
  uint8_t  iProduct;
  uint8_t  iSerialNumber;
  uint8_t  bNumConfigurations;
} desc_device_noheader_t;

TU_VERIFY_STATIC( sizeof(desc_device_noheader_t) == 16u, "size is not correct");

typedef struct {
  tuh_bus_info_t bus_info;
  desc_device_noheader_t desc_device;

  // Device State
  struct TU_ATTR_PACKED {
    volatile uint8_t connected  : 1; // After 1st transfer
    volatile uint8_t addressed  : 1; // After SET_ADDR
    volatile uint8_t configured : 1; // After SET_CONFIG and all drivers are configured
    volatile uint8_t suspended  : 1; // Bus suspended
    // volatile uint8_t removing : 1; // Physically disconnected, waiting to be processed by usbh
  };

  // Endpoint & Interface
  uint8_t itf2drv[CFG_TUH_INTERFACE_MAX];  // map interface number to driver (0xff is invalid)
  uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each

  volatile uint8_t ep_status[CFG_TUH_ENDPOINT_MAX][2];

#if CFG_TUH_API_EDPT_XFER
  // TODO array can be CFG_TUH_ENDPOINT_MAX-1
  struct {
    tuh_xfer_cb_t complete_cb;
    uintptr_t user_data;
  }ep_callback[CFG_TUH_ENDPOINT_MAX][2];
#endif

} usbh_device_t;

// sum of end device + hub
#define TOTAL_DEVICES   (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB)

// all devices excluding zero-address
// hub address start from CFG_TUH_DEVICE_MAX+1
// TODO: hub can has its own simpler struct to save memory
static usbh_device_t _usbh_devices[TOTAL_DEVICES];

// Mutex for claiming endpoint
#if OSAL_MUTEX_REQUIRED
static osal_mutex_def_t _usbh_mutexdef;
static osal_mutex_t _usbh_mutex;
#else
#define _usbh_mutex   NULL
#endif

// Spinlock for interrupt handler
static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set);

// Event queue: usbh_int_set() is used as mutex in OS NONE config
OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t);
static osal_queue_t _usbh_q;

#if CFG_TUH_HUB
// Deferred attachment queue, only needed when using hub
OSAL_QUEUE_DEF(usbh_int_set, _usbh_daqdef, CFG_TUH_HUB, hcd_event_t);
static osal_queue_t _usbh_daq;
#endif

// Control transfers: since most controllers do not support multiple control transfers
// on multiple devices concurrently and control transfers are not used much except for
// enumeration, we will only execute control transfers one at a time.
typedef struct {
  uint8_t* buffer;
  tuh_xfer_cb_t complete_cb;
  uintptr_t user_data;

  volatile uint16_t actual_len;
  volatile uint8_t stage;
  uint8_t daddr;
  uint8_t failed_count;
} usbh_ctrl_xfer_info_t;

typedef struct {
  tusb_defer_func_t func;
  uintptr_t         arg;
  uint32_t          at_ms;
} usbh_call_after_t;

typedef struct {
  tusb_control_request_t setup;
  uint8_t*               buffer;
  tuh_xfer_cb_t          complete_cb;
  uintptr_t              user_data;
  uint8_t                daddr;
  uint8_t                daddr_gen;
} usbh_pending_ctrl_t;

// FIFO for pending async control transfers since we only execute 1 control transfer at a time
TU_FIFO_DEF(_usbh_pending_ctrl_q, CFG_TUH_CONTROL_PENDING_QUEUE_SZ * sizeof(usbh_pending_ctrl_t), false);

typedef struct {
  uint8_t enumerating_daddr;  // device address of the device being enumerated
  uint8_t attach_debouncing_bm;  // bitmask for roothub port attach debouncing
  tuh_bus_info_t dev0_bus;    // bus info for dev0 in enumeration
  usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer
  usbh_call_after_t call_after;
  // Per-daddr generation counter — bumped on usbh_device_close() to identify stale pending control transfer
  uint8_t daddr_gen[TOTAL_DEVICES + 1];
#if CFG_TUSB_OS_HAS_SCHEDULER
  osal_task_handle_t task_hdl;  // host task handle, lazy-captured on first tuh_task_ext()
#endif
} usbh_data_t;

static uint8_t _usbh_controller_id = TUSB_INDEX_INVALID_8;
static usbh_data_t _usbh_data;

typedef struct {
  TUH_EPBUF_TYPE_DEF(tusb_control_request_t, request);
  TUH_EPBUF_DEF(ctrl, CFG_TUH_ENUMERATION_BUFSIZE);
} usbh_epbuf_t;
CFG_TUH_MEM_SECTION static usbh_epbuf_t _usbh_epbuf;

//--------------------------------------------------------------------+
// Class Driver
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
  #define DRIVER_NAME(_name)  _name
#else
  #define DRIVER_NAME(_name)  NULL
#endif

static usbh_class_driver_t const usbh_class_drivers[] = {
  #if CFG_TUH_CDC
  {
      .name       = DRIVER_NAME("CDC"),
      .init       = cdch_init,
      .deinit     = cdch_deinit,
      .open       = cdch_open,
      .set_config = cdch_set_config,
      .xfer_cb    = cdch_xfer_cb,
      .close      = cdch_close
  },
  #endif

  #if CFG_TUH_MSC
  {
      .name       = DRIVER_NAME("MSC"),
      .init       = msch_init,
      .deinit     = msch_deinit,
      .open       = msch_open,
      .set_config = msch_set_config,
      .xfer_cb    = msch_xfer_cb,
      .close      = msch_close
  },
  #endif

  #if CFG_TUH_HID
  {
      .name       = DRIVER_NAME("HID"),
      .init       = hidh_init,
      .deinit     = hidh_deinit,
      .open       = hidh_open,
      .set_config = hidh_set_config,
      .xfer_cb    = hidh_xfer_cb,
      .close      = hidh_close
  },
  #endif

  #if CFG_TUH_MIDI
  {
      .name       = DRIVER_NAME("MIDI"),
      .init       = midih_init,
      .deinit     = midih_deinit,
      .open       = midih_open,
      .set_config = midih_set_config,
      .xfer_cb    = midih_xfer_cb,
      .close      = midih_close
  },
  #endif

  #if CFG_TUH_MIDI2
  {
      .name       = DRIVER_NAME("MIDI2"),
      .init       = midih2_init,
      .deinit     = midih2_deinit,
      .open       = midih2_open,
      .set_config = midih2_set_config,
      .xfer_cb    = midih2_xfer_cb,
      .close      = midih2_close
  },
  #endif

  #if CFG_TUH_HUB
  {
      .name       = DRIVER_NAME("HUB"),
      .init       = hub_init,
      .deinit     = hub_deinit,
      .open       = hub_open,
      .set_config = hub_set_config,
      .xfer_cb    = hub_xfer_cb,
      .close      = hub_close
  },
  #endif

};

// Additional class drivers implemented by application
static usbh_class_driver_t const * _app_driver = NULL;
static const uint8_t _builtin_driver_count     = TU_ARRAY_SIZE(usbh_class_drivers);
static uint8_t _app_driver_count               = 0;

#define TOTAL_DRIVER_COUNT    (_app_driver_count + _builtin_driver_count)

// virtually joins built-in and application drivers together.
// Application is positioned first to allow overwriting built-in ones.
TU_ATTR_ALWAYS_INLINE static inline usbh_class_driver_t const *get_driver(uint8_t drv_id) {
  usbh_class_driver_t const *driver = NULL;
  if (drv_id < _app_driver_count) {
    driver = &_app_driver[drv_id];
  } else {
    drv_id -= _app_driver_count;
    if (_builtin_driver_count > 0 && drv_id < _builtin_driver_count) {
      driver = &usbh_class_drivers[drv_id];
    }
  }

  return driver;
}

//--------------------------------------------------------------------+
// Function Inline and Prototypes
//--------------------------------------------------------------------+
static void enum_new_device(hcd_event_t* event);
static void enum_delay_async(uintptr_t state);
static void process_remove_event(hcd_event_t *event);
static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port);

static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size);
static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
static void control_xfer_dispatch_pending(void);
static void control_xfer_complete(uint8_t daddr, xfer_result_t result);

TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) {
  TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL);
  return &_usbh_devices[dev_addr-1];
}

TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) {
  return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); //-V560
}

TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) {
  TU_ASSERT(osal_queue_send(_usbh_q, event, in_isr));
  tuh_event_hook_cb(event->rhport, event->event_id, in_isr);
  return true;
}

TU_ATTR_ALWAYS_INLINE static inline void control_xfer_set_stage(uint8_t stage) {
  if (_usbh_data.ctrl_xfer_info.stage != stage) {
    (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
    _usbh_data.ctrl_xfer_info.stage = stage;
    (void) osal_mutex_unlock(_usbh_mutex);
  }
}

bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param) {
  TU_ASSERT(_usbh_data.call_after.func == NULL);
  TU_LOG_USBH("USBH schedule function after %u ms\r\n", (unsigned int)ms);
  _usbh_data.call_after.func  = func;
  _usbh_data.call_after.arg   = param;
  // add one to ensure we wait at least 'ms' milliseconds
  _usbh_data.call_after.at_ms = tusb_time_millis_api() + ms + 1;
  return true;
}

TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8_t daddr) {
  hcd_device_close(rhport, daddr);

  // Bump the generation under the mutex so a concurrent producer in
  // tuh_control_xfer stamps a value that is strictly monotonic w.r.t. close.
  (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
  _usbh_data.daddr_gen[daddr]++;
  (void) osal_mutex_unlock(_usbh_mutex);

  // If this device has in-flight control xfer, complete as FAILED
  usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;
  if (daddr == ctrl_info->daddr && ctrl_info->stage != CONTROL_STAGE_IDLE) {
    control_xfer_complete(daddr, XFER_RESULT_FAILED);
  }

  // invalidate if enumerating
  if (daddr == _usbh_data.enumerating_daddr) {
    _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8;
    // clear enum delay function of the device being removed
    if (_usbh_data.call_after.func == enum_delay_async) {
      _usbh_data.call_after.func = NULL;
    }
  }
}

//--------------------------------------------------------------------+
// Device API
//--------------------------------------------------------------------+
bool tuh_mounted(uint8_t dev_addr) {
  usbh_device_t *dev = get_device(dev_addr);
  TU_VERIFY(dev);
  return dev->configured;
}

bool tuh_connected(uint8_t daddr) {
  if (daddr == 0) {
    return _usbh_data.enumerating_daddr == 0;
  } else {
    const usbh_device_t* dev = get_device(daddr);
    TU_VERIFY(dev != NULL);
    return dev->connected;
  }
}

bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) {
  *vid = *pid = 0;

  usbh_device_t const *dev = get_device(dev_addr);
  TU_VERIFY(dev && dev->addressed && dev->desc_device.idVendor != 0);

  *vid = dev->desc_device.idVendor;
  *pid = dev->desc_device.idProduct;

  return true;
}

bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device) {
  usbh_device_t *dev = get_device(daddr);
  TU_VERIFY(dev && desc_device);

  desc_device->bLength = sizeof(tusb_desc_device_t);
  desc_device->bDescriptorType = TUSB_DESC_DEVICE;
  memcpy((uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), &dev->desc_device, sizeof(desc_device_noheader_t));

  return true;
}

tusb_speed_t tuh_speed_get(uint8_t daddr) {
  tuh_bus_info_t bus_info;
  tuh_bus_info_get(daddr, &bus_info);
  return (tusb_speed_t)bus_info.speed;
}

bool tuh_rhport_is_active(uint8_t rhport) {
  return _usbh_controller_id == rhport;
}

bool tuh_rhport_reset_bus(uint8_t rhport, bool active) {
  TU_VERIFY(tuh_rhport_is_active(rhport));
  if (active) {
    hcd_port_reset(rhport);
  } else {
    hcd_port_reset_end(rhport);
  }
  return true;
}

//--------------------------------------------------------------------+
// PUBLIC API (Parameter Verification is required)
//--------------------------------------------------------------------+
bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) {
  return hcd_configure(rhport, cfg_id, cfg_param);
}

static void clear_device(usbh_device_t* dev) {
  tu_memclr(dev, sizeof(usbh_device_t));
  (void) memset(dev->itf2drv, TUSB_INDEX_INVALID_8, sizeof(dev->itf2drv)); // invalid mapping
  (void) memset(dev->ep2drv , TUSB_INDEX_INVALID_8, sizeof(dev->ep2drv )); // invalid mapping
}

bool tuh_inited(void) {
  return _usbh_controller_id != TUSB_INDEX_INVALID_8;
}

bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
  if (tuh_rhport_is_active(rhport)) {
    return true; // skip if already initialized
  }
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
  char const* speed_str = 0;
  switch (rh_init->speed) {
    case TUSB_SPEED_HIGH:
      speed_str = "High";
    break;
    case TUSB_SPEED_FULL:
      speed_str = "Full";
    break;
    case TUSB_SPEED_LOW:
      speed_str = "Low";
    break;
    case TUSB_SPEED_AUTO:
      speed_str = "Auto";
    break;
  default:
    break;
  }
  TU_LOG_USBH("USBH init on controller %u, speed = %s\r\n", rhport, speed_str);
#endif

  // Init host stack if not already
  if (!tuh_inited()) {
    TU_LOG_INT_USBH(sizeof(usbh_data_t));
    TU_LOG_INT_USBH(sizeof(usbh_device_t));
    TU_LOG_INT_USBH(sizeof(hcd_event_t));
    TU_LOG_INT_USBH(sizeof(tuh_xfer_t));
    TU_LOG_INT_USBH(sizeof(tu_fifo_t));
    TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t));

    osal_spin_init(&_usbh_spin);

    // Event queue
    _usbh_q = osal_queue_create(&_usbh_qdef);
    TU_ASSERT(_usbh_q != NULL);

  #if CFG_TUH_HUB
    // Deferred attachment queue
    _usbh_daq = osal_queue_create(&_usbh_daqdef);
    TU_ASSERT(_usbh_daq != NULL);
  #endif

  #if OSAL_MUTEX_REQUIRED
    // Init mutex
    _usbh_mutex = osal_mutex_create(&_usbh_mutexdef);
    TU_ASSERT(_usbh_mutex);
  #endif

    // Get application driver if available
    _app_driver = usbh_app_driver_get_cb(&_app_driver_count);
    TU_ASSERT(_app_driver_count + _builtin_driver_count <= UINT8_MAX);

    // Device
    tu_memclr(_usbh_devices, sizeof(_usbh_devices));
    tu_memclr(&_usbh_data, sizeof(_usbh_data));

    _usbh_controller_id = TUSB_INDEX_INVALID_8;
    _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8;

    for (uint8_t i = 0; i < TOTAL_DEVICES; i++) {
      clear_device(&_usbh_devices[i]);
    }

    // Class drivers
    for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
      usbh_class_driver_t const* driver = get_driver(drv_id);
      if (driver != NULL) {
        TU_LOG_USBH("%s init\r\n", driver->name);
        driver->init();
      }
    }
  }

  // Init host controller
  _usbh_controller_id = rhport;
  TU_ASSERT(hcd_init(rhport, rh_init));
  hcd_int_enable(rhport);

  return true;
}

bool tuh_deinit(uint8_t rhport) {
  if (!tuh_rhport_is_active(rhport)) {
    return true;
  }

  // deinit host controller
  hcd_int_disable(rhport);
  TU_ASSERT(hcd_deinit(rhport));
  _usbh_controller_id = TUSB_INDEX_INVALID_8;

  // remove all devices on this rhport (hub_addr = 0, hub_port = 0)
  remove_device_tree(rhport, 0, 0);

  // deinit host stack if no controller is active
  if (!tuh_inited()) {
    // Class drivers
    for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
      usbh_class_driver_t const* driver = get_driver(drv_id);
      if (driver && driver->deinit) {
        TU_LOG_USBH("%s deinit\r\n", driver->name);
        driver->deinit();
      }
    }

    osal_queue_delete(_usbh_q);
    _usbh_q = NULL;

  #if CFG_TUH_HUB
    osal_queue_delete(_usbh_daq);
    _usbh_daq = NULL;
  #endif

    // Fire FAILED cb for any queued async control xfer so callers aren't stranded.
    usbh_pending_ctrl_t pending;
    while (tu_fifo_read_n(&_usbh_pending_ctrl_q, &pending, sizeof(pending)) == sizeof(pending)) {
      if (pending.complete_cb) {
        tuh_xfer_t x = {
          .daddr       = pending.daddr,
          .ep_addr     = 0,
          .result      = XFER_RESULT_FAILED,
          .actual_len  = 0,
          .setup       = &pending.setup,
          .buffer      = pending.buffer,
          .complete_cb = pending.complete_cb,
          .user_data   = pending.user_data,
        };
        pending.complete_cb(&x);
      }
    }
    tu_fifo_clear(&_usbh_pending_ctrl_q);

  #if OSAL_MUTEX_REQUIRED
    // TODO make sure there is no task waiting on this mutex
    osal_mutex_delete(_usbh_mutex);
    _usbh_mutex = NULL;
  #endif

    osal_spin_deinit(&_usbh_spin);
  }

  return true;
}

bool tuh_task_event_ready(void) {
  if (!tuh_inited()) {
    return false; // Skip if tusb stack is not initialized
  }
  if (!osal_queue_empty(_usbh_q)) {
    return true;
  }

  #if CFG_TUH_HUB
  if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8 &&
      !osal_queue_empty(_usbh_daq)) {
    return true;
  }
  #endif

  // Pending control xfer waiting for an idle slot
  if (_usbh_data.ctrl_xfer_info.stage == CONTROL_STAGE_IDLE &&
      !tu_fifo_empty(&_usbh_pending_ctrl_q)) {
    return true;
  }

  if (_usbh_data.call_after.func) {
    int32_t remain_ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api());
    if (remain_ms <= 0) {
      return true;
    }
  }

  return false;
}

/* USB Host Driver task
 * This top level thread manages all host controller event and delegates events to class-specific drivers.
 * This should be called periodically within the mainloop or rtos thread.
 *
   @code
    int main(void) {
      application_init();
      tusb_init(0, TUSB_ROLE_HOST);

      while(1) { // the mainloop
        application_code();
        tuh_task(); // tinyusb host task
      }
    }
    @endcode
 */
void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
  // Skip if stack is not initialized
  if (!tuh_inited()) {
    return;
  }

  (void) in_isr; // not implemented yet

#if CFG_TUSB_OS_HAS_SCHEDULER
  // Save task handle on 1st run
  if (_usbh_data.task_hdl == NULL) {
    _usbh_data.task_hdl = osal_task_get_current_handle();
  }
#endif

  // Loop until there are no more events in the queue or CFG_TUH_TASK_EVENTS_PER_RUN is reached
  for (unsigned epr = 0;; epr++) {
  #if CFG_TUH_TASK_EVENTS_PER_RUN > 0
    if (epr >= CFG_TUH_TASK_EVENTS_PER_RUN) {
      TU_LOG_USBH("USBH event limit (" TU_XSTRING(CFG_TUH_TASK_EVENTS_PER_RUN) ") reached\r\n");
      break;
    }
  #endif

    // Process call_after_ms function if ms is reached
    tusb_defer_func_t after_cb = _usbh_data.call_after.func;
    if (after_cb) {
      int32_t remain_ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api());
      if (remain_ms <= 0) {
        // delay expired, run callback now
        TU_LOG_USBH("USBH invoke scheduled function\r\n");
        _usbh_data.call_after.func = NULL;
        after_cb(_usbh_data.call_after.arg);
      }

      // above after_cb() can re-schedule another function, we need to re-check and reduce timeout of
      // the main event timeout to make sure we aren't blocking more than call_after remaining ms.
      if (_usbh_data.call_after.func != NULL) {
        remain_ms = (int32_t) (_usbh_data.call_after.at_ms - tusb_time_millis_api());
        if (remain_ms <= 0) {
          timeout_ms = 0; // expired already
        } else if (timeout_ms > (uint32_t)remain_ms) {
          timeout_ms = (uint32_t)remain_ms;
        }
      }
    }

    // Drain pending async control xfers. Slot transitions and dispatch are
    // decoupled: completion / abort / device_close set stage = IDLE via
    // control_xfer_set_stage() and the actual FIFO drain happens here in the
    // event loop. The check is a fast non-mutex sanity gate; the dispatcher
    // itself re-checks under the mutex.
    if (_usbh_data.ctrl_xfer_info.stage == CONTROL_STAGE_IDLE &&
        !tu_fifo_empty(&_usbh_pending_ctrl_q)) {
      control_xfer_dispatch_pending();
    }

    hcd_event_t event;

  #if CFG_TUH_HUB
    // Get deferred device attachments if none is enumerating
    bool has_deferred_attach = false;
    if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) {
      // zero wait to avoid blocking the main event queue
      has_deferred_attach = osal_queue_receive(_usbh_daq, &event, 0);
    }

    if (!has_deferred_attach) // skip event queue to process deferred attach
  #endif
    {
      if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) {
        return;
      }
    }

    switch (event.event_id) {
      case HCD_EVENT_DEVICE_ATTACH:
        // Should we miss the hub detach event due to high traffic, Or due to physical debouncing, some devices can
        // cause multiple attaches (actually reset) without a detached event.
        // Force remove currently mounted with the same bus info (rhport, hub addr, hub port) if exists
        process_remove_event(&event);

        // due to the shared control buffer, we must fully complete enumerating one device first.
        if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) {
          // New device attached and we are ready
          TU_LOG_USBH("[%u:] USBH Device Attach\r\n", event.rhport);
          _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0
          enum_new_device(&event);
        }
  #if CFG_TUH_HUB
        else {
          TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport);
          TU_ASSERT(osal_queue_send(_usbh_daq, &event, in_isr), );
        }
  #endif
        break;

      case HCD_EVENT_DEVICE_REMOVE:
        TU_LOG_USBH("[%u:%u:%u] USBH Device Removed\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
        process_remove_event(&event);
        break;

      case HCD_EVENT_XFER_COMPLETE: {
        uint8_t const ep_addr = event.xfer_complete.ep_addr;
        uint8_t const epnum = tu_edpt_number(ep_addr);
        uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr);

        TU_LOG_USBH("[:%u] on EP %02X with %u bytes: %s\r\n",
                    event.dev_addr, ep_addr, (unsigned int) event.xfer_complete.len, tu_str_xfer_result[event.xfer_complete.result]);

        if (event.dev_addr == 0) {
          // device 0 only has control endpoint
          TU_ASSERT(epnum == 0,);
          usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
        } else {
          usbh_device_t* dev = get_device(event.dev_addr);
          TU_VERIFY(dev && dev->connected,);

          // clear busy and claimed
          dev->ep_status[epnum][ep_dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);

          if (0 == epnum) {
            usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
          } else {
            // Prefer application callback over built-in one if available. This occurs when tuh_edpt_xfer() is used
            // with enabled driver e.g HID endpoint
            #if CFG_TUH_API_EDPT_XFER
            tuh_xfer_cb_t const complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb;
            if (complete_cb != NULL) {
              // re-construct xfer info
              tuh_xfer_t xfer = {
                  .daddr       = event.dev_addr,
                  .ep_addr     = ep_addr,
                  .result      = (xfer_result_t)event.xfer_complete.result,
                  .actual_len  = event.xfer_complete.len,
                  .buflen      = 0,    // not available
                  .buffer      = NULL, // not available
                  .complete_cb = complete_cb,
                  .user_data   = dev->ep_callback[epnum][ep_dir].user_data
              };
              complete_cb(&xfer);
            }else
            #endif
            {
              uint8_t drv_id = dev->ep2drv[epnum][ep_dir];
              usbh_class_driver_t const* driver = get_driver(drv_id);
              if (driver != NULL) {
                TU_LOG_USBH("  %s xfer callback\r\n", driver->name);
                driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result,
                                event.xfer_complete.len);
              } else {
                // no driver/callback responsible for this transfer
                TU_ASSERT(false,);
              }
            }
          }
        }
        break;
      }

      case USBH_EVENT_FUNC_CALL:
        if (event.func_call.func != NULL) {
          event.func_call.func(event.func_call.param);
        }
        break;

      default:
        // unknown event
        break;
    }

    // allow to exit tuh_task() if there is no event in the next run
    timeout_ms = 0;
  }
}

//--------------------------------------------------------------------+
// Control transfer
//--------------------------------------------------------------------+

// Carries both fields the sync waiter cares about — capturing from xfer_temp
// (snapshot taken before release_slot resets ctrl_info for the next pending
// entry) so the waiter sees this xfer's data, not the next dispatched one's.
typedef struct {
  volatile xfer_result_t result;
  volatile uint32_t      actual_len;
} control_xfer_sync_param_t;

static void control_xfer_sync_complete(tuh_xfer_t* xfer) {
  control_xfer_sync_param_t* s = (control_xfer_sync_param_t*) xfer->user_data;
  s->actual_len = xfer->actual_len;
  s->result     = xfer->result;
}

// TODO timeout_ms is not supported yet
bool tuh_control_xfer (tuh_xfer_t* xfer) {
  const uint8_t daddr = xfer->daddr;
  TU_VERIFY(daddr <= TOTAL_DEVICES && xfer->ep_addr == 0 && xfer->setup); // EP0 with setup packet
  usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;

#if CFG_TUSB_OS_HAS_SCHEDULER
  // Sync (complete_cb == NULL) from a host-stack callback is forbidden on
  // RTOS targets — the event-loop driver can't block on its own pending xfer
  // (deadlock if other control xfers are queued behind). Use async with a
  // chained cb instead. OS_NONE / OS_PICO are exempt: they have a single
  // execution context and the recursive-drive path is the only way to wait.
  TU_ASSERT(!(xfer->complete_cb == NULL &&
              osal_task_get_current_handle() == _usbh_data.task_hdl));
#endif

  // Slot is single-threaded — when busy, sync callers block until it frees
  // (blocking semantics require the result); async callers get queued in the
  // pending FIFO and submitted by control_xfer_complete() when the slot
  // drains. The test-and-{claim|enqueue} is one critical section so a slot
  // that becomes IDLE between the check and the enqueue can't strand an async
  // request in a queue nothing else drains.
  const bool is_nonblocking = (xfer->complete_cb != NULL);
  while (true) {
    TU_VERIFY(tuh_connected(daddr));
    bool claimed = false;
    bool is_queued = false;
    (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
    if (ctrl_info->stage == CONTROL_STAGE_IDLE) {
      ctrl_info->stage        = CONTROL_STAGE_SETUP;
      ctrl_info->daddr        = daddr;
      ctrl_info->actual_len   = 0;
      ctrl_info->failed_count = 0;

      ctrl_info->buffer       = xfer->buffer;
      ctrl_info->complete_cb  = xfer->complete_cb;
      ctrl_info->user_data    = xfer->user_data;
      _usbh_epbuf.request     = (*xfer->setup);
      claimed = true;
    } else if (is_nonblocking) {
      // Async + busy: queue the transfer.
      const usbh_pending_ctrl_t entry = {
        .setup       = *xfer->setup,
        .buffer      = xfer->buffer,
        .complete_cb = xfer->complete_cb,
        .user_data   = xfer->user_data,
        .daddr       = daddr,
        .daddr_gen   = _usbh_data.daddr_gen[daddr]
      };
      is_queued = tu_fifo_write_n(&_usbh_pending_ctrl_q, &entry, sizeof(entry)) == sizeof(entry);
    }

    (void) osal_mutex_unlock(_usbh_mutex);

    if (claimed) {
      break;
    }

    if (is_nonblocking) {
      return is_queued;
    }

    // - OS_HAS_SCHEDULER: delay 1 ms
    // - Otherwise: single execution context; drive the loop ourselves to progress the in-flight transfer.
#if CFG_TUSB_OS_HAS_SCHEDULER
    osal_task_delay(1);
#else
    tuh_task_ext(0, false);
#endif
  }
  TU_LOG_USBH("[%u:%u] %s: ", usbh_get_rhport(daddr), daddr,
              (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ?
                  tu_str_std_request[xfer->setup->bRequest] : "Class Request");
  TU_LOG_BUF_USBH(xfer->setup, 8);

  // Sync: wire control_xfer_sync_complete BEFORE submit so a fast completion
  // event has the cb in place. control_xfer_complete() captures both result
  // and actual_len through this cb before release_slot overwrites ctrl_info.
  volatile control_xfer_sync_param_t sync_state;
  if (!is_nonblocking) {
    sync_state.result = XFER_RESULT_INVALID;
    sync_state.actual_len = 0;
    ctrl_info->user_data   = (uintptr_t) &sync_state;
    ctrl_info->complete_cb = control_xfer_sync_complete;
  }

  if (!hcd_setup_send(usbh_get_rhport(daddr), daddr, (uint8_t const *) &_usbh_epbuf.request)) {
    control_xfer_set_stage(CONTROL_STAGE_IDLE);
    return false;
  }

  if (!is_nonblocking) {
    // No tuh_connected() escape needed: usbh_device_close() routes through
    // control_xfer_complete(daddr, FAILED) on disconnect, which fires
    // sync_complete and unblocks this poll.
    while (sync_state.result == XFER_RESULT_INVALID) {
#if CFG_TUSB_OS_HAS_SCHEDULER
      osal_task_delay(1);
#else
      tuh_task_ext(0, false);
#endif
    }

    // Forward to caller (xfer->user_data, if set, is a xfer_result_t pointer).
    if (xfer->user_data != 0) {
      *((xfer_result_t*) xfer->user_data) = sync_state.result;
    }
    xfer->result     = sync_state.result;
    xfer->actual_len = sync_state.actual_len;
  }

  return true;
}

// Start control transfer from pending fifo
static void control_xfer_dispatch_pending(void) {
  usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;

  while (true) {
    usbh_pending_ctrl_t xfer;
    bool has_xfer = false;

    (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
    if (ctrl_info->stage == CONTROL_STAGE_IDLE &&
        tu_fifo_read_n(&_usbh_pending_ctrl_q, &xfer, sizeof(xfer)) == sizeof(xfer)) {
      ctrl_info->stage        = CONTROL_STAGE_SETUP;
      ctrl_info->daddr        = xfer.daddr;
      ctrl_info->actual_len   = 0;
      ctrl_info->failed_count = 0;
      ctrl_info->buffer       = xfer.buffer;
      ctrl_info->complete_cb  = xfer.complete_cb;
      ctrl_info->user_data    = xfer.user_data;
      _usbh_epbuf.request     = xfer.setup;
      has_xfer = true;
    }
    (void) osal_mutex_unlock(_usbh_mutex);

    if (!has_xfer) {
      return; // nothing to do
    }

    // mismatched daddr_gen means pending transfer is stale due to the device got disconnected while in the FIFO
    // Note: the address can be re-allocated to another device at this point.
    if (xfer.daddr_gen == _usbh_data.daddr_gen[xfer.daddr]) {
      TU_LOG_USBH("[%u:%u] %s: ", usbh_get_rhport(xfer.daddr), xfer.daddr,
                  (xfer.setup.bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer.setup.bRequest <= TUSB_REQ_SYNCH_FRAME) ?
                      tu_str_std_request[xfer.setup.bRequest] : "Class Request");
      TU_LOG_BUF_USBH(&xfer.setup, 8);
      if (hcd_setup_send(usbh_get_rhport(xfer.daddr), xfer.daddr, (uint8_t const *) &_usbh_epbuf.request)) {
        return; // transfer kicked-off, we are done
      }
    }

    // complete callback as FAILED and continue with next pending xfer
    control_xfer_complete(xfer.daddr, XFER_RESULT_FAILED);
  }
}

static void control_xfer_complete(uint8_t daddr, xfer_result_t result) {
  TU_LOG_USBH("\r\n");
  usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;

  // duplicate xfer since user can execute control transfer within callback
  tusb_control_request_t const request = _usbh_epbuf.request;
  tuh_xfer_t xfer_temp = {
    .daddr       = daddr,
    .ep_addr     = 0,
    .result      = result,
    .setup       = &request,
    .actual_len  = (uint32_t) ctrl_info->actual_len,
    .buffer      = ctrl_info->buffer,
    .complete_cb = ctrl_info->complete_cb,
    .user_data   = ctrl_info->user_data
  };

  // set to IDLE before callback since cb can invoke another transfer
  control_xfer_set_stage(CONTROL_STAGE_IDLE);

  if (xfer_temp.complete_cb != NULL) {
    xfer_temp.complete_cb(&xfer_temp);
  }
}

static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
  (void) ep_addr;

  const uint8_t rhport = usbh_get_rhport(daddr);
  tusb_control_request_t const * request = &_usbh_epbuf.request;
  usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;

  // Drop stale completions: slot already released (abort/close fired its cb)
  // or now owns a different device's xfer (a pending entry was dispatched).
  if (ctrl_info->stage == CONTROL_STAGE_IDLE || ctrl_info->daddr != daddr) {
    return true;
  }

  switch (result) {
    case XFER_RESULT_STALLED:
      TU_LOG_USBH("[%u:%u] Control STALLED, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, xferred_bytes);
      TU_LOG_BUF_USBH(request, 8);
      control_xfer_complete(daddr, result);
    break;

    case XFER_RESULT_FAILED:
      if (tuh_connected(daddr) && ctrl_info->failed_count < USBH_CONTROL_RETRY_MAX) {
        TU_LOG_USBH("[%u:%u] Control FAILED %u/%u, retrying\r\n", rhport, daddr, ctrl_info->failed_count+1, USBH_CONTROL_RETRY_MAX);
        (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
        ctrl_info->stage = CONTROL_STAGE_SETUP;
        ctrl_info->failed_count++;
        ctrl_info->actual_len = 0; // reset actual_len
        (void) osal_mutex_unlock(_usbh_mutex);

        if (!hcd_setup_send(rhport, daddr, (uint8_t const *) request)) {
          control_xfer_complete(daddr, XFER_RESULT_FAILED);
          return false;
        }
      } else {
        TU_LOG_USBH("[%u:%u] Control FAILED, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, xferred_bytes);
        TU_LOG_BUF_USBH(request, 8);
        control_xfer_complete(daddr, result);
      }
    break;

    case XFER_RESULT_SUCCESS:
      switch(ctrl_info->stage) {
        case CONTROL_STAGE_SETUP:
          if (request->wLength > 0) {
            // DATA stage: initial data toggle is always 1
            control_xfer_set_stage(CONTROL_STAGE_DATA);
            const uint8_t ep_data = tu_edpt_addr(0, request->bmRequestType_bit.direction);
            TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_data, ctrl_info->buffer, request->wLength));
            return true;
          }
          TU_ATTR_FALLTHROUGH;

        case CONTROL_STAGE_DATA: {
            if (request->wLength > 0) {
              TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr);
              TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2);
            }
            ctrl_info->actual_len = (uint16_t) xferred_bytes;

            // ACK stage: toggle is always 1
            control_xfer_set_stage(CONTROL_STAGE_ACK);
            const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction);
            TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0));
            break;
          }

        case CONTROL_STAGE_ACK: {
          // Abort all pending transfers if SET_CONFIGURATION request
          // NOTE: should we force closing all non-control endpoints in the future?
          if (request->bRequest == TUSB_REQ_SET_CONFIGURATION && request->bmRequestType == 0x00) {
            for(uint8_t epnum=1; epnum<CFG_TUH_ENDPOINT_MAX; epnum++) {
              for(uint8_t dir=0; dir<2; dir++) {
                tuh_edpt_abort_xfer(daddr, tu_edpt_addr(epnum, dir));
              }
            }
          }

          control_xfer_complete(daddr, result);
          break;
        }

        default: return false; // unsupported stage
      }
      break;

    default: return false; // unsupported result
  }

  return true;
}

//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+

bool tuh_edpt_xfer(tuh_xfer_t* xfer) {
  uint8_t const daddr = xfer->daddr;
  uint8_t const ep_addr = xfer->ep_addr;

  TU_VERIFY(daddr && ep_addr);
  TU_VERIFY(usbh_edpt_claim(daddr, ep_addr));

  if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen,
                                    xfer->complete_cb, xfer->user_data)) {
    usbh_edpt_release(daddr, ep_addr);
    return false;
  }

  return true;
}

bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) {
  TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr);
  const uint8_t epnum = tu_edpt_number(ep_addr);
  const uint8_t dir   = tu_edpt_dir(ep_addr);

  if (epnum == 0) {
    // Also include dev0 for aborting enumerating
    const uint8_t rhport = usbh_get_rhport(daddr);

    // control transfer: only 1 control at a time, check if we are aborting the current one
    const usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;
    TU_VERIFY(daddr == ctrl_info->daddr && ctrl_info->stage != CONTROL_STAGE_IDLE);
    hcd_edpt_abort_xfer(rhport, daddr, ep_addr);
    control_xfer_complete(daddr, XFER_RESULT_ABORTED);
  } else {
    usbh_device_t* dev = get_device(daddr);
    TU_VERIFY(dev);

    TU_VERIFY(dev->ep_status[epnum][dir] & TU_EDPT_STATE_BUSY); // non-control skip if not busy
    // abort then mark as ready and release endpoint
    hcd_edpt_abort_xfer(dev->bus_info.rhport, daddr, ep_addr);
    dev->ep_status[epnum][dir] &= (uint8_t) ~TU_EDPT_STATE_BUSY; // clear busy
    tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex);
  }

  return true;
}

//--------------------------------------------------------------------+
// USBH API For Class Driver
//--------------------------------------------------------------------+

uint8_t usbh_get_rhport(uint8_t daddr) {
  tuh_bus_info_t bus_info;
  tuh_bus_info_get(daddr, &bus_info);
  return bus_info.rhport;
}

uint8_t *usbh_get_enum_buf(void) {
  return _usbh_epbuf.ctrl;
}

void usbh_int_set(bool enabled) {
  // TODO all host controller if multiple are used since they shared the same event queue
  if (enabled) {
    hcd_int_enable(_usbh_controller_id);
  } else {
    hcd_int_disable(_usbh_controller_id);
  }
}

void usbh_spin_lock(bool in_isr) {
  osal_spin_lock(&_usbh_spin, in_isr);
}

void usbh_spin_unlock(bool in_isr) {
  osal_spin_unlock(&_usbh_spin, in_isr);
}

void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) {
  hcd_event_t event = { 0 };
  event.event_id = USBH_EVENT_FUNC_CALL;
  event.func_call.func = func;
  event.func_call.param = param;
  queue_event(&event, in_isr);
}

//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+

// Claim an endpoint for transfer
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) {
  // Note: addr0 only use tuh_control_xfer
  usbh_device_t* dev = get_device(dev_addr);
  TU_ASSERT(dev && dev->connected);

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  TU_VERIFY(tu_edpt_claim(&dev->ep_status[epnum][dir], _usbh_mutex));
  TU_LOG_USBH("[%u] Claimed EP 0x%02x\r\n", dev_addr, ep_addr);

  return true;
}

// Release an claimed endpoint due to failed transfer attempt
bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) {
  // Note: addr0 only use tuh_control_xfer
  usbh_device_t* dev = get_device(dev_addr);
  TU_VERIFY(dev && dev->connected);

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  TU_VERIFY(tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex));
  TU_LOG_USBH("[%u] Released EP 0x%02x\r\n", dev_addr, ep_addr);

  return true;
}

// Submit an transfer
bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes,
                                  tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  (void) complete_cb;
  (void) user_data;

  usbh_device_t* dev = get_device(dev_addr);
  TU_VERIFY(dev);

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);
  volatile uint8_t* ep_state = &dev->ep_status[epnum][dir];

  TU_LOG_USBH("  Queue EP %02X with %u bytes ... \r\n", ep_addr, total_bytes);

  // Attempt to transfer on a busy endpoint, sound like an race condition !
  TU_ASSERT((*ep_state & TU_EDPT_STATE_BUSY) == 0);

  // Set busy first since the actual transfer can be complete before hcd_edpt_xfer()
  // could return and USBH task can preempt and clear the busy
  *ep_state |= TU_EDPT_STATE_BUSY;

#if CFG_TUH_API_EDPT_XFER
  dev->ep_callback[epnum][dir].complete_cb = complete_cb;
  dev->ep_callback[epnum][dir].user_data   = user_data;
#endif

  if (hcd_edpt_xfer(dev->bus_info.rhport, dev_addr, ep_addr, buffer, total_bytes)) {
    TU_LOG_USBH("OK\r\n");
    return true;
  } else {
    // HCD error, clear busy and claimed to allow next transfer
    *ep_state &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
    TU_LOG1("Failed\r\n");
//    TU_BREAKPOINT();
    return false;
  }
}

static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) {
  TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size);
  tusb_desc_endpoint_t ep0_desc = {
    .bLength          = sizeof(tusb_desc_endpoint_t),
    .bDescriptorType  = TUSB_DESC_ENDPOINT,
    .bEndpointAddress = 0,
    .bmAttributes     = { .xfer = TUSB_XFER_CONTROL },
    .wMaxPacketSize   = max_packet_size,
    .bInterval        = 0
  };

  return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc);
}

bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) {
  // HACK: some device incorrectly always reports 512 bulk regardless of link speed, overwrite descriptor to force 64
  if (desc_ep->bmAttributes.xfer == TUSB_XFER_BULK && tu_edpt_packet_size(desc_ep) > 64 &&
      tuh_speed_get(dev_addr) == TUSB_SPEED_FULL) {
    TU_LOG1("  WARN: EP max packet size is 512 in fullspeed, force to 64\r\n");
    tusb_desc_endpoint_t *hacked_ep = (tusb_desc_endpoint_t *)(uintptr_t)desc_ep;
    hacked_ep->wMaxPacketSize       = tu_htole16(64);
  }
  TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)));
  return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep);
}

bool tuh_edpt_close(uint8_t daddr, uint8_t ep_addr) {
  TU_VERIFY(0 != tu_edpt_number(ep_addr)); // cannot close EP0
  tuh_edpt_abort_xfer(daddr, ep_addr); // abort any pending transfer
  return hcd_edpt_close(usbh_get_rhport(daddr), daddr, ep_addr);
}

bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) {
  usbh_device_t* dev = get_device(dev_addr);
  TU_VERIFY(dev);

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  return (dev->ep_status[epnum][dir] & TU_EDPT_STATE_BUSY) != 0;
}

//--------------------------------------------------------------------+
// HCD Event Handler
//--------------------------------------------------------------------+

bool tuh_bus_info_get(uint8_t daddr, tuh_bus_info_t* bus_info) {
  usbh_device_t const* dev = get_device(daddr);
  if (dev != NULL) {
    *bus_info = dev->bus_info;
  } else {
    *bus_info = _usbh_data.dev0_bus;
  }
  return true;
}

TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) {
  switch (event->event_id) {
    case HCD_EVENT_DEVICE_ATTACH:
    case HCD_EVENT_DEVICE_REMOVE:
      // Attach debouncing on roothub: skip attach/remove while debouncing delay
      if (event->connection.hub_addr == 0) {
        if (tu_bit_test(_usbh_data.attach_debouncing_bm, event->rhport)) {
          return;
        }

        if (event->event_id == HCD_EVENT_DEVICE_ATTACH) {
          // No debouncing, set flag if attach event
          _usbh_data.attach_debouncing_bm |= TU_BIT(event->rhport);
        }
      }
      break;

    default:
      // nothing to do
      break;
  }

  queue_event(event, in_isr);
}

//--------------------------------------------------------------------+
// Descriptors Async
//--------------------------------------------------------------------+

// generic helper to get a descriptor
// if blocking, user_data is pointed to xfer_result
TU_ATTR_ALWAYS_INLINE static inline
bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len,
                    tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  tusb_control_request_t const request = {
    .bmRequestType_bit = {
      .recipient = TUSB_REQ_RCPT_DEVICE,
      .type      = TUSB_REQ_TYPE_STANDARD,
      .direction = TUSB_DIR_IN
    },
    .bRequest = TUSB_REQ_GET_DESCRIPTOR,
    .wValue   = tu_htole16( TU_U16(type, index) ),
    .wIndex   = tu_htole16(language_id),
    .wLength  = tu_htole16(len)
  };
  tuh_xfer_t xfer = {
    .daddr       = daddr,
    .ep_addr     = 0,
    .setup       = &request,
    .buffer      = buffer,
    .complete_cb = complete_cb,
    .user_data   = user_data
  };

  return tuh_control_xfer(&xfer);
}

bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len,
                        tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_data);
}

bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len,
                               tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  len = tu_min16(len, sizeof(tusb_desc_device_t));
  return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_data);
}

bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len,
                                      tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_data);
}

//------------- String Descriptor -------------//
bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len,
                               tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_data);
}

// Get manufacturer string descriptor
bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len,
                                            tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
  usbh_device_t const* dev = get_device(daddr);
  TU_VERIFY(dev && dev->desc_device.iManufacturer);
  return tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, language_id, buffer, len, complete_cb, user_data);
}

// Get product string descriptor
bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len,
                                       tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  usbh_device_t const* dev = get_device(daddr);
  TU_VERIFY(dev && dev->desc_device.iProduct);
  return tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, language_id, buffer, len, complete_cb, user_data);
}

// Get serial string descriptor
bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len,
                                      tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  usbh_device_t const* dev = get_device(daddr);
  TU_VERIFY(dev && dev->desc_device.iSerialNumber);
  return tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, language_id, buffer, len, complete_cb, user_data);
}

// Get HID report descriptor
// if blocking, user_data is pointed to xfer_result
bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len,
                                   tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  TU_LOG_USBH("HID Get Report Descriptor\r\n");
  tusb_control_request_t const request = {
      .bmRequestType_bit = {
          .recipient = TUSB_REQ_RCPT_INTERFACE,
          .type      = TUSB_REQ_TYPE_STANDARD,
          .direction = TUSB_DIR_IN
      },
      .bRequest = TUSB_REQ_GET_DESCRIPTOR,
      .wValue   = tu_htole16(TU_U16(desc_type, index)),
      .wIndex   = tu_htole16((uint16_t) itf_num),
      .wLength  = len
  };
  tuh_xfer_t xfer = {
      .daddr       = daddr,
      .ep_addr     = 0,
      .setup       = &request,
      .buffer      = buffer,
      .complete_cb = complete_cb,
      .user_data   = user_data
  };

  return tuh_control_xfer(&xfer);
}

bool tuh_address_set(uint8_t daddr, uint8_t new_addr,
                     tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  TU_LOG_USBH("Set Address = %d\r\n", new_addr);
  const tusb_control_request_t request = {
    .bmRequestType_bit = {
      .recipient = TUSB_REQ_RCPT_DEVICE,
      .type      = TUSB_REQ_TYPE_STANDARD,
      .direction = TUSB_DIR_OUT
    },
    .bRequest = TUSB_REQ_SET_ADDRESS,
    .wValue   = tu_htole16(new_addr),
    .wIndex   = 0,
    .wLength  = 0
  };
  tuh_xfer_t xfer = {
    .daddr       = daddr,
    .ep_addr     = 0,
    .setup       = &request,
    .buffer      = NULL,
    .complete_cb = complete_cb,
    .user_data   = user_data
  };

  TU_ASSERT(tuh_control_xfer(&xfer));
  return true;
}

bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
                           tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  TU_LOG_USBH("Set Configuration = %d\r\n", config_num);
  tusb_control_request_t const request = {
      .bmRequestType_bit = {
          .recipient = TUSB_REQ_RCPT_DEVICE,
          .type      = TUSB_REQ_TYPE_STANDARD,
          .direction = TUSB_DIR_OUT
      },
      .bRequest = TUSB_REQ_SET_CONFIGURATION,
      .wValue   = tu_htole16(config_num),
      .wIndex   = 0,
      .wLength  = 0
  };
  tuh_xfer_t xfer = {
      .daddr       = daddr,
      .ep_addr     = 0,
      .setup       = &request,
      .buffer      = NULL,
      .complete_cb = complete_cb,
      .user_data   = user_data
  };

  return tuh_control_xfer(&xfer);
}

bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt,
                       tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  TU_LOG_USBH("Set Interface %u Alternate %u\r\n", itf_num, itf_alt);
  tusb_control_request_t const request = {
      .bmRequestType_bit = {
          .recipient = TUSB_REQ_RCPT_INTERFACE,
          .type      = TUSB_REQ_TYPE_STANDARD,
          .direction = TUSB_DIR_OUT
      },
      .bRequest = TUSB_REQ_SET_INTERFACE,
      .wValue   = tu_htole16(itf_alt),
      .wIndex   = tu_htole16(itf_num),
      .wLength  = 0
  };
  tuh_xfer_t xfer = {
      .daddr       = daddr,
      .ep_addr     = 0,
      .setup       = &request,
      .buffer      = NULL,
      .complete_cb = complete_cb,
      .user_data   = user_data
  };

  return tuh_control_xfer(&xfer);
}

//--------------------------------------------------------------------+
// Detaching
//--------------------------------------------------------------------+

// process detach event from rhport:hub_addr:hub_port
static void process_remove_event(hcd_event_t *event) {
  if (_usbh_data.enumerating_daddr == 0 &&
      event->rhport == _usbh_data.dev0_bus.rhport &&
      event->connection.hub_addr == _usbh_data.dev0_bus.hub_addr &&
      event->connection.hub_port == _usbh_data.dev0_bus.hub_port) {
    // dev0 is unplugged while enumerating (not yet assigned an address)
    usbh_device_close(_usbh_data.dev0_bus.rhport, 0);
  } else {
    remove_device_tree(event->rhport, event->connection.hub_addr, event->connection.hub_port);
  }
}

// remove a device at rhport:hub_addr:hub_port and all of its downstream
static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) {
  // Find the all devices (star-network) under port that is unplugged
  #if CFG_TUH_HUB
  uint8_t removing_hubs[CFG_TUH_HUB] = { 0 };
  #endif

  do {
    for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) {
      usbh_device_t* dev = &_usbh_devices[dev_id];
      uint8_t const daddr = dev_id + 1u;

      // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub
      if (dev->bus_info.rhport == rhport && dev->connected &&
          (hub_addr == 0 || dev->bus_info.hub_addr == hub_addr) &&
          (hub_port == 0 || dev->bus_info.hub_port == hub_port)) {
        TU_LOG_USBH("[%u:%u:%u] unplugged address = %u\r\n", rhport, hub_addr, hub_port, daddr);

        #if CFG_TUH_HUB
        if (is_hub_addr(daddr)) {
          TU_LOG_USBH("  is a HUB device %u\r\n", daddr);
          removing_hubs[dev_id - CFG_TUH_DEVICE_MAX] = 1;
        } else
        #endif
        {
          // Invoke callback before closing driver (maybe call it later ?)
          tuh_umount_cb(daddr);
        }

        // Close class driver
        for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
          usbh_class_driver_t const* driver = get_driver(drv_id);
          if (driver != NULL) {
            driver->close(daddr);
          }
        }

        usbh_device_close(rhport, daddr);
        clear_device(dev);
      }
    }

#if CFG_TUH_HUB
    // if a hub is removed, we need to remove all of its downstream devices
    if (tu_mem_is_zero(removing_hubs, CFG_TUH_HUB)) {
      break;
    }

    // find a marked hub to process
    for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) {
      if (0 != removing_hubs[h_id]) {
        removing_hubs[h_id] = 0;

        // update hub_addr and hub_port for next loop
        hub_addr = h_id + 1 + CFG_TUH_DEVICE_MAX;
        hub_port = 0;
        break;
      }
    }
#else
    break;
#endif

  } while(1);
}

//--------------------------------------------------------------------+
// Enumeration Process
// is a lengthy process with a series of control transfer to configure newly attached device.
// NOTE: due to the shared control buffer, we must complete enumerating
// one device before enumerating another one.
//--------------------------------------------------------------------+
enum {                                      // USB 2.0 specs 7.1.7 for timing
  ENUM_DEBOUNCING_DELAY_MS           = 150, // T(ATTDB)  minimum 100 ms for stable connection
  ENUM_RESET_ROOT_DELAY_MS           = 50,  // T(DRSTr)  minimum 50 ms for reset from root port
  ENUM_RESET_ROOT_POST_DELAY_MS      = 2,   // 2 ms delay after root port reset before getting speed/status
  ENUM_RESET_HUB_DELAY_MS            = 20,  // T(DRST)   10-20 ms for hub reset
  ENUM_RESET_RECOVERY_DELAY_MS       = 10,  // T(RSTRCY) minimum 10 ms for reset recovery
  ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2,   // USB 2.0 Spec 9.2.6.3 min is 2 ms
};

enum {
  ENUM_IDLE,
  ENUM_HUB_RERSET,
  ENUM_HUB_RESET_COMPLETE,
  ENUM_HUB_CLEAR_RESET,
  ENUM_HUB_CLEAR_RESET_RETRY, // 2nd attempt waiting for hub reset
  ENUM_HUB_CLEAR_RESET_COMPLETE,
  ENUM_ADDR0_DEVICE_DESC,
  ENUM_SET_ADDR,
  ENUM_GET_DEVICE_DESC,
  ENUM_GET_STRING_LANGUAGE_ID_LEN,
  ENUM_GET_STRING_LANGUAGE_ID,
  ENUM_GET_STRING_MANUFACTURER_LEN,
  ENUM_GET_STRING_MANUFACTURER,
  ENUM_GET_STRING_PRODUCT_LEN,
  ENUM_GET_STRING_PRODUCT,
  ENUM_GET_STRING_SERIAL_LEN,
  ENUM_GET_STRING_SERIAL,
  ENUM_GET_9BYTE_CONFIG_DESC,
  ENUM_GET_FULL_CONFIG_DESC,
  ENUM_SET_CONFIG,
  ENUM_CONFIG_DRIVER
};

static uint8_t enum_get_new_address(bool is_hub);
static bool    enum_parse_configuration_desc(uint8_t dev_addr, const tusb_desc_configuration_t *desc_cfg);
static void    enum_full_complete(bool success);
static void    process_enumeration(tuh_xfer_t *xfer);

enum {
  ENUM_AFTER_DEBOUNCING_DELAY,
  ENUM_AFTER_RESET_ROOT_DELAY,
  ENUM_AFTER_RESET_ROOT_POST_DELAY,
  ENUM_AFTER_RESET_HUB_DELAY,
  ENUM_AFTER_RESET_HUB_DELAY_RETRY,
  ENUM_AFTER_RESET_RECOVERY_DELAY,
  ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY,
};

// process async delay in enumeration
static void enum_delay_async(uintptr_t state) {
  tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus;
  switch (state) {
    case ENUM_AFTER_DEBOUNCING_DELAY:
  #if CFG_TUH_HUB
      if (dev0_bus->hub_addr != 0) {
        // connected via hub
        TU_VERIFY(dev0_bus->hub_port != 0, );
        TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration,
                                      ENUM_HUB_RERSET), );
      } else
  #endif
      {
        // connected directly to roothub
        _usbh_data.attach_debouncing_bm &= (uint8_t)~TU_BIT(dev0_bus->rhport); // clear roothub debouncing delay
        if (!hcd_port_connect_status(dev0_bus->rhport)) {
          TU_LOG_USBH("Device unplugged while debouncing\r\n");
          enum_full_complete(false);
          return;
        }
        hcd_port_reset(dev0_bus->rhport); // reset port
        usbh_defer_func_ms_async(ENUM_RESET_ROOT_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_ROOT_DELAY);
      }
      break;

    case ENUM_AFTER_RESET_ROOT_DELAY:
      hcd_port_reset_end(dev0_bus->rhport);
      usbh_defer_func_ms_async(ENUM_RESET_ROOT_POST_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_ROOT_POST_DELAY);
      break;

    case ENUM_AFTER_RESET_ROOT_POST_DELAY:
      if (!hcd_port_connect_status(dev0_bus->rhport)) {
        // device unplugged while delaying
        enum_full_complete(false);
        return;
      }

      dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport);
      TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]);

      // fake transfer to kick-off the enumeration process
      tuh_xfer_t xfer;
      xfer.daddr     = 0;
      xfer.result    = XFER_RESULT_SUCCESS;
      xfer.user_data = ENUM_ADDR0_DEVICE_DESC;
      process_enumeration(&xfer);
      break;

  #if CFG_TUH_HUB
    case ENUM_AFTER_RESET_HUB_DELAY:
    case ENUM_AFTER_RESET_HUB_DELAY_RETRY:
      // get status after reset complete to check for reset change
      TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration,
                                    state == ENUM_AFTER_RESET_HUB_DELAY ? ENUM_HUB_CLEAR_RESET
                                                                        : ENUM_HUB_CLEAR_RESET_RETRY), );
      break;
  #endif

    case ENUM_AFTER_RESET_RECOVERY_DELAY:
      // TODO probably doesn't need to open/close each enumeration
      if (!usbh_edpt_control_open(0, 8)) {
        TU_LOG_USBH("Failed to open dev0's control endpoint\r\n");
        enum_full_complete(false); // Stop enumeration gracefully
        return;
      }
      // Get first 8 bytes of device descriptor for control endpoint size
      TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n");
      TU_ASSERT(tuh_descriptor_get_device(0, _usbh_epbuf.ctrl, 8, process_enumeration, ENUM_SET_ADDR), );
      break;

    case ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY: {
      const uint8_t  new_addr = _usbh_data.enumerating_daddr;
      usbh_device_t *new_dev  = get_device(new_addr);
      TU_ASSERT(new_dev, );
      if (!usbh_edpt_control_open(new_addr, new_dev->desc_device.bMaxPacketSize0)) {
        TU_LOG_USBH("Failed to open new device's control endpoint\r\n");
        clear_device(new_dev);
        enum_full_complete(false);
        return;
      }
      TU_LOG_USBH("Get Device Descriptor\r\n");
      TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t), process_enumeration,
                                          ENUM_GET_STRING_LANGUAGE_ID_LEN), );
      break;
    }

    default:
      break;
  }
}

// start a new enumeration process
static void enum_new_device(hcd_event_t *event) {
  tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus;
  dev0_bus->rhport         = event->rhport;
  dev0_bus->hub_addr       = event->connection.hub_addr;
  dev0_bus->hub_port       = event->connection.hub_port;
  usbh_defer_func_ms_async(ENUM_DEBOUNCING_DELAY_MS, enum_delay_async, ENUM_AFTER_DEBOUNCING_DELAY);
}

// process device enumeration
static void process_enumeration(tuh_xfer_t *xfer) {
  if (XFER_RESULT_FAILED == xfer->result) {
    enum_full_complete(false); // failed to enum
    return;
  }

  const uint8_t   daddr    = xfer->daddr;
  const uintptr_t state    = xfer->user_data;
  usbh_device_t  *dev      = get_device(daddr);
  tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus;
  if (daddr > 0) {
    TU_ASSERT(dev != NULL,);
  }
  uint16_t langid = 0x0409; // default is English
  bool is_enum_failed = false;

  switch (state) {
  #if CFG_TUH_HUB
    case ENUM_HUB_RERSET: {
      hub_port_status_response_t port_status;
      hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status);

      if (0 == port_status.status.connection) {
        TU_LOG_USBH("Device unplugged from hub while debouncing\r\n");
        is_enum_failed = true;
      } else {
        TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration,
                                 ENUM_HUB_RESET_COMPLETE), );
      }
      break;
    }

    case ENUM_HUB_RESET_COMPLETE:
      // wait for reset to take effect
      usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY);
      break;

    case ENUM_HUB_CLEAR_RESET:
    case ENUM_HUB_CLEAR_RESET_RETRY: {
      hub_port_status_response_t port_status;
      hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status);

      if (1 == port_status.change.reset) {
        // Acknowledge Port Reset Change
        TU_ASSERT(hub_port_clear_reset_change(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration,
                                              ENUM_HUB_CLEAR_RESET_COMPLETE), );
      } else if (state == ENUM_HUB_CLEAR_RESET) {
        // retry one more time if reset change not set yet
        usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY_RETRY);
      } else {
        // retry but still not set --> failed
        is_enum_failed = true;
      }
      break;
    }

    case ENUM_HUB_CLEAR_RESET_COMPLETE: {
      hub_port_status_response_t port_status;
      hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status);

      if (0 == port_status.status.connection) {
        TU_LOG_USBH("Device unplugged from hub (not addressed yet)\r\n");
        is_enum_failed = true;
        break;
      }

      dev0_bus->speed = (port_status.status.high_speed)  ? TUSB_SPEED_HIGH
                        : (port_status.status.low_speed) ? TUSB_SPEED_LOW
                                                         : TUSB_SPEED_FULL;
      TU_ATTR_FALLTHROUGH;
    }
  #endif

    case ENUM_ADDR0_DEVICE_DESC:
      usbh_defer_func_ms_async(ENUM_RESET_RECOVERY_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_RECOVERY_DELAY);
      break;

    case ENUM_SET_ADDR: {
      const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl;
      if (!(desc_device->bDescriptorType == TUSB_DESC_DEVICE && desc_device->bMaxPacketSize0 >= 8)) {
        TU_LOG_USBH("Invalid Device descriptor\r\n");
        is_enum_failed = true;
        break;
      }

      const uint8_t new_addr = enum_get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB);
      TU_ASSERT(new_addr != 0,);

      usbh_device_t* new_dev = get_device(new_addr);
      new_dev->bus_info = *dev0_bus;
      new_dev->connected = 1;
      new_dev->desc_device.bMaxPacketSize0 = desc_device->bMaxPacketSize0;

      TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC), );
      break;
    }

    case ENUM_GET_DEVICE_DESC: {
      const uint8_t  new_addr = (uint8_t)tu_le16toh(xfer->setup->wValue);
      usbh_device_t *new_dev  = get_device(new_addr);
      TU_ASSERT(new_dev, );
      new_dev->addressed           = 1;
      _usbh_data.enumerating_daddr = new_addr;

      usbh_device_close(dev0_bus->rhport, 0); // close dev0
      usbh_defer_func_ms_async(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_delay_async, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY);
      break;
    }

    // For string descriptor (langid, manufacturer, product, serila): always get the first 2 bytes
    // to determine the length first. otherwise, some device may have buffer overflow.
    case ENUM_GET_STRING_LANGUAGE_ID_LEN: {
      // save the received device descriptor
      tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl;

      memcpy(&dev->desc_device, (const uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), sizeof(desc_device_noheader_t));

      tuh_enum_descriptor_device_cb(daddr, desc_device); // callback
      tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, 2,
                                       process_enumeration, ENUM_GET_STRING_LANGUAGE_ID);
      break;
    }

    case ENUM_GET_STRING_LANGUAGE_ID: {
      const uint8_t str_len = xfer->buffer[0];
      tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, str_len,
                                       process_enumeration, ENUM_GET_STRING_MANUFACTURER_LEN);
      break;
    }

    case ENUM_GET_STRING_MANUFACTURER_LEN: {
      const tusb_desc_string_t* desc_langid = (const tusb_desc_string_t *) _usbh_epbuf.ctrl;
      if (desc_langid->bLength >= 4) {
        langid = tu_le16toh(desc_langid->utf16le[0]); // previous request is langid
      }
      if (dev->desc_device.iManufacturer != 0) {
        tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, 2,
                                  process_enumeration, ENUM_GET_STRING_MANUFACTURER);
        break;
      }
      TU_ATTR_FALLTHROUGH;
    }

    case ENUM_GET_STRING_MANUFACTURER: {
      if (dev->desc_device.iManufacturer != 0)  {
        langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
        const uint8_t str_len = xfer->buffer[0];
        tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, str_len,
                                  process_enumeration, ENUM_GET_STRING_PRODUCT_LEN);
        break;
      }
      TU_ATTR_FALLTHROUGH;
    }

    case ENUM_GET_STRING_PRODUCT_LEN: {
      if (dev->desc_device.iProduct != 0) {
        if (state == ENUM_GET_STRING_PRODUCT_LEN) {
          langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through
        }
        tuh_descriptor_get_string(
            daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_PRODUCT);
        break;
      }
      TU_ATTR_FALLTHROUGH;
    }

    case ENUM_GET_STRING_PRODUCT: {
      if (dev->desc_device.iProduct != 0) {
        langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
        const uint8_t str_len = xfer->buffer[0];
        tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, str_len,
                            process_enumeration, ENUM_GET_STRING_SERIAL_LEN);
        break;
      }
      TU_ATTR_FALLTHROUGH;
    }

    case ENUM_GET_STRING_SERIAL_LEN: {
      if (dev->desc_device.iSerialNumber != 0) {
        if (state == ENUM_GET_STRING_SERIAL_LEN) {
          langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through
        }
        tuh_descriptor_get_string(
            daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_SERIAL);
        break;
      }
      TU_ATTR_FALLTHROUGH;
    }

    case ENUM_GET_STRING_SERIAL: {
      if (dev->desc_device.iSerialNumber != 0) {
        langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
        const uint8_t str_len = xfer->buffer[0];
        tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, str_len,
                                  process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC);
        break;
      }
      TU_ATTR_FALLTHROUGH;
    }

    case ENUM_GET_9BYTE_CONFIG_DESC: {
      // Get 9-byte for total length
      uint8_t const config_idx = 0;
      TU_LOG_USBH("Get Configuration[%u] Descriptor (9 bytes)\r\n", config_idx);
      TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, 9,
                                                 process_enumeration, ENUM_GET_FULL_CONFIG_DESC),);
      break;
    }

    case ENUM_GET_FULL_CONFIG_DESC: {
      uint8_t const* desc_config = _usbh_epbuf.ctrl;

      // Use offsetof to avoid pointer to the odd/misaligned address
      uint16_t const total_len = tu_le16toh(tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)));

      // TODO not enough buffer to hold configuration descriptor
      TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE,);

      // Get full configuration descriptor
      uint8_t const config_idx = (uint8_t) tu_le16toh(xfer->setup->wIndex);
      TU_LOG_USBH("Get Configuration[%u] Descriptor\r\n", config_idx);
      TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, total_len,
                                                 process_enumeration, ENUM_SET_CONFIG),);
      break;
    }

    case ENUM_SET_CONFIG: {
      uint8_t config_idx = (uint8_t) tu_le16toh(xfer->setup->wIndex);
      if (tuh_enum_descriptor_configuration_cb(daddr, config_idx, (const tusb_desc_configuration_t*) _usbh_epbuf.ctrl)) {
        TU_ASSERT(tuh_configuration_set(daddr, config_idx+1u, process_enumeration, ENUM_CONFIG_DRIVER),);
      } else {
        config_idx++;
        TU_ASSERT(config_idx < dev->desc_device.bNumConfigurations,);
        TU_LOG_USBH("Get Configuration[%u] Descriptor (9 bytes)\r\n", config_idx);
        TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, 9,
                                                   process_enumeration, ENUM_GET_FULL_CONFIG_DESC),);
      }
      break;
    }

    case ENUM_CONFIG_DRIVER: {
      TU_LOG_USBH("Device configured\r\n");
      dev->configured = 1;

  #if CFG_TUH_HUB
      // get next hub status now since device can be unplugged before set_configure() is complete
      if (_usbh_data.dev0_bus.hub_addr != 0) {
        hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr);
      }
  #endif

      // Parse configuration & set up drivers
      // driver_open() must not make any usb transfer
      TU_ASSERT(enum_parse_configuration_desc(daddr, (tusb_desc_configuration_t*) _usbh_epbuf.ctrl),);

      // Start the Set Configuration process for interfaces (itf = TUSB_INDEX_INVALID_8)
      // Since driver can perform control transfer within its set_config, this is done asynchronously.
      // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete()
      // TODO use separated API instead of using TUSB_INDEX_INVALID_8
      usbh_driver_set_config_complete(daddr, TUSB_INDEX_INVALID_8);
      break;
    }

    default:
      is_enum_failed = true;
      break;
  }

  if (is_enum_failed) {
    enum_full_complete(false);
  }
}

static uint8_t enum_get_new_address(bool is_hub) {
  uint8_t start;
  uint8_t end;

  if ( is_hub ) {
    start = CFG_TUH_DEVICE_MAX;
    end   = start + CFG_TUH_HUB;
  }else {
    start = 0;
    end   = start + CFG_TUH_DEVICE_MAX;
  }

  for (uint8_t idx = start; idx < end; idx++) {
    if (0 == _usbh_devices[idx].connected) {
      return (idx + 1);
    }
  }

#if CFG_TUH_HUB
  if ( is_hub ) {
    TU_LOG1("All addresses are occupied, try to increase CFG_TUH_HUB value.\r\n");
  }
#endif // CFG_TUH_HUB

  return 0; // invalid address
}

static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) {
  usbh_device_t* dev = get_device(dev_addr);
  uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength);
  uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len;
  uint8_t const* p_desc   = tu_desc_next(desc_cfg);

  TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len);

  // parse all interfaces
  while (tu_desc_in_bounds(p_desc, desc_end)) {
    if (0 == tu_desc_len(p_desc)) {
      // A zero-length descriptor indicates that the device is off spec (e.g. wrong wTotalLength).
      // Parsed interfaces should still be usable
      TU_LOG_USBH("Encountered a zero-length descriptor after %" PRIu32 " bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg);
      break;
    }

    // skip if not interface
    if (TUSB_DESC_INTERFACE != tu_desc_type(p_desc)) {
      p_desc = tu_desc_next(p_desc);
      continue;
    }
    const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc;

    // uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t)
    // (desc_end-p_desc)); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t));

    // Find a driver for this interface
    const uint16_t remaining_len = (uint16_t)(desc_end - p_desc);
    uint8_t        drv_id;
    for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
      const usbh_class_driver_t *driver = get_driver(drv_id);
      if (driver) {
        const uint16_t drv_len = driver->open(dev->bus_info.rhport, dev_addr, desc_itf, remaining_len);
        if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) {
          // open successfully
          TU_LOG_USBH("  %s opened\r\n", driver->name);

          // bind found driver to all interfaces and endpoint within drv_len
          tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, p_desc, drv_len);

          p_desc += drv_len; // next Interface
          break;             // exit driver find loop
        }
      }
    }

    // no driver found
    if (drv_id == TOTAL_DRIVER_COUNT) {
      p_desc = tu_desc_next(p_desc); // skip this interface
      TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
                  dev->bus_info.rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass,
                  desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol);
    }
  }

  return true;
}

void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) {
  usbh_device_t* dev = get_device(dev_addr);

  for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) {
    // continue with next valid interface
    // IAD binding interface such as CDCs should return itf_num + 1 when complete
    // with usbh_driver_set_config_complete()
    uint8_t const drv_id = dev->itf2drv[itf_num];
    usbh_class_driver_t const * driver = get_driver(drv_id);
    if (driver != NULL) {
      TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num);
      driver->set_config(dev_addr, itf_num);
      break;
    }
  }

  // all interfaces are configured
  if (itf_num == CFG_TUH_INTERFACE_MAX) {
    enum_full_complete(true);

    if (is_hub_addr(dev_addr)) {
      TU_LOG_USBH("HUB address = %u is mounted\r\n", dev_addr);
    }else {
      // Invoke callback if available
      tuh_mount_cb(dev_addr);
    }
  }
}

static void enum_full_complete(bool success) {
  (void)success;
  TU_LOG_USBH("Enumeration complete: success = %u\r\n", success);

  _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; // mark enumeration as complete
  _usbh_data.call_after.func = NULL;

  #if CFG_TUH_HUB
  // Hub status is already requested in case of successful enumeration
  if (!success && _usbh_data.dev0_bus.hub_addr != 0) {
    hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr);
  }
  #endif
}

#endif
