diff --git a/doc/connectivity/usb/device_next/api/udc.rst b/doc/connectivity/usb/device_next/api/udc.rst index 752cca5947917..ae8d2587a4eb7 100644 --- a/doc/connectivity/usb/device_next/api/udc.rst +++ b/doc/connectivity/usb/device_next/api/udc.rst @@ -17,4 +17,4 @@ API reference .. doxygengroup:: udc_api -.. doxygengroup:: udc_buf +.. doxygengroup:: usb_buf diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index bcccdf6b65789..1250ca265229d 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -3,6 +3,13 @@ # Copyright (c) 2016 Wind River Systems, Inc. # SPDX-License-Identifier: Apache-2.0 +config USB_BUF_FORCE_NOCACHE + bool + depends on NOCACHE_MEMORY && DCACHE && (UDC_DRIVER || UHC_DRIVER) + help + Place the buffer pools in the nocache memory region if the driver + cannot handle buffers in cached memory. + source "drivers/usb/bc12/Kconfig" source "drivers/usb/udc/Kconfig" source "drivers/usb/uhc/Kconfig" diff --git a/drivers/usb/common/CMakeLists.txt b/drivers/usb/common/CMakeLists.txt index 56e4c734ced97..f4242d2a88c5b 100644 --- a/drivers/usb/common/CMakeLists.txt +++ b/drivers/usb/common/CMakeLists.txt @@ -1,3 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 add_subdirectory_ifdef(CONFIG_HAS_NRFX nrf_usbd_common) +add_subdirectory(buf) diff --git a/drivers/usb/common/buf/CMakeLists.txt b/drivers/usb/common/buf/CMakeLists.txt new file mode 100644 index 0000000000000..a24df3a0cac0f --- /dev/null +++ b/drivers/usb/common/buf/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources_ifdef(CONFIG_UDC_DRIVER usb_buf.c) diff --git a/drivers/usb/common/buf/usb_buf.c b/drivers/usb/common/buf/usb_buf.c new file mode 100644 index 0000000000000..e78abbceba465 --- /dev/null +++ b/drivers/usb/common/buf/usb_buf.c @@ -0,0 +1,39 @@ +/* + * Copyright 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static inline uint8_t *usb_pool_data_alloc(struct net_buf *const buf, + size_t *const size, k_timeout_t timeout) +{ + struct net_buf_pool *const buf_pool = net_buf_pool_get(buf->pool_id); + struct k_heap *const pool = buf_pool->alloc->alloc_data; + void *b; + + *size = USB_BUF_ROUND_UP(*size); + b = k_heap_aligned_alloc(pool, USB_BUF_ALIGN, *size, timeout); + if (b == NULL) { + *size = 0; + return NULL; + } + + return b; +} + +static inline void usb_pool_data_unref(struct net_buf *buf, uint8_t *const data) +{ + struct net_buf_pool *buf_pool = net_buf_pool_get(buf->pool_id); + struct k_heap *pool = buf_pool->alloc->alloc_data; + + k_heap_free(pool, data); +} + +const struct net_buf_data_cb net_buf_dma_cb = { + .alloc = usb_pool_data_alloc, + .unref = usb_pool_data_unref, +}; diff --git a/drivers/usb/common/usb_dwc2_hw.h b/drivers/usb/common/include/usb_dwc2_hw.h similarity index 100% rename from drivers/usb/common/usb_dwc2_hw.h rename to drivers/usb/common/include/usb_dwc2_hw.h diff --git a/drivers/usb/device/CMakeLists.txt b/drivers/usb/device/CMakeLists.txt index 6763b3c7f88d9..c1d728a55c6e0 100644 --- a/drivers/usb/device/CMakeLists.txt +++ b/drivers/usb/device/CMakeLists.txt @@ -3,7 +3,7 @@ if(CONFIG_USB_DEVICE_DRIVER) zephyr_library() -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/usb/common/) +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/usb/common/include) zephyr_library_sources_ifdef(CONFIG_USB_DW usb_dc_dw.c) zephyr_library_sources_ifdef(CONFIG_USB_DC_RPI_PICO usb_dc_rpi_pico.c) diff --git a/drivers/usb/udc/CMakeLists.txt b/drivers/usb/udc/CMakeLists.txt index 0fdc321a3141a..09191e803c7b2 100644 --- a/drivers/usb/udc/CMakeLists.txt +++ b/drivers/usb/udc/CMakeLists.txt @@ -4,7 +4,7 @@ zephyr_library() zephyr_library_sources(udc_common.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/usb/common/) +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/usb/common/include) zephyr_library_sources_ifdef(CONFIG_UDC_DWC2 udc_dwc2.c) zephyr_library_sources_ifdef(CONFIG_UDC_NRF udc_nrf.c) diff --git a/drivers/usb/udc/Kconfig b/drivers/usb/udc/Kconfig index fd5e25cf11344..a6750d47647f5 100644 --- a/drivers/usb/udc/Kconfig +++ b/drivers/usb/udc/Kconfig @@ -25,13 +25,6 @@ config UDC_BUF_POOL_SIZE help Total amount of memory available for UDC requests. -config UDC_BUF_FORCE_NOCACHE - bool "Place the buffer pools in the nocache memory region" - depends on NOCACHE_MEMORY && DCACHE - help - Place the buffer pools in the nocache memory region if the driver - cannot handle buffers in cached memory. - config UDC_WORKQUEUE bool "Use a dedicate work queue for UDC drivers" help diff --git a/drivers/usb/udc/Kconfig.mcux b/drivers/usb/udc/Kconfig.mcux index d68b21d171039..8db17011df17b 100644 --- a/drivers/usb/udc/Kconfig.mcux +++ b/drivers/usb/udc/Kconfig.mcux @@ -7,7 +7,7 @@ config UDC_NXP_EHCI depends on DT_HAS_NXP_EHCI_ENABLED select PINCTRL select NOCACHE_MEMORY if CPU_HAS_DCACHE - imply UDC_BUF_FORCE_NOCACHE + imply USB_BUF_FORCE_NOCACHE imply UDC_WORKQUEUE help NXP MCUX USB Device Controller Driver for EHCI. diff --git a/drivers/usb/udc/udc_common.c b/drivers/usb/udc/udc_common.c index 3718290ce42e0..73829187f42f9 100644 --- a/drivers/usb/udc/udc_common.c +++ b/drivers/usb/udc/udc_common.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "udc_common.h" #include @@ -21,36 +21,6 @@ #endif LOG_MODULE_REGISTER(udc, CONFIG_UDC_DRIVER_LOG_LEVEL); -static inline uint8_t *udc_pool_data_alloc(struct net_buf *const buf, - size_t *const size, k_timeout_t timeout) -{ - struct net_buf_pool *const buf_pool = net_buf_pool_get(buf->pool_id); - struct k_heap *const pool = buf_pool->alloc->alloc_data; - void *b; - - *size = ROUND_UP(*size, UDC_BUF_GRANULARITY); - b = k_heap_aligned_alloc(pool, UDC_BUF_ALIGN, *size, timeout); - if (b == NULL) { - *size = 0; - return NULL; - } - - return b; -} - -static inline void udc_pool_data_unref(struct net_buf *buf, uint8_t *const data) -{ - struct net_buf_pool *buf_pool = net_buf_pool_get(buf->pool_id); - struct k_heap *pool = buf_pool->alloc->alloc_data; - - k_heap_free(pool, data); -} - -const struct net_buf_data_cb net_buf_dma_cb = { - .alloc = udc_pool_data_alloc, - .unref = udc_pool_data_unref, -}; - static inline void udc_buf_destroy(struct net_buf *buf); UDC_BUF_POOL_VAR_DEFINE(udc_ep_pool, diff --git a/drivers/usb/uhc/uhc_common.c b/drivers/usb/uhc/uhc_common.c index 097d4a01457e0..9effb96db206e 100644 --- a/drivers/usb/uhc/uhc_common.c +++ b/drivers/usb/uhc/uhc_common.c @@ -14,11 +14,10 @@ LOG_MODULE_REGISTER(uhc, CONFIG_UHC_DRIVER_LOG_LEVEL); K_MEM_SLAB_DEFINE_STATIC(uhc_xfer_pool, sizeof(struct uhc_transfer), CONFIG_UHC_XFER_COUNT, sizeof(void *)); -NET_BUF_POOL_VAR_DEFINE(uhc_ep_pool, +USB_BUF_POOL_VAR_DEFINE(uhc_ep_pool, CONFIG_UHC_BUF_COUNT, CONFIG_UHC_BUF_POOL_SIZE, 0, NULL); - int uhc_submit_event(const struct device *dev, const enum uhc_event_type type, const int status) diff --git a/include/zephyr/drivers/usb/udc.h b/include/zephyr/drivers/usb/udc.h index 197cfe60e5575..8e5b723c17803 100644 --- a/include/zephyr/drivers/usb/udc.h +++ b/include/zephyr/drivers/usb/udc.h @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/include/zephyr/drivers/usb/uhc.h b/include/zephyr/drivers/usb/uhc.h index f7e357854e882..7371b9e2f1385 100644 --- a/include/zephyr/drivers/usb/uhc.h +++ b/include/zephyr/drivers/usb/uhc.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/include/zephyr/drivers/usb/udc_buf.h b/include/zephyr/drivers/usb/usb_buf.h similarity index 58% rename from include/zephyr/drivers/usb/udc_buf.h rename to include/zephyr/drivers/usb/usb_buf.h index 5975c6d6a358f..546e0222f9ff6 100644 --- a/include/zephyr/drivers/usb/udc_buf.h +++ b/include/zephyr/drivers/usb/usb_buf.h @@ -9,13 +9,13 @@ * @brief Buffers for USB device support */ -#ifndef ZEPHYR_INCLUDE_UDC_BUF_H -#define ZEPHYR_INCLUDE_UDC_BUF_H +#ifndef ZEPHYR_INCLUDE_USB_BUF_H +#define ZEPHYR_INCLUDE_USB_BUF_H #include #include -#if defined(CONFIG_DCACHE) && !defined(CONFIG_UDC_BUF_FORCE_NOCACHE) +#if defined(CONFIG_DCACHE) && !defined(CONFIG_USB_BUF_FORCE_NOCACHE) /* * Here we try to get DMA-safe buffers, but we lack a consistent source of * information about data cache properties, such as line cache size, and a @@ -23,41 +23,44 @@ * For now, we simply assume that all available memory is DMA'able and use * Kconfig option DCACHE_LINE_SIZE for alignment and granularity. */ -#define Z_UDC_BUF_ALIGN CONFIG_DCACHE_LINE_SIZE -#define Z_UDC_BUF_GRANULARITY CONFIG_DCACHE_LINE_SIZE +#define Z_USB_BUF_ALIGN CONFIG_DCACHE_LINE_SIZE +#define Z_USB_BUF_GRANULARITY CONFIG_DCACHE_LINE_SIZE #else /* * Default alignment and granularity to pointer size if the platform does not * have a data cache or buffers are placed in nocache memory region. */ -#define Z_UDC_BUF_ALIGN sizeof(void *) -#define Z_UDC_BUF_GRANULARITY sizeof(void *) +#define Z_USB_BUF_ALIGN sizeof(void *) +#define Z_USB_BUF_GRANULARITY sizeof(void *) #endif -#if defined(CONFIG_UDC_BUF_FORCE_NOCACHE) +#if defined(CONFIG_USB_BUF_FORCE_NOCACHE) /* * The usb transfer buffer needs to be in __nocache section */ -#define Z_UDC_BUF_SECTION __nocache +#define Z_USB_BUF_SECTION __nocache #else -#define Z_UDC_BUF_SECTION +#define Z_USB_BUF_SECTION #endif /** - * @brief Buffer macros and definitions used in USB device support - * @defgroup udc_buf Buffer macros and definitions used in USB device support + * @brief USB buffer macros and definitions + * @defgroup usb_buf USB buffer macros and definitions * @ingroup usb * @since 4.0 - * @version 0.1.0 + * @version 0.1.1 * @{ */ /** Buffer alignment required by the UDC driver */ -#define UDC_BUF_ALIGN Z_UDC_BUF_ALIGN +#define USB_BUF_ALIGN Z_USB_BUF_ALIGN /** Buffer granularity required by the UDC driver */ -#define UDC_BUF_GRANULARITY Z_UDC_BUF_GRANULARITY +#define USB_BUF_GRANULARITY Z_USB_BUF_GRANULARITY + +/** Round up to the granularity required by the UDC driver */ +#define USB_BUF_ROUND_UP(size) ROUND_UP(size, Z_USB_BUF_GRANULARITY) /** * @brief Define a UDC driver-compliant static buffer @@ -68,9 +71,9 @@ * @param name Buffer name * @param size Buffer size */ -#define UDC_STATIC_BUF_DEFINE(name, size) \ - static uint8_t Z_UDC_BUF_SECTION __aligned(UDC_BUF_ALIGN) \ - name[ROUND_UP(size, UDC_BUF_GRANULARITY)]; +#define USB_STATIC_BUF_DEFINE(name, size) \ + static uint8_t Z_USB_BUF_SECTION __aligned(USB_BUF_ALIGN) \ + name[USB_BUF_ROUND_UP(size)]; /** * @brief Verify that the buffer is aligned as required by the UDC driver @@ -79,13 +82,13 @@ * * @param buf Buffer pointer */ -#define IS_UDC_ALIGNED(buf) IS_ALIGNED(buf, UDC_BUF_ALIGN) +#define IS_USB_BUF_ALIGNED(buf) IS_ALIGNED(buf, USB_BUF_ALIGN) /** * @cond INTERNAL_HIDDEN */ -#define UDC_HEAP_DEFINE(name, bytes, in_section) \ - uint8_t in_section __aligned(UDC_BUF_ALIGN) \ +#define USB_BUF_HEAP_DEFINE(name, bytes, in_section) \ + uint8_t in_section __aligned(USB_BUF_ALIGN) \ kheap_##name[MAX(bytes, Z_HEAP_MIN_SIZE)]; \ STRUCT_SECTION_ITERABLE(k_heap, name) = { \ .heap = { \ @@ -94,10 +97,10 @@ }, \ } -#define UDC_K_HEAP_DEFINE(name, size) \ - COND_CODE_1(CONFIG_UDC_BUF_FORCE_NOCACHE, \ - (UDC_HEAP_DEFINE(name, size, __nocache)), \ - (UDC_HEAP_DEFINE(name, size, __noinit))) +#define USB_BUF_K_HEAP_DEFINE(name, size) \ + COND_CODE_1(CONFIG_USB_BUF_FORCE_NOCACHE, \ + (USB_BUF_HEAP_DEFINE(name, size, __nocache)), \ + (USB_BUF_HEAP_DEFINE(name, size, __noinit))) extern const struct net_buf_data_cb net_buf_dma_cb; /** @endcond */ @@ -116,9 +119,9 @@ extern const struct net_buf_data_cb net_buf_dma_cb; * @param ud_size User data space to reserve per buffer. * @param fdestroy Optional destroy callback when buffer is freed. */ -#define UDC_BUF_POOL_VAR_DEFINE(pname, count, size, ud_size, fdestroy) \ +#define USB_BUF_POOL_VAR_DEFINE(pname, count, size, ud_size, fdestroy) \ _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \ - UDC_K_HEAP_DEFINE(net_buf_mem_pool_##pname, size); \ + USB_BUF_K_HEAP_DEFINE(net_buf_mem_pool_##pname, size); \ static const struct net_buf_data_alloc net_buf_data_alloc_##pname = { \ .cb = &net_buf_dma_cb, \ .alloc_data = &net_buf_mem_pool_##pname, \ @@ -143,25 +146,68 @@ extern const struct net_buf_data_cb net_buf_dma_cb; * @param ud_size User data space to reserve per buffer. * @param fdestroy Optional destroy callback when buffer is freed. */ -#define UDC_BUF_POOL_DEFINE(pname, count, size, ud_size, fdestroy) \ +#define USB_BUF_POOL_DEFINE(pname, count, size, ud_size, fdestroy) \ _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \ - BUILD_ASSERT((UDC_BUF_GRANULARITY) % (UDC_BUF_ALIGN) == 0, \ + BUILD_ASSERT((USB_BUF_GRANULARITY) % (USB_BUF_ALIGN) == 0, \ "Code assumes granurality is multiple of alignment"); \ - static uint8_t Z_UDC_BUF_SECTION __aligned(UDC_BUF_ALIGN) \ - net_buf_data_##pname[count][ROUND_UP(size, UDC_BUF_GRANULARITY)];\ + static uint8_t Z_USB_BUF_SECTION __aligned(USB_BUF_ALIGN) \ + net_buf_data_##pname[count][USB_BUF_ROUND_UP(size)]; \ static const struct net_buf_pool_fixed net_buf_fixed_##pname = { \ .data_pool = (uint8_t *)net_buf_data_##pname, \ }; \ static const struct net_buf_data_alloc net_buf_fixed_alloc_##pname = { \ .cb = &net_buf_fixed_cb, \ .alloc_data = (void *)&net_buf_fixed_##pname, \ - .max_alloc_size = ROUND_UP(size, UDC_BUF_GRANULARITY), \ + .max_alloc_size = USB_BUF_ROUND_UP(size), \ }; \ static STRUCT_SECTION_ITERABLE(net_buf_pool, pname) = \ NET_BUF_POOL_INITIALIZER(pname, &net_buf_fixed_alloc_##pname, \ _net_buf_##pname, count, ud_size, \ fdestroy) +/** + * @brief Buffer alignment required by the UDC driver + * @see USB_BUF_ALIGN + */ +#define UDC_BUF_ALIGN USB_BUF_ALIGN + +/** + * @brief Buffer granularity required by the UDC driver + * @see USB_BUF_GRANULARITY + */ +#define UDC_BUF_GRANULARITY USB_BUF_GRANULARITY + +/** + * @brief Round up to the granularity required by the UDC driver + * @see USB_BUF_ROUND_UP + */ +#define UDC_ROUND_UP(size) USB_BUF_ROUND_UP(size) + +/** + * @brief Define a UDC driver-compliant static buffer + * @see USB_STATIC_BUF_DEFINE + */ +#define UDC_STATIC_BUF_DEFINE(name, size) USB_STATIC_BUF_DEFINE(name, size) + +/** + * @brief Verify that the buffer is aligned as required by the UDC driver + * @see IS_UDC_ALIGNED + */ +#define IS_UDC_ALIGNED(buf) IS_USB_BUF_ALIGNED(buf) + +/** + * @brief Define a new pool for UDC buffers based on fixed-size data + * @see USB_BUF_POOL_VAR_DEFINE + */ +#define UDC_BUF_POOL_VAR_DEFINE(pname, count, size, ud_size, fdestroy) \ + USB_BUF_POOL_VAR_DEFINE(pname, count, size, ud_size, fdestroy) + +/** + * @brief Define a new pool for UDC buffers based on fixed-size data + * @see USB_BUF_POOL_DEFINE + */ +#define UDC_BUF_POOL_DEFINE(pname, count, size, ud_size, fdestroy) \ + USB_BUF_POOL_DEFINE(pname, count, size, ud_size, fdestroy) /** * @} */ diff --git a/include/zephyr/usb/usbd.h b/include/zephyr/usb/usbd.h index b85f6e2507fd5..aa56744e71503 100644 --- a/include/zephyr/usb/usbd.h +++ b/include/zephyr/usb/usbd.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_device_config.h b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_device_config.h index 0fc30704bdadc..80c5020d51368 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_device_config.h +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_device_config.h @@ -102,7 +102,7 @@ BUILD_ASSERT(NUM_INSTS <= 1, "Only one USB device supported"); /*! @brief How many the DTD are supported. */ #define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U) -#ifndef CONFIG_UDC_BUF_FORCE_NOCACHE +#ifndef CONFIG_USB_BUF_FORCE_NOCACHE #ifdef CONFIG_NOCACHE_MEMORY #define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (1U) #endif diff --git a/samples/bluetooth/bap_broadcast_source/src/main.c b/samples/bluetooth/bap_broadcast_source/src/main.c index 30ca1a5026c2b..216d1474dbf05 100644 --- a/samples/bluetooth/bap_broadcast_source/src/main.c +++ b/samples/bluetooth/bap_broadcast_source/src/main.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/subsys/usb/host/usbip.c b/subsys/usb/host/usbip.c index 773acbb55d32e..f6692d7854d21 100644 --- a/subsys/usb/host/usbip.c +++ b/subsys/usb/host/usbip.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(usbip, CONFIG_USBIP_LOG_LEVEL); USBH_CONTROLLER_DEFINE(usbip_uhs_ctx, DEVICE_DT_GET(DT_NODELABEL(zephyr_uhc0))); #define USBIP_MAX_PKT_SIZE 2048 -NET_BUF_POOL_DEFINE(usbip_pool, 32, USBIP_MAX_PKT_SIZE, 0, NULL); +USB_BUF_POOL_DEFINE(usbip_pool, 32, USBIP_MAX_PKT_SIZE, 0, NULL); K_THREAD_STACK_DEFINE(usbip_thread_stack, CONFIG_USBIP_THREAD_STACK_SIZE); K_THREAD_STACK_ARRAY_DEFINE(dev_thread_stacks, CONFIG_USBIP_DEVICES_COUNT,