Skip to content

drivers: usb: rename UDC buffer to USB buffer #86920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/connectivity/usb/device_next/api/udc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ API reference

.. doxygengroup:: udc_api

.. doxygengroup:: udc_buf
.. doxygengroup:: usb_buf
7 changes: 7 additions & 0 deletions drivers/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# Copyright (c) 2016 Wind River Systems, Inc.
# SPDX-License-Identifier: Apache-2.0

config USB_BUF_FORCE_NOCACHE
bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't remove the prompt as part of rename macro commit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing functional behavior is something that should not be done in rename commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing functional behavior is something that should not be done in rename commit.

Where did you get that?
What functional behavior has been changed that is not described in the commit message?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Kconfig symbol is now promptless.

Copy link
Contributor Author

@jfischer-no jfischer-no Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not have a prompt. And now it is moved up one level and it must not have a prompt. Rather there also should be menu USB.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jfischer-no Could you please help to explain why it should not have a prompt? Without prompt, it can't be configured in application. Take NXP USB controller as one example, USB_BUF_FORCE_NOCACHE can be true default. application can set it as false, then data is in cached ram and data size aligned with cache line size, NXP USB controller will do the cached data maintenance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then data is in cached ram and data size aligned with cache line size, NXP USB controller will do the cached data maintenance.

If your driver can handle it, the driver should not select this option at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I understand your point. My original thought is: USB_BUF_FORCE_NOCACHE can give option that can be selected by User/Application. For example: User put the USB transfer buffer to non-cached ram that is faster (internal ram) than cached ram (external ram) in order that CPU can process the USB data faster, then the USB_BUF_FORCE_NOCACHE can be enabled by application. Anyway the USB buffer of application can be put in non-cached ram even USB_BUF_FORCE_NOCACHE is disabled. But the stack's USB transfer buffer's location can only be controlled by USB_BUF_FORCE_NOCACHE, application can't control it.
If you think it should not be controlled by application, I don't see the strong request now.
After this is merged, I can create PR to not select USB_BUF_FORCE_NOCACHE default in NXP controller drivers.

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"
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0

add_subdirectory_ifdef(CONFIG_HAS_NRFX nrf_usbd_common)
add_subdirectory(buf)
5 changes: 5 additions & 0 deletions drivers/usb/common/buf/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
39 changes: 39 additions & 0 deletions drivers/usb/common/buf/usb_buf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/net_buf.h>
#include <zephyr/drivers/usb/usb_buf.h>

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,
};
2 changes: 1 addition & 1 deletion drivers/usb/device/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 0 additions & 7 deletions drivers/usb/udc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/Kconfig.mcux
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
32 changes: 1 addition & 31 deletions drivers/usb/udc/udc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/usb/usb_ch9.h>
#include <zephyr/drivers/usb/udc_buf.h>
#include <zephyr/drivers/usb/usb_buf.h>
#include "udc_common.h"

#include <zephyr/logging/log.h>
Expand All @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions drivers/usb/uhc/uhc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/drivers/usb/udc.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/usb/udc_buf.h>
#include <zephyr/drivers/usb/usb_buf.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/usb/usb_ch9.h>

Expand Down
1 change: 1 addition & 0 deletions include/zephyr/drivers/usb/uhc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/net_buf.h>
#include <zephyr/drivers/usb/usb_buf.h>
#include <zephyr/usb/usb_ch9.h>
#include <zephyr/sys/dlist.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,58 @@
* @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 <zephyr/kernel.h>
#include <zephyr/net_buf.h>

#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
* consistent source of information about what part of memory is DMA'able.
* 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
Expand All @@ -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
Expand All @@ -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 = { \
Expand All @@ -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 */
Expand All @@ -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, \
Expand All @@ -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)
/**
* @}
*/
Expand Down
Loading