usb: device_next: Update IAD first interface on init

IAD must be before the interfaces it associates and therefore there is
no need for the class to be in charge of updating the bFirstInterface.
Update IAD in common initialization code and remove the updates from
classes.

This fixes UAC2 instances where the IAD bFirstInterface is not 0, e.g.
when HID was used together with UAC2.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This commit is contained in:
Tomasz Moń 2024-12-05 11:18:43 +01:00 committed by Benjamin Cabé
commit 9006780db4
5 changed files with 10 additions and 12 deletions

View file

@ -459,11 +459,7 @@ static void *bt_hci_get_desc(struct usbd_class_data *const c_data,
static int bt_hci_init(struct usbd_class_data *const c_data)
{
struct bt_hci_data *data = usbd_class_get_private(c_data);
struct usbd_bt_hci_desc *desc = data->desc;
desc->iad.bFirstInterface = desc->if0.bInterfaceNumber;
ARG_UNUSED(c_data);
return 0;
}

View file

@ -135,11 +135,6 @@ static void *lb_get_desc(struct usbd_class_data *const c_data,
static int lb_init(struct usbd_class_data *c_data)
{
struct lb_data *data = usbd_class_get_private(c_data);
struct loopback_desc *desc = data->desc;
desc->iad.bFirstInterface = desc->if0.bInterfaceNumber;
LOG_DBG("Init class instance %p", c_data);
return 0;

View file

@ -488,7 +488,6 @@ static int usbd_cdc_acm_init(struct usbd_class_data *const c_data)
struct cdc_acm_uart_data *data = dev->data;
struct usbd_cdc_acm_desc *desc = data->desc;
desc->iad.bFirstInterface = desc->if0.bInterfaceNumber;
desc->if0_union.bControlInterface = desc->if0.bInterfaceNumber;
desc->if0_union.bSubordinateInterface0 = desc->if1.bInterfaceNumber;

View file

@ -449,7 +449,6 @@ static int usbd_cdc_ecm_init(struct usbd_class_data *const c_data)
const uint8_t if_num = desc->if0.bInterfaceNumber;
/* Update relevant b*Interface fields */
desc->iad.bFirstInterface = if_num;
desc->if0_union.bControlInterface = if_num;
desc->if0_union.bSubordinateInterface0 = if_num + 1;
LOG_DBG("CDC ECM class initialized");

View file

@ -115,6 +115,7 @@ static int init_configuration_inst(struct usbd_context *const uds_ctx,
uint8_t *const nif)
{
struct usb_desc_header **dhp;
struct usb_association_descriptor *iad = NULL;
struct usb_if_descriptor *ifd = NULL;
struct usb_ep_descriptor *ed;
uint32_t class_ep_bm = 0;
@ -132,6 +133,14 @@ static int init_configuration_inst(struct usbd_context *const uds_ctx,
c_nd->ep_active = 0U;
while (*dhp != NULL && (*dhp)->bLength != 0) {
if ((*dhp)->bDescriptorType == USB_DESC_INTERFACE_ASSOC) {
iad = (struct usb_association_descriptor *)(*dhp);
/* IAD must be before interfaces it associates, so the
* first interface will be the next interface assigned.
*/
iad->bFirstInterface = tmp_nif;
}
if ((*dhp)->bDescriptorType == USB_DESC_INTERFACE) {
ifd = (struct usb_if_descriptor *)(*dhp);