usb: device_next: Separate endpoint assignment from class data

Introduce usbd_class_iter for keeping endpoint assignment variables
and the single-linked list node. No functional changes right now, but
this paves the way for independent speed specific configurations.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This commit is contained in:
Tomasz Moń 2024-02-28 13:12:48 +01:00 committed by Carles Cufí
parent 2deab70f0f
commit f411f801fe
12 changed files with 164 additions and 145 deletions

View file

@ -121,7 +121,7 @@ endif()
if(CONFIG_USB_DEVICE_STACK OR CONFIG_USB_DEVICE_STACK_NEXT)
zephyr_iterable_section(NAME usb_cfg_data GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
zephyr_iterable_section(NAME usbd_contex GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
zephyr_iterable_section(NAME usbd_class_node GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
zephyr_iterable_section(NAME usbd_class_iter GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
endif()
if(CONFIG_USB_HOST_STACK)

View file

@ -271,6 +271,32 @@ struct usbd_class_data {
struct usbd_contex *uds_ctx;
/** Supported vendor request table, can be NULL */
const struct usbd_cctx_vendor_req *v_reqs;
/** Pointer to private data */
void *priv;
};
struct usbd_class_node {
/** Name of the USB device class instance */
const char *name;
/** Pointer to device support class API */
const struct usbd_class_api *api;
/** Pointer to USB device support class data */
struct usbd_class_data *data;
};
/**
* @cond INTERNAL_HIDDEN
*
* Variables necessary for per speed class management. For each speed (Full,
* High) there is separate `struct usbd_class_iter` pointing to the same
* `struct usbd_class_node` (because the class can only operate at one speed
* at a time).
*/
struct usbd_class_iter {
/** Node information for the slist. */
sys_snode_t node;
/** Pointer to public class node instance. */
struct usbd_class_node *const c_nd;
/** Bitmap of all endpoints assigned to the instance.
* The IN endpoints are mapped in the upper halfword.
*/
@ -283,20 +309,9 @@ struct usbd_class_data {
uint32_t iface_bm;
/** Variable to store the state of the class instance */
atomic_t state;
/** Pointer to private data */
void *priv;
};
struct usbd_class_node {
/** Node information for the slist. */
sys_snode_t node;
/** Name of the USB device class instance */
const char *name;
/** Pointer to device support class API */
const struct usbd_class_api *api;
/** Pointer to USB device support class data */
struct usbd_class_data *data;
};
/** @endcond */
/**
* @brief Get the USB device runtime context under which the class is registered
@ -459,11 +474,14 @@ static inline void *usbd_class_get_private(const struct usbd_class_node *const c
#define USBD_DESC_SERIAL_NUMBER_DEFINE(d_name, d_string) \
USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_SERIAL_NUMBER)
#define USBD_DEFINE_CLASS(class_name, class_api, class_data) \
static STRUCT_SECTION_ITERABLE(usbd_class_node, class_name) = { \
.name = STRINGIFY(class_name), \
.api = class_api, \
.data = class_data, \
#define USBD_DEFINE_CLASS(class_name, class_api, class_data) \
static struct usbd_class_node class_name = { \
.name = STRINGIFY(class_name), \
.api = class_api, \
.data = class_data, \
}; \
static STRUCT_SECTION_ITERABLE(usbd_class_iter, class_name##_iter) = { \
.c_nd = &class_name, \
}
/** @brief Helper to declare request table of usbd_cctx_vendor_req

View file

@ -67,15 +67,16 @@ struct usbd_contex *sample_usbd_init_device(usbd_msg_cb_t msg_cb)
return NULL;
}
STRUCT_SECTION_FOREACH(usbd_class_node, node) {
STRUCT_SECTION_FOREACH(usbd_class_iter, iter) {
/* Pull everything that is enabled in our configuration. */
err = usbd_register_class(&sample_usbd, node->name, 1);
err = usbd_register_class(&sample_usbd, iter->c_nd->name, 1);
if (err) {
LOG_ERR("Failed to register %s (%d)", node->name, err);
LOG_ERR("Failed to register %s (%d)",
iter->c_nd->name, err);
return NULL;
}
LOG_DBG("Register %s", node->name);
LOG_DBG("Register %s", iter->c_nd->name);
}
/* Always use class code information from Interface Descriptors */

View file

@ -208,10 +208,10 @@ static int sreq_set_interface(struct usbd_contex *const uds_ctx)
static void sreq_feature_halt_notify(struct usbd_contex *const uds_ctx,
const uint8_t ep, const bool halted)
{
struct usbd_class_node *c_nd = usbd_class_get_by_ep(uds_ctx, ep);
struct usbd_class_iter *iter = usbd_class_get_by_ep(uds_ctx, ep);
if (c_nd != NULL) {
usbd_class_feature_halt(c_nd, ep, halted);
if (iter != NULL) {
usbd_class_feature_halt(iter->c_nd, ep, halted);
}
}
@ -455,7 +455,7 @@ static int sreq_get_desc_cfg(struct usbd_contex *const uds_ctx,
struct usb_cfg_descriptor *cfg_desc;
struct usbd_config_node *cfg_nd;
enum usbd_speed get_desc_speed;
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
uint16_t len;
/*
@ -502,10 +502,10 @@ static int sreq_get_desc_cfg(struct usbd_contex *const uds_ctx,
net_buf_add_mem(buf, cfg_desc, MIN(net_buf_tailroom(buf), cfg_desc->bLength));
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
struct usb_desc_header **dhp;
dhp = usbd_class_get_desc(c_nd, get_desc_speed);
dhp = usbd_class_get_desc(iter->c_nd, get_desc_speed);
if (dhp == NULL) {
return -EINVAL;
}
@ -721,28 +721,28 @@ static int nonstd_request(struct usbd_contex *const uds_ctx,
struct net_buf *const dbuf)
{
struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
struct usbd_class_node *c_nd = NULL;
struct usbd_class_iter *iter = NULL;
int ret = 0;
switch (setup->RequestType.recipient) {
case USB_REQTYPE_RECIPIENT_ENDPOINT:
c_nd = usbd_class_get_by_ep(uds_ctx, setup->wIndex);
iter = usbd_class_get_by_ep(uds_ctx, setup->wIndex);
break;
case USB_REQTYPE_RECIPIENT_INTERFACE:
c_nd = usbd_class_get_by_iface(uds_ctx, setup->wIndex);
iter = usbd_class_get_by_iface(uds_ctx, setup->wIndex);
break;
case USB_REQTYPE_RECIPIENT_DEVICE:
c_nd = usbd_class_get_by_req(uds_ctx, setup->bRequest);
iter = usbd_class_get_by_req(uds_ctx, setup->bRequest);
break;
default:
break;
}
if (c_nd != NULL) {
if (iter != NULL) {
if (reqtype_is_to_device(setup)) {
ret = usbd_class_control_to_dev(c_nd, setup, dbuf);
ret = usbd_class_control_to_dev(iter->c_nd, setup, dbuf);
} else {
ret = usbd_class_control_to_host(c_nd, setup, dbuf);
ret = usbd_class_control_to_host(iter->c_nd, setup, dbuf);
}
} else {
errno = -ENOTSUP;

View file

@ -43,12 +43,12 @@ size_t usbd_class_desc_len(struct usbd_class_node *const c_nd,
return len;
}
struct usbd_class_node *
struct usbd_class_iter *
usbd_class_get_by_config(struct usbd_contex *const uds_ctx,
const uint8_t cnum,
const uint8_t inum)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
struct usbd_config_node *cfg_nd;
cfg_nd = usbd_config_get(uds_ctx, cnum);
@ -56,20 +56,20 @@ usbd_class_get_by_config(struct usbd_contex *const uds_ctx,
return NULL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
if (c_nd->data->iface_bm & BIT(inum)) {
return c_nd;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
if (iter->iface_bm & BIT(inum)) {
return iter;
}
}
return NULL;
}
struct usbd_class_node *
struct usbd_class_iter *
usbd_class_get_by_iface(struct usbd_contex *const uds_ctx,
const uint8_t inum)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
struct usbd_config_node *cfg_nd;
cfg_nd = usbd_config_get_current(uds_ctx);
@ -77,9 +77,9 @@ usbd_class_get_by_iface(struct usbd_contex *const uds_ctx,
return NULL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
if (c_nd->data->iface_bm & BIT(inum)) {
return c_nd;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
if (iter->iface_bm & BIT(inum)) {
return iter;
}
}
@ -91,12 +91,12 @@ static bool xfer_owner_exist(struct usbd_contex *const uds_ctx,
struct net_buf *const buf)
{
struct udc_buf_info *bi = udc_get_buf_info(buf);
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
if (bi->owner == c_nd) {
uint32_t ep_active = c_nd->data->ep_active;
uint32_t ep_assigned = c_nd->data->ep_assigned;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
if (bi->owner == iter->c_nd) {
uint32_t ep_active = iter->ep_active;
uint32_t ep_assigned = iter->ep_assigned;
if (!usbd_ep_bm_is_set(&ep_active, bi->ep)) {
LOG_DBG("ep 0x%02x is not active", bi->ep);
@ -135,11 +135,11 @@ int usbd_class_handle_xfer(struct usbd_contex *const uds_ctx,
return usbd_class_request(bi->owner, buf, err);
}
struct usbd_class_node *
struct usbd_class_iter *
usbd_class_get_by_ep(struct usbd_contex *const uds_ctx,
const uint8_t ep)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
struct usbd_config_node *cfg_nd;
uint8_t ep_idx = USB_EP_GET_IDX(ep);
uint8_t cfg;
@ -162,39 +162,39 @@ usbd_class_get_by_ep(struct usbd_contex *const uds_ctx,
return NULL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
if (c_nd->data->ep_assigned & ep_bm) {
return c_nd;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
if (iter->ep_assigned & ep_bm) {
return iter;
}
}
return NULL;
}
struct usbd_class_node *
struct usbd_class_iter *
usbd_class_get_by_req(struct usbd_contex *const uds_ctx,
const uint8_t request)
{
struct usbd_config_node *cfg_nd;
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
cfg_nd = usbd_config_get_current(uds_ctx);
if (cfg_nd == NULL) {
return NULL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
if (c_nd->data->v_reqs == NULL) {
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
if (iter->c_nd->data->v_reqs == NULL) {
continue;
}
for (int i = 0; i < c_nd->data->v_reqs->len; i++) {
for (int i = 0; i < iter->c_nd->data->v_reqs->len; i++) {
/*
* First instance always wins.
* There is no other way to determine the recipient.
*/
if (c_nd->data->v_reqs->reqs[i] == request) {
return c_nd;
if (iter->c_nd->data->v_reqs->reqs[i] == request) {
return iter;
}
}
}
@ -202,11 +202,11 @@ usbd_class_get_by_req(struct usbd_contex *const uds_ctx,
return NULL;
}
static struct usbd_class_node *usbd_class_node_get(const char *name)
static struct usbd_class_iter *usbd_class_iter_get(const char *name)
{
STRUCT_SECTION_FOREACH(usbd_class_node, c_nd) {
if (strcmp(name, c_nd->name) == 0) {
return c_nd;
STRUCT_SECTION_FOREACH(usbd_class_iter, iter) {
if (strcmp(name, iter->c_nd->name) == 0) {
return iter;
}
}
@ -216,7 +216,7 @@ static struct usbd_class_node *usbd_class_node_get(const char *name)
}
static int usbd_class_append(struct usbd_contex *const uds_ctx,
struct usbd_class_node *const c_nd,
struct usbd_class_iter *const iter,
const uint8_t cfg)
{
struct usbd_config_node *cfg_nd;
@ -226,13 +226,13 @@ static int usbd_class_append(struct usbd_contex *const uds_ctx,
return -ENODATA;
}
sys_slist_append(&cfg_nd->class_list, &c_nd->node);
sys_slist_append(&cfg_nd->class_list, &iter->node);
return 0;
}
static int usbd_class_remove(struct usbd_contex *const uds_ctx,
struct usbd_class_node *const c_nd,
struct usbd_class_iter *const iter,
const uint8_t cfg)
{
struct usbd_config_node *cfg_nd;
@ -242,7 +242,7 @@ static int usbd_class_remove(struct usbd_contex *const uds_ctx,
return -ENODATA;
}
if (!sys_slist_find_and_remove(&cfg_nd->class_list, &c_nd->node)) {
if (!sys_slist_find_and_remove(&cfg_nd->class_list, &iter->node)) {
return -ENODATA;
}
@ -253,7 +253,7 @@ int usbd_class_remove_all(struct usbd_contex *const uds_ctx,
const uint8_t cfg)
{
struct usbd_config_node *cfg_nd;
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
sys_snode_t *node;
cfg_nd = usbd_config_get(uds_ctx, cfg);
@ -262,10 +262,10 @@ int usbd_class_remove_all(struct usbd_contex *const uds_ctx,
}
while ((node = sys_slist_get(&cfg_nd->class_list))) {
c_nd = CONTAINER_OF(node, struct usbd_class_node, node);
atomic_clear_bit(&c_nd->data->state, USBD_CCTX_REGISTERED);
usbd_class_shutdown(c_nd);
LOG_DBG("Remove class node %p from configuration %u", c_nd, cfg);
iter = CONTAINER_OF(node, struct usbd_class_iter, node);
atomic_clear_bit(&iter->state, USBD_CCTX_REGISTERED);
usbd_class_shutdown(iter->c_nd);
LOG_DBG("Remove class node %p from configuration %u", iter, cfg);
}
return 0;
@ -279,12 +279,12 @@ int usbd_register_class(struct usbd_contex *const uds_ctx,
const char *name,
const uint8_t cfg)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
struct usbd_class_data *data;
int ret;
c_nd = usbd_class_node_get(name);
if (c_nd == NULL) {
iter = usbd_class_iter_get(name);
if (iter == NULL) {
return -ENODEV;
}
@ -296,19 +296,19 @@ int usbd_register_class(struct usbd_contex *const uds_ctx,
goto register_class_error;
}
data = c_nd->data;
data = iter->c_nd->data;
/* TODO: does it still need to be atomic ? */
if (atomic_test_bit(&data->state, USBD_CCTX_REGISTERED)) {
if (atomic_test_bit(&iter->state, USBD_CCTX_REGISTERED)) {
LOG_WRN("Class instance already registered");
ret = -EBUSY;
goto register_class_error;
}
ret = usbd_class_append(uds_ctx, c_nd, cfg);
ret = usbd_class_append(uds_ctx, iter, cfg);
if (ret == 0) {
/* Initialize pointer back to the device struct */
atomic_set_bit(&data->state, USBD_CCTX_REGISTERED);
atomic_set_bit(&iter->state, USBD_CCTX_REGISTERED);
data->uds_ctx = uds_ctx;
}
@ -321,12 +321,12 @@ int usbd_unregister_class(struct usbd_contex *const uds_ctx,
const char *name,
const uint8_t cfg)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
struct usbd_class_data *data;
int ret;
c_nd = usbd_class_node_get(name);
if (c_nd == NULL) {
iter = usbd_class_iter_get(name);
if (iter == NULL) {
return -ENODEV;
}
@ -338,18 +338,18 @@ int usbd_unregister_class(struct usbd_contex *const uds_ctx,
goto unregister_class_error;
}
data = c_nd->data;
data = iter->c_nd->data;
/* TODO: does it still need to be atomic ? */
if (!atomic_test_bit(&data->state, USBD_CCTX_REGISTERED)) {
if (!atomic_test_bit(&iter->state, USBD_CCTX_REGISTERED)) {
LOG_WRN("Class instance not registered");
ret = -EBUSY;
goto unregister_class_error;
}
ret = usbd_class_remove(uds_ctx, c_nd, cfg);
ret = usbd_class_remove(uds_ctx, iter, cfg);
if (ret == 0) {
atomic_clear_bit(&data->state, USBD_CCTX_REGISTERED);
usbd_class_shutdown(c_nd);
atomic_clear_bit(&iter->state, USBD_CCTX_REGISTERED);
usbd_class_shutdown(iter->c_nd);
data->uds_ctx = NULL;
}

View file

@ -45,9 +45,9 @@ size_t usbd_class_desc_len(struct usbd_class_node *const c_nd,
* @param[in] uds_ctx Pointer to device context
* @param[in] inum Interface number
*
* @return Class node pointer or NULL
* @return Class iter pointer or NULL
*/
struct usbd_class_node *usbd_class_get_by_iface(struct usbd_contex *uds_ctx,
struct usbd_class_iter *usbd_class_get_by_iface(struct usbd_contex *uds_ctx,
uint8_t i_n);
/**
@ -57,9 +57,9 @@ struct usbd_class_node *usbd_class_get_by_iface(struct usbd_contex *uds_ctx,
* @param[in] cnum Configuration number
* @param[in] inum Interface number
*
* @return Class node pointer or NULL
* @return Class iter pointer or NULL
*/
struct usbd_class_node *usbd_class_get_by_config(struct usbd_contex *uds_ctx,
struct usbd_class_iter *usbd_class_get_by_config(struct usbd_contex *uds_ctx,
uint8_t cnum,
uint8_t inum);
@ -71,9 +71,9 @@ struct usbd_class_node *usbd_class_get_by_config(struct usbd_contex *uds_ctx,
* @param[in] uds_ctx Pointer to device context
* @param[in] ep Endpoint address
*
* @return Class node pointer or NULL
* @return Class iter pointer or NULL
*/
struct usbd_class_node *usbd_class_get_by_ep(struct usbd_contex *uds_ctx,
struct usbd_class_iter *usbd_class_get_by_ep(struct usbd_contex *uds_ctx,
uint8_t ep);
/**
@ -88,9 +88,9 @@ struct usbd_class_node *usbd_class_get_by_ep(struct usbd_contex *uds_ctx,
* @param[in] uds_ctx Pointer to device context
* @param[in] request bRequest value
*
* @return Class node pointer or NULL
* @return Class iter pointer or NULL
*/
struct usbd_class_node *usbd_class_get_by_req(struct usbd_contex *uds_ctx,
struct usbd_class_iter *usbd_class_get_by_req(struct usbd_contex *uds_ctx,
uint8_t request);
/**

View file

@ -44,13 +44,13 @@ usbd_config_get_current(struct usbd_contex *const uds_ctx)
static void usbd_config_classes_enable(struct usbd_config_node *const cfg_nd,
const bool enable)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
if (enable) {
usbd_class_enable(c_nd);
usbd_class_enable(iter->c_nd);
} else {
usbd_class_disable(c_nd);
usbd_class_disable(iter->c_nd);
}
}
}

View file

@ -63,7 +63,7 @@ static void usbd_class_bcast_event(struct usbd_contex *const uds_ctx,
struct udc_event *const event)
{
struct usbd_config_node *cfg_nd;
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
if (!usbd_state_is_configured(uds_ctx)) {
return;
@ -75,16 +75,16 @@ static void usbd_class_bcast_event(struct usbd_contex *const uds_ctx,
return;
}
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
switch (event->type) {
case UDC_EVT_SUSPEND:
usbd_class_suspended(c_nd);
usbd_class_suspended(iter->c_nd);
break;
case UDC_EVT_RESUME:
usbd_class_resumed(c_nd);
usbd_class_resumed(iter->c_nd);
break;
case UDC_EVT_SOF:
usbd_class_sof(c_nd);
usbd_class_sof(iter->c_nd);
break;
default:
break;
@ -253,10 +253,10 @@ static int usbd_pre_init(void)
k_thread_name_set(&usbd_thread_data, "usbd");
LOG_DBG("Available USB class nodes:");
STRUCT_SECTION_FOREACH(usbd_class_node, node) {
atomic_set(&node->data->state, 0);
LOG_DBG("\t%p, name %s", node, node->name);
LOG_DBG("Available USB class iterators:");
STRUCT_SECTION_FOREACH(usbd_class_iter, iter) {
atomic_set(&iter->state, 0);
LOG_DBG("\t%p->%p, name %s", iter, iter->c_nd, iter->c_nd->name);
}
return 0;

View file

@ -1,4 +1,4 @@
#include <zephyr/linker/iterable_sections.h>
ITERABLE_SECTION_RAM(usbd_contex, Z_LINK_ITERABLE_SUBALIGN)
ITERABLE_SECTION_RAM(usbd_class_node, Z_LINK_ITERABLE_SUBALIGN)
ITERABLE_SECTION_RAM(usbd_class_iter, Z_LINK_ITERABLE_SUBALIGN)

View file

@ -109,11 +109,10 @@ static int unassign_eps(struct usbd_contex *const uds_ctx,
* USB device configuration.
*/
static int init_configuration_inst(struct usbd_contex *const uds_ctx,
struct usbd_class_node *const c_nd,
struct usbd_class_iter *const iter,
uint32_t *const config_ep_bm,
uint8_t *const nif)
{
struct usbd_class_data *const data = c_nd->data;
struct usb_desc_header **dhp;
struct usb_if_descriptor *ifd = NULL;
struct usb_ep_descriptor *ed;
@ -138,25 +137,25 @@ static int init_configuration_inst(struct usbd_contex *const uds_ctx,
speed = usbd_caps_speed(uds_ctx);
LOG_DBG("Highest speed supported by the controller is %u", speed);
dhp = usbd_class_get_desc(c_nd, speed);
dhp = usbd_class_get_desc(iter->c_nd, speed);
if (dhp == NULL) {
return -EINVAL;
}
tmp_nif = *nif;
data->iface_bm = 0U;
data->ep_active = 0U;
iter->iface_bm = 0U;
iter->ep_active = 0U;
while (*dhp != NULL && (*dhp)->bLength != 0) {
if ((*dhp)->bDescriptorType == USB_DESC_INTERFACE) {
ifd = (struct usb_if_descriptor *)(*dhp);
data->ep_active |= class_ep_bm;
iter->ep_active |= class_ep_bm;
if (ifd->bAlternateSetting == 0) {
ifd->bInterfaceNumber = tmp_nif;
data->iface_bm |= BIT(tmp_nif);
iter->iface_bm |= BIT(tmp_nif);
tmp_nif++;
} else {
ifd->bInterfaceNumber = tmp_nif - 1;
@ -194,10 +193,10 @@ static int init_configuration_inst(struct usbd_contex *const uds_ctx,
}
*nif = tmp_nif;
data->ep_active |= class_ep_bm;
iter->ep_active |= class_ep_bm;
LOG_INF("Instance iface-bm 0x%08x ep-bm 0x%08x",
data->iface_bm, data->ep_active);
iter->iface_bm, iter->ep_active);
return 0;
}
@ -211,30 +210,30 @@ static int init_configuration(struct usbd_contex *const uds_ctx,
struct usbd_config_node *const cfg_nd)
{
struct usb_cfg_descriptor *cfg_desc = cfg_nd->desc;
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
uint32_t config_ep_bm = 0;
size_t cfg_len = 0;
uint8_t nif = 0;
int ret;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
ret = init_configuration_inst(uds_ctx, c_nd,
ret = init_configuration_inst(uds_ctx, iter,
&config_ep_bm, &nif);
if (ret != 0) {
LOG_ERR("Failed to assign endpoint addresses");
return ret;
}
ret = usbd_class_init(c_nd);
ret = usbd_class_init(iter->c_nd);
if (ret != 0) {
LOG_ERR("Failed to initialize class instance");
return ret;
}
LOG_INF("Init class node %p, descriptor length %zu",
c_nd, usbd_class_desc_len(c_nd, usbd_caps_speed(uds_ctx)));
cfg_len += usbd_class_desc_len(c_nd, usbd_caps_speed(uds_ctx));
LOG_INF("Init class node %p, descriptor length %zu", iter->c_nd,
usbd_class_desc_len(iter->c_nd, usbd_caps_speed(uds_ctx)));
cfg_len += usbd_class_desc_len(iter->c_nd, usbd_caps_speed(uds_ctx));
}
/* Update wTotalLength and bNumInterfaces of configuration descriptor */
@ -247,9 +246,9 @@ static int init_configuration(struct usbd_contex *const uds_ctx,
cfg_desc->wTotalLength);
/* Finally reset configuration's endpoint assignment */
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
c_nd->data->ep_assigned = c_nd->data->ep_active;
ret = unassign_eps(uds_ctx, &config_ep_bm, &c_nd->data->ep_active);
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
iter->ep_assigned = iter->ep_active;
ret = unassign_eps(uds_ctx, &config_ep_bm, &iter->ep_active);
if (ret != 0) {
return ret;
}

View file

@ -51,7 +51,7 @@ static int handle_ep_op(struct usbd_contex *const uds_ctx,
}
static int usbd_interface_modify(struct usbd_contex *const uds_ctx,
struct usbd_class_node *const node,
struct usbd_class_iter *const iter,
const enum ep_op op,
const uint8_t iface,
const uint8_t alt)
@ -60,7 +60,7 @@ static int usbd_interface_modify(struct usbd_contex *const uds_ctx,
bool found_iface = false;
int ret;
dhp = usbd_class_get_desc(node, usbd_bus_speed(uds_ctx));
dhp = usbd_class_get_desc(iter->c_nd, usbd_bus_speed(uds_ctx));
if (dhp == NULL) {
return -EINVAL;
}
@ -79,7 +79,7 @@ static int usbd_interface_modify(struct usbd_contex *const uds_ctx,
if (ifd->bInterfaceNumber == iface &&
ifd->bAlternateSetting == alt) {
found_iface = true;
LOG_DBG("Found interface %u %p", iface, node);
LOG_DBG("Found interface %u %p", iface, iter);
if (ifd->bNumEndpoints == 0) {
LOG_INF("No endpoints, skip interface");
break;
@ -89,14 +89,14 @@ static int usbd_interface_modify(struct usbd_contex *const uds_ctx,
if ((*dhp)->bDescriptorType == USB_DESC_ENDPOINT && found_iface) {
ed = (struct usb_ep_descriptor *)(*dhp);
ret = handle_ep_op(uds_ctx, op, ed, &node->data->ep_active);
ret = handle_ep_op(uds_ctx, op, ed, &iter->ep_active);
if (ret) {
return ret;
}
LOG_INF("Modify interface %u ep 0x%02x by op %u ep_bm %x",
iface, ed->bEndpointAddress,
op, node->data->ep_active);
op, iter->ep_active);
}
dhp++;
@ -110,10 +110,10 @@ static int usbd_interface_modify(struct usbd_contex *const uds_ctx,
int usbd_interface_shutdown(struct usbd_contex *const uds_ctx,
struct usbd_config_node *const cfg_nd)
{
struct usbd_class_node *c_nd;
struct usbd_class_iter *iter;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
uint32_t *ep_bm = &c_nd->data->ep_active;
SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, iter, node) {
uint32_t *ep_bm = &iter->ep_active;
for (int idx = 1; idx < 16 && *ep_bm; idx++) {
uint8_t ep_in = USB_EP_DIR_IN | idx;
@ -147,7 +147,7 @@ int usbd_interface_default(struct usbd_contex *const uds_ctx,
/* Set default alternate for all interfaces */
for (int i = 0; i < desc->bNumInterfaces; i++) {
struct usbd_class_node *class;
struct usbd_class_iter *class;
int ret;
class = usbd_class_get_by_config(uds_ctx, new_cfg, i);
@ -168,7 +168,7 @@ int usbd_interface_set(struct usbd_contex *const uds_ctx,
const uint8_t iface,
const uint8_t alt)
{
struct usbd_class_node *class;
struct usbd_class_iter *class;
uint8_t cur_alt;
int ret;
@ -206,7 +206,7 @@ int usbd_interface_set(struct usbd_contex *const uds_ctx,
return ret;
}
usbd_class_update(class, iface, alt);
usbd_class_update(class->c_nd, iface, alt);
usbd_set_alt_value(uds_ctx, iface, alt);
return 0;

View file

@ -397,10 +397,11 @@ static void class_node_name_lookup(size_t idx, struct shell_static_entry *entry)
entry->help = NULL;
entry->subcmd = NULL;
STRUCT_SECTION_FOREACH(usbd_class_node, node) {
if ((node->name != NULL) && (strlen(node->name) != 0)) {
STRUCT_SECTION_FOREACH(usbd_class_iter, iter) {
if ((iter->c_nd->name != NULL) &&
(strlen(iter->c_nd->name) != 0)) {
if (match_idx == idx) {
entry->syntax = node->name;
entry->syntax = iter->c_nd->name;
break;
}