[PATCH] usb-audio: Fix invalid values in AudioControl descriptors

Joonas Kankaala posted 1 patch 1 month, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20240309172932.288940-1-joonas.a.kankaala@gmail.com
Maintainers: Gerd Hoffmann <kraxel@redhat.com>
hw/usb/dev-audio.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
[PATCH] usb-audio: Fix invalid values in AudioControl descriptors
Posted by Joonas Kankaala 1 month, 2 weeks ago
This fixes the invalid bInterfaceProtocol value 0x04 in the USB audio
AudioControl descriptors. It should be zero. While Linux and Windows
forgive this error, macOS 14 Sonoma does not. The usb-audio device does
not appear in macOS sound settings even though the device is recognized
and shows up in USB system information. According to the USB audio class
specs 1.0-4.0, valid values are 0x00, 0x20, 0x30 and 0x40. (Note also
that Linux prints the warning "unknown interface protocol 0x4, assuming
v1", but then proceeds as if the value was zero.)

This also fixes the invalid wTotalLength value in the multi-channel
setup AudioControl interface header descriptor (used when multi=on
and out.mixing-engine off). The combined length of all the descriptors
there add up to 0x37, not 0x38. In Linux, "lsusb -D ..." displays
incomplete descriptor information when this length is incorrect.

Signed-off-by: Joonas Kankaala <joonas.a.kankaala@gmail.com>
---
 hw/usb/dev-audio.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index d5ac1f8962..1897fff9e6 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -124,7 +124,6 @@ static const USBDescIface desc_iface[] = {
         .bNumEndpoints                 = 0,
         .bInterfaceClass               = USB_CLASS_AUDIO,
         .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_CONTROL,
-        .bInterfaceProtocol            = 0x04,
         .iInterface                    = STRING_USBAUDIO_CONTROL,
         .ndesc                         = 4,
         .descs = (USBDescOther[]) {
@@ -282,7 +281,6 @@ static const USBDescIface desc_iface_multi[] = {
         .bNumEndpoints                 = 0,
         .bInterfaceClass               = USB_CLASS_AUDIO,
         .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_CONTROL,
-        .bInterfaceProtocol            = 0x04,
         .iInterface                    = STRING_USBAUDIO_CONTROL,
         .ndesc                         = 4,
         .descs = (USBDescOther[]) {
@@ -293,7 +291,7 @@ static const USBDescIface desc_iface_multi[] = {
                     USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
                     DST_AC_HEADER,              /*  u8  bDescriptorSubtype */
                     U16(0x0100),                /* u16  bcdADC */
-                    U16(0x38),                  /* u16  wTotalLength */
+                    U16(0x37),                  /* u16  wTotalLength */
                     0x01,                       /*  u8  bInCollection */
                     0x01,                       /*  u8  baInterfaceNr */
                 }
-- 
2.39.2
Re: [PATCH] usb-audio: Fix invalid values in AudioControl descriptors
Posted by Volker Rümelin 1 month, 1 week ago
Am 09.03.24 um 18:29 schrieb Joonas Kankaala:
> This fixes the invalid bInterfaceProtocol value 0x04 in the USB audio
> AudioControl descriptors. It should be zero. While Linux and Windows
> forgive this error, macOS 14 Sonoma does not. The usb-audio device does
> not appear in macOS sound settings even though the device is recognized
> and shows up in USB system information. According to the USB audio class
> specs 1.0-4.0, valid values are 0x00, 0x20, 0x30 and 0x40. (Note also
> that Linux prints the warning "unknown interface protocol 0x4, assuming
> v1", but then proceeds as if the value was zero.)
>
> This also fixes the invalid wTotalLength value in the multi-channel
> setup AudioControl interface header descriptor (used when multi=on
> and out.mixing-engine off). The combined length of all the descriptors
> there add up to 0x37, not 0x38. In Linux, "lsusb -D ..." displays
> incomplete descriptor information when this length is incorrect.
>
> Signed-off-by: Joonas Kankaala <joonas.a.kankaala@gmail.com>

lsusb also misinterprets the invalid interface protocol 0x4 and uses
0x30 instead.

Reviewed-by: Volker Rümelin <vr_qemu@t-online.de>

> ---
>  hw/usb/dev-audio.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
> index d5ac1f8962..1897fff9e6 100644
> --- a/hw/usb/dev-audio.c
> +++ b/hw/usb/dev-audio.c
> @@ -124,7 +124,6 @@ static const USBDescIface desc_iface[] = {
>          .bNumEndpoints                 = 0,
>          .bInterfaceClass               = USB_CLASS_AUDIO,
>          .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_CONTROL,
> -        .bInterfaceProtocol            = 0x04,
>          .iInterface                    = STRING_USBAUDIO_CONTROL,
>          .ndesc                         = 4,
>          .descs = (USBDescOther[]) {
> @@ -282,7 +281,6 @@ static const USBDescIface desc_iface_multi[] = {
>          .bNumEndpoints                 = 0,
>          .bInterfaceClass               = USB_CLASS_AUDIO,
>          .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_CONTROL,
> -        .bInterfaceProtocol            = 0x04,
>          .iInterface                    = STRING_USBAUDIO_CONTROL,
>          .ndesc                         = 4,
>          .descs = (USBDescOther[]) {
> @@ -293,7 +291,7 @@ static const USBDescIface desc_iface_multi[] = {
>                      USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
>                      DST_AC_HEADER,              /*  u8  bDescriptorSubtype */
>                      U16(0x0100),                /* u16  bcdADC */
> -                    U16(0x38),                  /* u16  wTotalLength */
> +                    U16(0x37),                  /* u16  wTotalLength */
>                      0x01,                       /*  u8  bInCollection */
>                      0x01,                       /*  u8  baInterfaceNr */
>                  }