Skip to content

Commit 0be1c7c

Browse files
committed
subsys: usb: host: support multiple devices under hub
When hub is used, need to consider about multiple devices are attached. Signed-off-by: Aiden Hu <[email protected]>
1 parent 3daddb8 commit 0be1c7c

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

subsys/usb/host/usbh_core.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,35 @@ static int usbh_event_carrier(const struct device *dev,
4646
static void dev_connected_handler(struct usbh_context *const ctx,
4747
const struct uhc_event *const event)
4848
{
49+
struct usb_device *udev;
4950

5051
LOG_DBG("Device connected event");
51-
if (ctx->root != NULL) {
52-
LOG_ERR("Device already connected");
53-
usbh_device_free(ctx->root);
54-
ctx->root = NULL;
55-
}
5652

57-
ctx->root = usbh_device_alloc(ctx);
58-
if (ctx->root == NULL) {
53+
udev = usbh_device_alloc(ctx);
54+
if (udev == NULL) {
5955
LOG_ERR("Failed allocate new device");
6056
return;
6157
}
6258

63-
ctx->root->state = USB_STATE_DEFAULT;
59+
udev->state = USB_STATE_DEFAULT;
6460

6561
if (event->type == UHC_EVT_DEV_CONNECTED_HS) {
66-
ctx->root->speed = USB_SPEED_SPEED_HS;
62+
udev->speed = USB_SPEED_SPEED_HS;
6763
} else {
68-
ctx->root->speed = USB_SPEED_SPEED_FS;
64+
udev->speed = USB_SPEED_SPEED_FS;
65+
}
66+
67+
k_mutex_lock(&ctx->mutex, K_FOREVER);
68+
sys_dlist_append(&ctx->udevs, &udev->node);
69+
70+
if (ctx->root == NULL) {
71+
ctx->root = udev;
6972
}
73+
k_mutex_unlock(&ctx->mutex);
7074

71-
if (usbh_device_init(ctx->root)) {
75+
if (usbh_device_init(udev)) {
7276
LOG_ERR("Failed to reset new USB device");
77+
sys_dlist_remove(&udev->node);
7378
}
7479
}
7580

subsys/usb/host/usbh_device.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ int usbh_device_init(struct usb_device *const udev)
452452
struct usbh_context *const uhs_ctx = udev->ctx;
453453
uint8_t new_addr;
454454
int err;
455+
sys_dnode_t *node;
456+
uint8_t device_count = 0;
455457

456458
if (udev->state != USB_STATE_DEFAULT) {
457459
LOG_ERR("USB device is not in default state");
@@ -464,11 +466,19 @@ int usbh_device_init(struct usb_device *const udev)
464466
return err;
465467
}
466468

467-
/* FIXME: The port to which the device is connected should be reset. */
468-
err = uhc_bus_reset(uhs_ctx->dev);
469-
if (err) {
470-
LOG_ERR("Failed to signal bus reset");
471-
return err;
469+
k_mutex_lock(&uhs_ctx->mutex, K_FOREVER);
470+
SYS_DLIST_FOR_EACH_NODE(&uhs_ctx->udevs, node) {
471+
device_count++;
472+
}
473+
k_mutex_unlock(&uhs_ctx->mutex);
474+
475+
/* Only reset bus if this is the root device. */
476+
if (device_count == 1U) {
477+
err = uhc_bus_reset(uhs_ctx->dev);
478+
if (err) {
479+
LOG_ERR("Failed to signal bus reset");
480+
return err;
481+
}
472482
}
473483

474484
/*

0 commit comments

Comments
 (0)