Skip to content

Commit c004b93

Browse files
committed
Merge branch 'feature/usb_host_usbh_uid_presence_in_list' into 'master'
feature(usbh): Added uid presence check in USBH device object list Closes IDF-10022 See merge request espressif/esp-idf!36705
2 parents 6b1d8db + 46952c6 commit c004b93

File tree

3 files changed

+46
-30
lines changed

3 files changed

+46
-30
lines changed

components/usb/hub.c

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -28,7 +28,6 @@ implement the bare minimum to control the root HCD port.
2828
*/
2929

3030
#define HUB_ROOT_PORT_NUM 1 // HCD only supports one port
31-
#define HUB_ROOT_DEV_UID 1 // Unique device ID
3231

3332
#ifdef CONFIG_USB_HOST_HW_BUFFER_BIAS_IN
3433
#define HUB_ROOT_HCD_PORT_FIFO_BIAS HCD_PORT_FIFO_BIAS_RX
@@ -93,7 +92,6 @@ typedef struct {
9392

9493
struct {
9594
TAILQ_HEAD(tailhead_devs, dev_tree_node_s) dev_nodes_tailq; /**< Tailq of attached devices */
96-
unsigned int next_uid; /**< Unique ID for next upcoming device */
9795
} single_thread; /**< Single thread members don't require a critical section so long as they are never accessed from multiple threads */
9896

9997
struct {
@@ -153,53 +151,52 @@ static bool root_port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port
153151
*
154152
* @return esp_err_t
155153
*/
156-
static esp_err_t new_dev_tree_node(usb_device_handle_t parent_dev_hdl, uint8_t parent_port_num, usb_speed_t speed)
154+
static esp_err_t dev_tree_node_new(usb_device_handle_t parent_dev_hdl, uint8_t parent_port_num, usb_speed_t speed)
157155
{
158156
esp_err_t ret;
159-
unsigned int node_uid = p_hub_driver_obj->single_thread.next_uid;
160-
157+
// Allocate memory for a new device tree node
161158
dev_tree_node_t *dev_tree_node = heap_caps_calloc(1, sizeof(dev_tree_node_t), MALLOC_CAP_DEFAULT);
162159
if (dev_tree_node == NULL) {
163160
return ESP_ERR_NO_MEM;
164161
}
162+
// Assign initial UID based on the current number of registered devices
163+
int device_num = 0;
164+
ESP_ERROR_CHECK(usbh_devs_num(&device_num));
165+
dev_tree_node->uid = device_num + 1;
166+
// Ensure the UID is unique
167+
while (usbh_devs_is_uid_in_use(dev_tree_node->uid)) {
168+
dev_tree_node->uid++;
169+
assert(dev_tree_node->uid != 0); // No overflow possible
170+
}
171+
172+
dev_tree_node->parent_dev_hdl = parent_dev_hdl;
173+
dev_tree_node->parent_port_num = parent_port_num;
165174

166-
// Allocate a new USBH device
175+
// Initialize and register a new USBH Device with the assigned UID
167176
usbh_dev_params_t params = {
168-
.uid = node_uid,
177+
.uid = dev_tree_node->uid,
169178
.speed = speed,
170179
.root_port_hdl = p_hub_driver_obj->constant.root_port_hdl, // Always the same for all devices
171-
// TODO: IDF-10023 Move responsibility of parent-child tree building to Hub Driver instead of USBH
180+
// TODO: IDF-10023 Move parent-child tree management responsibility to Hub Driver
172181
.parent_dev_hdl = parent_dev_hdl,
173182
.parent_port_num = parent_port_num,
174183
};
175184

176185
ret = usbh_devs_add(&params);
177186
if (ret != ESP_OK) {
178-
// USBH devs add could failed due to lack of free hcd channels
179-
// TODO: IDF-10044 Hub should recover after running out of hcd channels
187+
// Device registration may fail if there are no available HCD channels.
188+
// TODO: IDF-10044 Implement hub recovery mechanism for running out of HCD channels.
180189
goto fail;
181190
}
182191

183-
dev_tree_node->uid = node_uid;
184-
dev_tree_node->parent_dev_hdl = parent_dev_hdl;
185-
dev_tree_node->parent_port_num = parent_port_num;
186192
TAILQ_INSERT_TAIL(&p_hub_driver_obj->single_thread.dev_nodes_tailq, dev_tree_node, tailq_entry);
187193

188-
p_hub_driver_obj->single_thread.next_uid++;
189-
if (p_hub_driver_obj->single_thread.next_uid == 0) {
190-
ESP_LOGW(HUB_DRIVER_TAG, "Counter overflowed, possibility of uid collisions");
191-
p_hub_driver_obj->single_thread.next_uid = HUB_ROOT_DEV_UID;
192-
}
193-
// Verify presence of a device with newly prepared uid in USBH
194-
// TODO: IDF-10022 Provide a mechanism to request presence status of a device with uid in USBH device object list
195-
// Return if device uid is not in USBH device object list, repeat until uid will be founded
196-
197-
ESP_LOGD(HUB_DRIVER_TAG, "Device tree node (uid=%d): new", node_uid);
194+
ESP_LOGD(HUB_DRIVER_TAG, "Device tree node (uid=%d): new", dev_tree_node->uid);
198195

199196
hub_event_data_t event_data = {
200197
.event = HUB_EVENT_CONNECTED,
201198
.connected = {
202-
.uid = node_uid,
199+
.uid = dev_tree_node->uid,
203200
},
204201
};
205202
p_hub_driver_obj->constant.event_cb(&event_data, p_hub_driver_obj->constant.event_cb_arg);
@@ -364,7 +361,7 @@ static void ext_port_event_callback(ext_port_event_data_t *event_data, void *arg
364361
}
365362
#endif // CONFIG_USB_HOST_EXT_PORT_SUPPORT_LS
366363

367-
if (new_dev_tree_node(event_data->connected.parent_dev_hdl, event_data->connected.parent_port_num, port_speed) != ESP_OK) {
364+
if (dev_tree_node_new(event_data->connected.parent_dev_hdl, event_data->connected.parent_port_num, port_speed) != ESP_OK) {
368365
ESP_LOGE(HUB_DRIVER_TAG, "Failed to add new downstream device");
369366
goto new_ds_dev_err;
370367
}
@@ -406,7 +403,7 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl)
406403
goto new_dev_err;
407404
}
408405

409-
if (new_dev_tree_node(NULL, 0, speed) != ESP_OK) {
406+
if (dev_tree_node_new(NULL, 0, speed) != ESP_OK) {
410407
ESP_LOGE(HUB_DRIVER_TAG, "Failed to add new device");
411408
goto new_dev_err;
412409
}
@@ -589,7 +586,6 @@ esp_err_t hub_install(hub_config_t *hub_config, void **client_ret)
589586
hub_driver_obj->constant.proc_req_cb_arg = hub_config->proc_req_cb_arg;
590587
hub_driver_obj->constant.event_cb = hub_config->event_cb;
591588
hub_driver_obj->constant.event_cb_arg = hub_config->event_cb_arg;
592-
hub_driver_obj->single_thread.next_uid = HUB_ROOT_DEV_UID;
593589
TAILQ_INIT(&hub_driver_obj->single_thread.dev_nodes_tailq);
594590
// Driver is not installed, we can modify dynamic section outside of the critical section
595591
hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_NOT_POWERED;

components/usb/private_include/usbh.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -194,6 +194,18 @@ esp_err_t usbh_uninstall(void);
194194
esp_err_t usbh_process(void);
195195

196196
// ---------------------- Device Pool Functions --------------------------------
197+
/**
198+
* @brief Determines whether a UID is currently assigned in the USBH device list
199+
*
200+
* @note This function may block execution while checking the device list.
201+
*
202+
* @param[in] uid Unique ID to check
203+
*
204+
* @return
205+
* - true if UID is already in use.
206+
* - false if UID is available for assignment.
207+
*/
208+
bool usbh_devs_is_uid_in_use(uint32_t uid);
197209

198210
/**
199211
* @brief Get the current number of devices

components/usb/usbh.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -781,6 +781,14 @@ esp_err_t usbh_process(void)
781781
// -----------------------------------------------------------------------------
782782
// ------------------------- Device Pool Functions -----------------------------
783783
// -----------------------------------------------------------------------------
784+
bool usbh_devs_is_uid_in_use(uint32_t uid)
785+
{
786+
bool uid_in_use;
787+
USBH_ENTER_CRITICAL();
788+
uid_in_use = (_find_dev_from_uid(uid) != NULL); // Check if UID exists
789+
USBH_EXIT_CRITICAL();
790+
return uid_in_use;
791+
}
784792

785793
esp_err_t usbh_devs_num(int *num_devs_ret)
786794
{

0 commit comments

Comments
 (0)