From 0054ae9fd751ee86bc977de14ac57e4f2b74d7b2 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Sat, 9 Aug 2025 16:24:17 +0000 Subject: [PATCH 1/4] usb: host: rename "struct usbh_contex" to "usbh_context" Make the struct name match the device naming for ease of use, although slightly longer name. Propagate the change to the subsystem, includes, tests and samples. Signed-off-by: Josuah Demangeon --- include/zephyr/usb/usbh.h | 26 +++++++++++++------------- subsys/usb/host/usbh_api.c | 8 ++++---- subsys/usb/host/usbh_core.c | 14 +++++++------- subsys/usb/host/usbh_data.ld | 2 +- subsys/usb/host/usbh_device.c | 12 ++++++------ subsys/usb/host/usbh_device.h | 20 ++++++++++---------- subsys/usb/host/usbh_internal.h | 2 +- subsys/usb/host/usbip.c | 2 +- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/include/zephyr/usb/usbh.h b/include/zephyr/usb/usbh.h index 852d8b9ac6986..e2e6f3074000e 100644 --- a/include/zephyr/usb/usbh.h +++ b/include/zephyr/usb/usbh.h @@ -36,7 +36,7 @@ extern "C" { /** * USB host support runtime context */ -struct usbh_contex { +struct usbh_context { /** Name of the USB device */ const char *name; /** Access mutex */ @@ -53,7 +53,7 @@ struct usbh_contex { #define USBH_CONTROLLER_DEFINE(device_name, uhc_dev) \ SYS_BITARRAY_DEFINE_STATIC(ba_##device_name, 128); \ - static STRUCT_SECTION_ITERABLE(usbh_contex, device_name) = { \ + static STRUCT_SECTION_ITERABLE(usbh_context, device_name) = { \ .name = STRINGIFY(device_name), \ .mutex = Z_MUTEX_INITIALIZER(device_name.mutex), \ .dev = uhc_dev, \ @@ -80,20 +80,20 @@ struct usbh_class_data { struct usbh_code_triple code; /** Initialization of the class implementation */ - /* int (*init)(struct usbh_contex *const uhs_ctx); */ + /* int (*init)(struct usbh_context *const uhs_ctx); */ /** Request completion event handler */ - int (*request)(struct usbh_contex *const uhs_ctx, + int (*request)(struct usbh_context *const uhs_ctx, struct uhc_transfer *const xfer, int err); /** Device connected handler */ - int (*connected)(struct usbh_contex *const uhs_ctx); + int (*connected)(struct usbh_context *const uhs_ctx); /** Device removed handler */ - int (*removed)(struct usbh_contex *const uhs_ctx); + int (*removed)(struct usbh_context *const uhs_ctx); /** Bus remote wakeup handler */ - int (*rwup)(struct usbh_contex *const uhs_ctx); + int (*rwup)(struct usbh_context *const uhs_ctx); /** Bus suspended handler */ - int (*suspended)(struct usbh_contex *const uhs_ctx); + int (*suspended)(struct usbh_context *const uhs_ctx); /** Bus resumed handler */ - int (*resumed)(struct usbh_contex *const uhs_ctx); + int (*resumed)(struct usbh_context *const uhs_ctx); }; /** @@ -109,7 +109,7 @@ struct usbh_class_data { * * @return 0 on success, other values on fail. */ -int usbh_init(struct usbh_contex *uhs_ctx); +int usbh_init(struct usbh_context *uhs_ctx); /** * @brief Enable the USB host support and class instances @@ -120,7 +120,7 @@ int usbh_init(struct usbh_contex *uhs_ctx); * * @return 0 on success, other values on fail. */ -int usbh_enable(struct usbh_contex *uhs_ctx); +int usbh_enable(struct usbh_context *uhs_ctx); /** * @brief Disable the USB host support @@ -131,7 +131,7 @@ int usbh_enable(struct usbh_contex *uhs_ctx); * * @return 0 on success, other values on fail. */ -int usbh_disable(struct usbh_contex *uhs_ctx); +int usbh_disable(struct usbh_context *uhs_ctx); /** * @brief Shutdown the USB host support @@ -142,7 +142,7 @@ int usbh_disable(struct usbh_contex *uhs_ctx); * * @return 0 on success, other values on fail. */ -int usbh_shutdown(struct usbh_contex *const uhs_ctx); +int usbh_shutdown(struct usbh_context *const uhs_ctx); /** * @} diff --git a/subsys/usb/host/usbh_api.c b/subsys/usb/host/usbh_api.c index e1aa6e99ac3b9..8fc1a1869deb2 100644 --- a/subsys/usb/host/usbh_api.c +++ b/subsys/usb/host/usbh_api.c @@ -11,7 +11,7 @@ #include LOG_MODULE_REGISTER(uhs_api, CONFIG_USBH_LOG_LEVEL); -int usbh_init(struct usbh_contex *uhs_ctx) +int usbh_init(struct usbh_context *uhs_ctx) { int ret; @@ -36,7 +36,7 @@ int usbh_init(struct usbh_contex *uhs_ctx) return ret; } -int usbh_enable(struct usbh_contex *uhs_ctx) +int usbh_enable(struct usbh_context *uhs_ctx) { int ret; @@ -65,7 +65,7 @@ int usbh_enable(struct usbh_contex *uhs_ctx) return ret; } -int usbh_disable(struct usbh_contex *uhs_ctx) +int usbh_disable(struct usbh_context *uhs_ctx) { int ret; @@ -86,7 +86,7 @@ int usbh_disable(struct usbh_contex *uhs_ctx) return 0; } -int usbh_shutdown(struct usbh_contex *const uhs_ctx) +int usbh_shutdown(struct usbh_context *const uhs_ctx) { int ret; diff --git a/subsys/usb/host/usbh_core.c b/subsys/usb/host/usbh_core.c index c18ef39cb63cf..1b654b5041133 100644 --- a/subsys/usb/host/usbh_core.c +++ b/subsys/usb/host/usbh_core.c @@ -43,7 +43,7 @@ static int usbh_event_carrier(const struct device *dev, return err; } -static void dev_connected_handler(struct usbh_contex *const ctx, +static void dev_connected_handler(struct usbh_context *const ctx, const struct uhc_event *const event) { @@ -73,7 +73,7 @@ static void dev_connected_handler(struct usbh_contex *const ctx, } } -static void dev_removed_handler(struct usbh_contex *const ctx) +static void dev_removed_handler(struct usbh_context *const ctx) { if (ctx->root != NULL) { usbh_device_free(ctx->root); @@ -84,7 +84,7 @@ static void dev_removed_handler(struct usbh_contex *const ctx) } } -static int discard_ep_request(struct usbh_contex *const ctx, +static int discard_ep_request(struct usbh_context *const ctx, struct uhc_transfer *const xfer) { const struct device *dev = ctx->dev; @@ -97,7 +97,7 @@ static int discard_ep_request(struct usbh_contex *const ctx, return uhc_xfer_free(dev, xfer); } -static ALWAYS_INLINE int usbh_event_handler(struct usbh_contex *const ctx, +static ALWAYS_INLINE int usbh_event_handler(struct usbh_context *const ctx, struct uhc_event *const event) { int ret = 0; @@ -141,7 +141,7 @@ static void usbh_bus_thread(void *p1, void *p2, void *p3) ARG_UNUSED(p2); ARG_UNUSED(p3); - struct usbh_contex *uhs_ctx; + struct usbh_context *uhs_ctx; struct uhc_event event; while (true) { @@ -158,7 +158,7 @@ static void usbh_thread(void *p1, void *p2, void *p3) ARG_UNUSED(p2); ARG_UNUSED(p3); - struct usbh_contex *uhs_ctx; + struct usbh_context *uhs_ctx; struct uhc_event event; usbh_udev_cb_t cb; int ret; @@ -182,7 +182,7 @@ static void usbh_thread(void *p1, void *p2, void *p3) } } -int usbh_init_device_intl(struct usbh_contex *const uhs_ctx) +int usbh_init_device_intl(struct usbh_context *const uhs_ctx) { int ret; diff --git a/subsys/usb/host/usbh_data.ld b/subsys/usb/host/usbh_data.ld index 193c63efc0ed2..4363154f29474 100644 --- a/subsys/usb/host/usbh_data.ld +++ b/subsys/usb/host/usbh_data.ld @@ -1,4 +1,4 @@ #include -ITERABLE_SECTION_RAM(usbh_contex, Z_LINK_ITERABLE_SUBALIGN) +ITERABLE_SECTION_RAM(usbh_context, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(usbh_class_data, Z_LINK_ITERABLE_SUBALIGN) diff --git a/subsys/usb/host/usbh_device.c b/subsys/usb/host/usbh_device.c index 13a2a81ccd2c1..99970ffb0c4ed 100644 --- a/subsys/usb/host/usbh_device.c +++ b/subsys/usb/host/usbh_device.c @@ -18,7 +18,7 @@ K_MEM_SLAB_DEFINE_STATIC(usb_device_slab, sizeof(struct usb_device), K_HEAP_DEFINE(usb_device_heap, CONFIG_USBH_USB_DEVICE_HEAP); -struct usb_device *usbh_device_alloc(struct usbh_contex *const uhs_ctx) +struct usb_device *usbh_device_alloc(struct usbh_context *const uhs_ctx) { struct usb_device *udev; @@ -37,7 +37,7 @@ struct usb_device *usbh_device_alloc(struct usbh_contex *const uhs_ctx) void usbh_device_free(struct usb_device *const udev) { - struct usbh_contex *const uhs_ctx = udev->ctx; + struct usbh_context *const uhs_ctx = udev->ctx; sys_bitarray_clear_bit(uhs_ctx->addr_ba, udev->addr); sys_dlist_remove(&udev->node); @@ -48,7 +48,7 @@ void usbh_device_free(struct usb_device *const udev) k_mem_slab_free(&usb_device_slab, (void *)udev); } -struct usb_device *usbh_device_get_any(struct usbh_contex *const uhs_ctx) +struct usb_device *usbh_device_get_any(struct usbh_context *const uhs_ctx) { sys_dnode_t *const node = sys_dlist_peek_head(&uhs_ctx->udevs); struct usb_device *udev; @@ -58,7 +58,7 @@ struct usb_device *usbh_device_get_any(struct usbh_contex *const uhs_ctx) return udev; } -struct usb_device *usbh_device_get(struct usbh_contex *const uhs_ctx, const uint8_t addr) +struct usb_device *usbh_device_get(struct usbh_context *const uhs_ctx, const uint8_t addr) { struct usb_device *udev; @@ -99,7 +99,7 @@ static int validate_device_mps0(const struct usb_device *const udev) static int alloc_device_address(struct usb_device *const udev, uint8_t *const addr) { - struct usbh_contex *const uhs_ctx = udev->ctx; + struct usbh_context *const uhs_ctx = udev->ctx; int val; int err; @@ -449,7 +449,7 @@ int usbh_device_set_configuration(struct usb_device *const udev, const uint8_t n int usbh_device_init(struct usb_device *const udev) { - struct usbh_contex *const uhs_ctx = udev->ctx; + struct usbh_context *const uhs_ctx = udev->ctx; uint8_t new_addr; int err; diff --git a/subsys/usb/host/usbh_device.h b/subsys/usb/host/usbh_device.h index 19613bda3bfa4..5c5637fb0bee8 100644 --- a/subsys/usb/host/usbh_device.h +++ b/subsys/usb/host/usbh_device.h @@ -20,12 +20,12 @@ typedef int (*usbh_udev_cb_t)(struct usb_device *const udev, * connection without hub support, this is the device connected directly to the * host controller. */ -struct usb_device *usbh_device_get_any(struct usbh_contex *const ctx); +struct usb_device *usbh_device_get_any(struct usbh_context *const ctx); -struct usb_device *usbh_device_get(struct usbh_contex *const uhs_ctx, const uint8_t addr); +struct usb_device *usbh_device_get(struct usbh_context *const uhs_ctx, const uint8_t addr); /* Allocate/free USB device */ -struct usb_device *usbh_device_alloc(struct usbh_contex *const uhs_ctx); +struct usb_device *usbh_device_alloc(struct usbh_context *const uhs_ctx); void usbh_device_free(struct usb_device *const udev); /* Reset and configure new USB device */ @@ -42,7 +42,7 @@ static inline struct uhc_transfer *usbh_xfer_alloc(struct usb_device *udev, usbh_udev_cb_t cb, void *const cb_priv) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; return uhc_xfer_alloc(ctx->dev, ep, udev, cb, cb_priv); } @@ -51,7 +51,7 @@ static inline int usbh_xfer_buf_add(const struct usb_device *udev, struct uhc_transfer *const xfer, struct net_buf *buf) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; return uhc_xfer_buf_add(ctx->dev, xfer, buf); } @@ -59,7 +59,7 @@ static inline int usbh_xfer_buf_add(const struct usb_device *udev, static inline struct net_buf *usbh_xfer_buf_alloc(struct usb_device *udev, const size_t size) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; return uhc_xfer_buf_alloc(ctx->dev, size); } @@ -67,7 +67,7 @@ static inline struct net_buf *usbh_xfer_buf_alloc(struct usb_device *udev, static inline int usbh_xfer_free(const struct usb_device *udev, struct uhc_transfer *const xfer) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; return uhc_xfer_free(ctx->dev, xfer); } @@ -75,7 +75,7 @@ static inline int usbh_xfer_free(const struct usb_device *udev, static inline void usbh_xfer_buf_free(const struct usb_device *udev, struct net_buf *const buf) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; uhc_xfer_buf_free(ctx->dev, buf); } @@ -83,7 +83,7 @@ static inline void usbh_xfer_buf_free(const struct usb_device *udev, static inline int usbh_xfer_enqueue(const struct usb_device *udev, struct uhc_transfer *const xfer) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; return uhc_ep_enqueue(ctx->dev, xfer); } @@ -91,7 +91,7 @@ static inline int usbh_xfer_enqueue(const struct usb_device *udev, static inline int usbh_xfer_dequeue(const struct usb_device *udev, struct uhc_transfer *const xfer) { - struct usbh_contex *const ctx = udev->ctx; + struct usbh_context *const ctx = udev->ctx; return uhc_ep_dequeue(ctx->dev, xfer); } diff --git a/subsys/usb/host/usbh_internal.h b/subsys/usb/host/usbh_internal.h index c731520118ed2..8fa8e7d48e19c 100644 --- a/subsys/usb/host/usbh_internal.h +++ b/subsys/usb/host/usbh_internal.h @@ -10,6 +10,6 @@ #include #include -int usbh_init_device_intl(struct usbh_contex *const uhs_ctx); +int usbh_init_device_intl(struct usbh_context *const uhs_ctx); #endif /* ZEPHYR_INCLUDE_USBH_INTERNAL_H */ diff --git a/subsys/usb/host/usbip.c b/subsys/usb/host/usbip.c index 773acbb55d32e..385f763463cdd 100644 --- a/subsys/usb/host/usbip.c +++ b/subsys/usb/host/usbip.c @@ -48,7 +48,7 @@ struct usbip_dev_ctx { /* Context of the exported bus (not really used yet) */ struct usbip_bus_ctx { - struct usbh_contex *uhs_ctx; + struct usbh_context *uhs_ctx; struct usbip_dev_ctx devs[CONFIG_USBIP_DEVICES_COUNT]; uint8_t busnum; }; From 9f1d92ad3519b90f5bd147bac2eb8b656d54d569 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Sat, 26 Jul 2025 15:42:36 +0000 Subject: [PATCH 2/4] usb: host: check that descriptor is in bound before dereferencing In the while loop parsing descriptors, check that the descriptor is past the end just before dereferencing it to check if it is seemingly valid. Signed-off-by: Josuah Demangeon --- subsys/usb/host/usbh_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/usb/host/usbh_device.c b/subsys/usb/host/usbh_device.c index 99970ffb0c4ed..92ecf6ae7aee1 100644 --- a/subsys/usb/host/usbh_device.c +++ b/subsys/usb/host/usbh_device.c @@ -285,7 +285,7 @@ static int parse_configuration_descriptor(struct usb_device *const udev) dhp = (void *)((uint8_t *)udev->cfg_desc + cfg_desc->bLength); desc_end = (void *)((uint8_t *)udev->cfg_desc + cfg_desc->wTotalLength); - while ((dhp->bDescriptorType != 0 || dhp->bLength != 0) && (void *)dhp < desc_end) { + while ((void *)dhp < desc_end && (dhp->bDescriptorType != 0 || dhp->bLength != 0)) { if (dhp->bDescriptorType == USB_DESC_INTERFACE_ASSOC) { iad = (struct usb_association_descriptor *)dhp; LOG_DBG("bFirstInterface %u", iad->bFirstInterface); From c042ba0525bc4ffee768341c9c0d9acc9f88c17e Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Fri, 8 Aug 2025 21:00:09 +0000 Subject: [PATCH 3/4] usb: host: wrap the mutex lock with a helper Hide the mutex lock details inside a wrapper call, like done for the device stack API. This is not used for the per-device lock of the host stack which use a different mutex lock. Signed-off-by: Josuah Demangeon --- subsys/usb/host/usbh_api.c | 17 +++++++++-------- subsys/usb/host/usbh_host.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 subsys/usb/host/usbh_host.h diff --git a/subsys/usb/host/usbh_api.c b/subsys/usb/host/usbh_api.c index 8fc1a1869deb2..8501ee044b2ad 100644 --- a/subsys/usb/host/usbh_api.c +++ b/subsys/usb/host/usbh_api.c @@ -6,6 +6,7 @@ #include #include +#include "usbh_host.h" #include "usbh_internal.h" #include @@ -15,7 +16,7 @@ int usbh_init(struct usbh_context *uhs_ctx) { int ret; - k_mutex_lock(&uhs_ctx->mutex, K_FOREVER); + usbh_host_lock(uhs_ctx); if (!device_is_ready(uhs_ctx->dev)) { LOG_ERR("USB host controller is not ready"); @@ -32,7 +33,7 @@ int usbh_init(struct usbh_context *uhs_ctx) ret = usbh_init_device_intl(uhs_ctx); init_exit: - k_mutex_unlock(&uhs_ctx->mutex); + usbh_host_unlock(uhs_ctx); return ret; } @@ -40,7 +41,7 @@ int usbh_enable(struct usbh_context *uhs_ctx) { int ret; - k_mutex_lock(&uhs_ctx->mutex, K_FOREVER); + usbh_host_lock(uhs_ctx); if (!uhc_is_initialized(uhs_ctx->dev)) { LOG_WRN("USB host controller is not initialized"); @@ -61,7 +62,7 @@ int usbh_enable(struct usbh_context *uhs_ctx) } enable_exit: - k_mutex_unlock(&uhs_ctx->mutex); + usbh_host_unlock(uhs_ctx); return ret; } @@ -74,14 +75,14 @@ int usbh_disable(struct usbh_context *uhs_ctx) return 0; } - k_mutex_lock(&uhs_ctx->mutex, K_FOREVER); + usbh_host_lock(uhs_ctx); ret = uhc_disable(uhs_ctx->dev); if (ret) { LOG_ERR("Failed to disable USB controller"); } - k_mutex_unlock(&uhs_ctx->mutex); + usbh_host_unlock(uhs_ctx); return 0; } @@ -90,14 +91,14 @@ int usbh_shutdown(struct usbh_context *const uhs_ctx) { int ret; - k_mutex_lock(&uhs_ctx->mutex, K_FOREVER); + usbh_host_lock(uhs_ctx); ret = uhc_shutdown(uhs_ctx->dev); if (ret) { LOG_ERR("Failed to shutdown USB device"); } - k_mutex_unlock(&uhs_ctx->mutex); + usbh_host_unlock(uhs_ctx); return ret; } diff --git a/subsys/usb/host/usbh_host.h b/subsys/usb/host/usbh_host.h new file mode 100644 index 0000000000000..1f04a72cdd019 --- /dev/null +++ b/subsys/usb/host/usbh_host.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_USBH_HOST_H +#define ZEPHYR_INCLUDE_USBH_HOST_H + +#include +#include + +/** + * @brief Lock the USB host stack context + * + * @param[in] uhs_ctx Pointer to a host context + */ +static inline void usbh_host_lock(struct usbh_context *const uhs_ctx) +{ + k_mutex_lock(&uhs_ctx->mutex, K_FOREVER); +} + +/** + * @brief Unlock the USB host stack context + * + * @param[in] uhs_ctx Pointer to a host context + */ +static inline void usbh_host_unlock(struct usbh_context *const uhs_ctx) +{ + k_mutex_unlock(&uhs_ctx->mutex); +} + +#endif /* ZEPHYR_INCLUDE_USBH_HOST_H */ From 8a40c808782ef8ef0ea62fd88335a0967e2d6bb0 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Thu, 14 Aug 2025 09:24:16 +0000 Subject: [PATCH 4/4] samples: usb: shell: update the output in the README Update the USB shell sample to the new syntax. This is based on tests done with native_sim, along with the virtual.conf, virtual.overlay and device_and_host_prj.conf extra config files. Signed-off-by: Josuah Demangeon --- samples/subsys/usb/shell/README.rst | 50 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/samples/subsys/usb/shell/README.rst b/samples/subsys/usb/shell/README.rst index 5e5437b56dc35..5fb42f2c3095e 100644 --- a/samples/subsys/usb/shell/README.rst +++ b/samples/subsys/usb/shell/README.rst @@ -50,37 +50,37 @@ Sample shell interaction .. code-block:: console - uart:~$ usbd defaults - dev: USB descriptors initialized - uart:~$ usbd config add 1 - uart:~$ usbd class add foobaz 1 - dev: added USB class foobaz to configuration 1 - uart:~$ usbd init + *** Booting Zephyr OS build v4.2.0-1588-g83f1bd7341de *** + uart:~$ usbd defcfg + dev: added default string descriptors + dev: register FS loopback_0 + dev: register HS loopback_0 dev: USB initialized uart:~$ usbh init host: USB host initialized uart:~$ usbh enable host: USB host enabled - [611:00:28.620,000] usbd_core: VBUS detected event uart:~$ usbh bus resume host: USB bus resumed uart:~$ usbd enable - host: USB device connected dev: USB enabled - uart:~$ usbh device descriptor device 0 - host: transfer finished 0x20006250, err 0 - 00000000: 80 06 00 01 00 00 12 00 |........ | - bLength 18 - bDescriptorType 1 - bcdUSB 200 - bDeviceClass 239 - bDeviceSubClass 2 - bDeviceProtocol 1 - bMaxPacketSize0 64 - idVendor 2fe3 - idProduct ffff - bcdDevice 301 - iManufacturer 1 - iProduct 2 - iSerial 3 - bNumConfigurations 1 + [160:04:13.870,000] usb_loopback: Enable loopback_0 + uart:~$ usbh device list + 1 + uart:~$ usbh device descriptor device 1 + host: USB device with address 1 + bLength 18 + bDescriptorType 1 + bcdUSB 200 + bDeviceClass 239 + bDeviceSubClass 2 + bDeviceProtocol 1 + bMaxPacketSize0 64 + idVendor 2fe3 + idProduct ffff + bcdDevice 402 + iManufacturer 1 + iProduct 2 + iSerial 3 + bNumConfigurations 1 + uart:~$