Skip to content

Commit 091e8b6

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 091e8b6

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

subsys/usb/host/usbh_core.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,38 @@ static int usbh_event_carrier(const struct device *dev,
4242

4343
return err;
4444
}
45-
4645
static void dev_connected_handler(struct usbh_context *const ctx,
4746
const struct uhc_event *const event)
4847
{
48+
struct usb_device *udev;
4949

5050
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-
}
5651

57-
ctx->root = usbh_device_alloc(ctx);
58-
if (ctx->root == NULL) {
52+
udev = usbh_device_alloc(ctx);
53+
if (udev == NULL) {
5954
LOG_ERR("Failed allocate new device");
6055
return;
6156
}
6257

63-
ctx->root->state = USB_STATE_DEFAULT;
58+
udev->state = USB_STATE_DEFAULT;
6459

6560
if (event->type == UHC_EVT_DEV_CONNECTED_HS) {
66-
ctx->root->speed = USB_SPEED_SPEED_HS;
61+
udev->speed = USB_SPEED_SPEED_HS;
6762
} else {
68-
ctx->root->speed = USB_SPEED_SPEED_FS;
63+
udev->speed = USB_SPEED_SPEED_FS;
64+
}
65+
66+
k_mutex_lock(&ctx->mutex, K_FOREVER);
67+
sys_dlist_append(&ctx->udevs, &udev->node);
68+
69+
if (ctx->root == NULL) {
70+
ctx->root = udev;
6971
}
72+
k_mutex_unlock(&ctx->mutex);
7073

71-
if (usbh_device_init(ctx->root)) {
74+
if (usbh_device_init(udev)) {
7275
LOG_ERR("Failed to reset new USB device");
76+
sys_dlist_remove(&udev->node);
7377
}
7478
}
7579

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)