refactor(ext_hub): Pospone the device release, if device is not IDLE

This commit is contained in:
Roman Leonov
2025-05-15 11:08:57 +02:00
parent 754d357f18
commit fc61875a56
2 changed files with 34 additions and 19 deletions

View File

@ -312,13 +312,32 @@ static bool _device_set_actions(ext_hub_dev_t *ext_hub_dev, uint32_t action_flag
static esp_err_t device_enable_int_ep(ext_hub_dev_t *ext_hub_dev) static esp_err_t device_enable_int_ep(ext_hub_dev_t *ext_hub_dev)
{ {
ESP_LOGD(EXT_HUB_TAG, "[%d] Enable EP IN", ext_hub_dev->constant.dev_addr); bool call_proc_req_cb = false;
bool is_active = true;
ESP_LOGD(EXT_HUB_TAG, "[%d] Device ports handle complete", ext_hub_dev->constant.dev_addr);
// Check if the device should be released
EXT_HUB_ENTER_CRITICAL();
if (ext_hub_dev->dynamic.flags.waiting_release) {
is_active = false;
call_proc_req_cb = _device_set_actions(ext_hub_dev, DEV_ACTION_RELEASE);
}
EXT_HUB_EXIT_CRITICAL();
if (is_active) {
ESP_LOGD(EXT_HUB_TAG, "[%d] Enable IN EP", ext_hub_dev->constant.dev_addr);
esp_err_t ret = usbh_ep_enqueue_urb(ext_hub_dev->constant.ep_in_hdl, ext_hub_dev->constant.in_urb); esp_err_t ret = usbh_ep_enqueue_urb(ext_hub_dev->constant.ep_in_hdl, ext_hub_dev->constant.in_urb);
if (ret != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(EXT_HUB_TAG, "[%d] Failed to submit in urb: %s", ext_hub_dev->constant.dev_addr, esp_err_to_name(ret)); ESP_LOGE(EXT_HUB_TAG, "[%d] Failed to submit in urb: %s", ext_hub_dev->constant.dev_addr, esp_err_to_name(ret));
device_error(ext_hub_dev); device_error(ext_hub_dev);
} }
return ret; return ret;
}
if (call_proc_req_cb) {
p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg);
}
return ESP_OK;
} }
static void device_has_changed(ext_hub_dev_t *ext_hub_dev) static void device_has_changed(ext_hub_dev_t *ext_hub_dev)
@ -1396,10 +1415,9 @@ exit:
return ret; return ret;
} }
esp_err_t ext_hub_all_free(void) void ext_hub_mark_all_free(void)
{ {
bool call_proc_req_cb = false; bool call_proc_req_cb = false;
bool wait_for_free = false;
EXT_HUB_ENTER_CRITICAL(); EXT_HUB_ENTER_CRITICAL();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@ -1414,11 +1432,13 @@ esp_err_t ext_hub_all_free(void)
while (hub_curr != NULL) { while (hub_curr != NULL) {
hub_next = TAILQ_NEXT(hub_curr, dynamic.tailq_entry); hub_next = TAILQ_NEXT(hub_curr, dynamic.tailq_entry);
hub_curr->dynamic.flags.waiting_release = 1; hub_curr->dynamic.flags.waiting_release = 1;
call_proc_req_cb = _device_set_actions(hub_curr, DEV_ACTION_EP1_FLUSH | uint32_t action_flags = DEV_ACTION_EP1_FLUSH | DEV_ACTION_EP1_DEQUEUE;
DEV_ACTION_EP1_DEQUEUE | // If device in the IDLE stage, add the release action
DEV_ACTION_RELEASE); // otherwise, device will be released when the stage changed to IDLE
// At least one hub should be released if (hub_curr->single_thread.stage == EXT_HUB_STAGE_IDLE) {
wait_for_free = true; action_flags |= DEV_ACTION_RELEASE;
}
call_proc_req_cb = _device_set_actions(hub_curr, action_flags);
hub_curr = hub_next; hub_curr = hub_next;
} }
} }
@ -1427,8 +1447,6 @@ esp_err_t ext_hub_all_free(void)
if (call_proc_req_cb) { if (call_proc_req_cb) {
p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg); p_ext_hub_driver->constant.proc_req_cb(false, p_ext_hub_driver->constant.proc_req_cb_arg);
} }
return (wait_for_free) ? ESP_ERR_NOT_FINISHED : ESP_OK;
} }
esp_err_t ext_hub_status_handle_complete(ext_hub_handle_t ext_hub_hdl) esp_err_t ext_hub_status_handle_complete(ext_hub_handle_t ext_hub_hdl)

View File

@ -131,11 +131,8 @@ esp_err_t ext_hub_dev_gone(uint8_t dev_addr);
* Entry: * Entry:
* - should be called within Hub Driver when USB Host library need to be uninstalled * - should be called within Hub Driver when USB Host library need to be uninstalled
* *
* @return
* - ESP_OK: All devices freed
* - ESP_ERR_NOT_FINISHED: Operation not finished: devices waiting children to be freed.
*/ */
esp_err_t ext_hub_all_free(void); void ext_hub_mark_all_free(void);
/** /**
* @brief The External Hub or Ports statuses change completed * @brief The External Hub or Ports statuses change completed