From ee4e5ca7576b60c15661f608eef2e0f20be89ccd Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 00:37:27 +0000 Subject: [PATCH 01/10] uaudio(4): Define v1 and v2 descriptor subtypes. Rename the v1 ones to match the spec. --- sys/dev/usb/uaudio.c | 79 +++++++++++++++++++++-------------------- sys/dev/usb/uaudioreg.h | 46 ++++++++++++++++-------- 2 files changed, 72 insertions(+), 53 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index b8daeb2d367a..541c3e04d5e3 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -691,30 +691,30 @@ uaudio_get_cluster(int id, const struct io_terminal *iot) if (dp == 0) goto bad; switch (dp->bDescriptorSubtype) { - case UDESCSUB_AC_INPUT: + case UDESCSUB_AC_INPUT_TERMINAL: r.bNrChannels = iot[id].d.it->bNrChannels; USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig)); r.iChannelNames = iot[id].d.it->iChannelNames; return r; - case UDESCSUB_AC_OUTPUT: + case UDESCSUB_AC_OUTPUT_TERMINAL: id = iot[id].d.ot->bSourceId; break; - case UDESCSUB_AC_MIXER: + case UDESCSUB_AC_MIXER_UNIT: r = *(const struct usb_audio_cluster *) &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins]; return r; - case UDESCSUB_AC_SELECTOR: + case UDESCSUB_AC_SELECTOR_UNIT: /* XXX This is not really right */ id = iot[id].d.su->baSourceId[0]; break; - case UDESCSUB_AC_FEATURE: + case UDESCSUB_AC_FEATURE_UNIT: id = iot[id].d.fu->bSourceId; break; - case UDESCSUB_AC_PROCESSING: + case UDESCSUB_AC_V1_PROCESSING_UNIT: r = *(const struct usb_audio_cluster *) &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins]; return r; - case UDESCSUB_AC_EXTENSION: + case UDESCSUB_AC_V1_EXTENSION_UNIT: r = *(const struct usb_audio_cluster *) &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins]; return r; @@ -1401,7 +1401,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) } switch (it->d.desc->bDescriptorSubtype) { - case UDESCSUB_AC_INPUT: + case UDESCSUB_AC_INPUT_TERMINAL: it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); if (it->inputs == NULL) { aprint_error("uaudio_io_terminaltype: no memory\n"); @@ -1419,7 +1419,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) tml->size = 1; it->inputs_size = 1; return uaudio_merge_terminal_list(it); - case UDESCSUB_AC_FEATURE: + case UDESCSUB_AC_FEATURE_UNIT: src_id = it->d.fu->bSourceId; it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); if (it->inputs == NULL) { @@ -1429,7 +1429,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); it->inputs_size = 1; return uaudio_merge_terminal_list(it); - case UDESCSUB_AC_OUTPUT: + case UDESCSUB_AC_OUTPUT_TERMINAL: it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); if (it->inputs == NULL) { aprint_error("uaudio_io_terminaltype: no memory\n"); @@ -1440,7 +1440,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) it->inputs_size = 1; iot[src_id].direct = TRUE; return NULL; - case UDESCSUB_AC_MIXER: + case UDESCSUB_AC_MIXER_UNIT: it->inputs_size = 0; it->inputs = malloc(sizeof(struct terminal_list *) * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT); @@ -1455,7 +1455,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) it->inputs_size++; } return uaudio_merge_terminal_list(it); - case UDESCSUB_AC_SELECTOR: + case UDESCSUB_AC_SELECTOR_UNIT: it->inputs_size = 0; it->inputs = malloc(sizeof(struct terminal_list *) * it->d.su->bNrInPins, M_TEMP, M_NOWAIT); @@ -1470,7 +1470,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) it->inputs_size++; } return uaudio_merge_terminal_list(it); - case UDESCSUB_AC_PROCESSING: + case UDESCSUB_AC_V1_PROCESSING_UNIT: it->inputs_size = 0; it->inputs = malloc(sizeof(struct terminal_list *) * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT); @@ -1485,7 +1485,7 @@ uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) it->inputs_size++; } return uaudio_merge_terminal_list(it); - case UDESCSUB_AC_EXTENSION: + case UDESCSUB_AC_V1_EXTENSION_UNIT: it->inputs_size = 0; it->inputs = malloc(sizeof(struct terminal_list *) * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT); @@ -1982,7 +1982,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc dp = iot[i].d.desc; if (dp == NULL) continue; - if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT) + if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT_TERMINAL) continue; pot = iot[i].d.ot; tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i); @@ -1998,21 +1998,23 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc continue; printf("id %d:\t", i); switch (iot[i].d.desc->bDescriptorSubtype) { - case UDESCSUB_AC_INPUT: - printf("AC_INPUT type=%s\n", uaudio_get_terminal_name - (UGETW(iot[i].d.it->wTerminalType))); + case UDESCSUB_AC_INPUT_TERMINAL: + printf("AC_INPUT_TERMINAL type=%s\n", + uaudio_get_terminal_name( + UGETW(iot[i].d.it->wTerminalType))); printf("\t"); cluster = uaudio_get_cluster(i, iot); uaudio_dump_cluster(&cluster); printf("\n"); break; - case UDESCSUB_AC_OUTPUT: - printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name - (UGETW(iot[i].d.ot->wTerminalType))); + case UDESCSUB_AC_OUTPUT_TERMINAL: + printf("AC_OUTPUT_TERMINAL type=%s ", + uaudio_get_terminal_name( + UGETW(iot[i].d.ot->wTerminalType))); printf("src=%d\n", iot[i].d.ot->bSourceId); break; - case UDESCSUB_AC_MIXER: - printf("AC_MIXER src="); + case UDESCSUB_AC_MIXER_UNIT: + printf("AC_MIXER_UNIT src="); for (j = 0; j < iot[i].d.mu->bNrInPins; j++) printf("%d ", iot[i].d.mu->baSourceId[j]); printf("\n\t"); @@ -2020,17 +2022,18 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc uaudio_dump_cluster(&cluster); printf("\n"); break; - case UDESCSUB_AC_SELECTOR: - printf("AC_SELECTOR src="); + case UDESCSUB_AC_SELECTOR_UNIT: + printf("AC_SELECTOR_UNIT src="); for (j = 0; j < iot[i].d.su->bNrInPins; j++) printf("%d ", iot[i].d.su->baSourceId[j]); printf("\n"); break; - case UDESCSUB_AC_FEATURE: - printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId); + case UDESCSUB_AC_FEATURE_UNIT: + printf("AC_FEATURE_UNIT src=%d\n", + iot[i].d.fu->bSourceId); break; - case UDESCSUB_AC_PROCESSING: - printf("AC_PROCESSING src="); + case UDESCSUB_AC_V1_PROCESSING_UNIT: + printf("AC_PROCESSING_UNIT src="); for (j = 0; j < iot[i].d.pu->bNrInPins; j++) printf("%d ", iot[i].d.pu->baSourceId[j]); printf("\n\t"); @@ -2038,8 +2041,8 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc uaudio_dump_cluster(&cluster); printf("\n"); break; - case UDESCSUB_AC_EXTENSION: - printf("AC_EXTENSION src="); + case UDESCSUB_AC_V1_EXTENSION_UNIT: + printf("AC_EXTENSION_UNIT src="); for (j = 0; j < iot[i].d.eu->bNrInPins; j++) printf("%d ", iot[i].d.eu->baSourceId[j]); printf("\n\t"); @@ -2069,25 +2072,25 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc case UDESCSUB_AC_HEADER: aprint_error("uaudio_identify_ac: unexpected AC header\n"); break; - case UDESCSUB_AC_INPUT: + case UDESCSUB_AC_INPUT_TERMINAL: uaudio_add_input(sc, iot, i); break; - case UDESCSUB_AC_OUTPUT: + case UDESCSUB_AC_OUTPUT_TERMINAL: uaudio_add_output(sc, iot, i); break; - case UDESCSUB_AC_MIXER: + case UDESCSUB_AC_MIXER_UNIT: uaudio_add_mixer(sc, iot, i); break; - case UDESCSUB_AC_SELECTOR: + case UDESCSUB_AC_SELECTOR_UNIT: uaudio_add_selector(sc, iot, i); break; - case UDESCSUB_AC_FEATURE: + case UDESCSUB_AC_FEATURE_UNIT: uaudio_add_feature(sc, iot, i); break; - case UDESCSUB_AC_PROCESSING: + case UDESCSUB_AC_V1_PROCESSING_UNIT: uaudio_add_processing(sc, iot, i); break; - case UDESCSUB_AC_EXTENSION: + case UDESCSUB_AC_V1_EXTENSION_UNIT: uaudio_add_extension(sc, iot, i); break; default: diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index ca6ecc738d1d..62b4490825ab 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -37,14 +37,30 @@ #define UDESC_CS_INTERFACE 0x24 #define UDESC_CS_ENDPOINT 0x25 -#define UDESCSUB_AC_HEADER 1 -#define UDESCSUB_AC_INPUT 2 -#define UDESCSUB_AC_OUTPUT 3 -#define UDESCSUB_AC_MIXER 4 -#define UDESCSUB_AC_SELECTOR 5 -#define UDESCSUB_AC_FEATURE 6 -#define UDESCSUB_AC_PROCESSING 7 -#define UDESCSUB_AC_EXTENSION 8 +/* + * v1: USB Audio 1.0, Appendix A.5, Audio Class-Specific AC Interface + * Descriptor Subtypes, p. 100 + * + * v2: USB Audio 2.0, Appendix A.9, Audio Class-Specific AC Interface + * Descriptor Subtypes, p. 133 + */ +#define UDESCSUB_AC_HEADER 0x01 +#define UDESCSUB_AC_INPUT_TERMINAL 0x02 +#define UDESCSUB_AC_OUTPUT_TERMINAL 0x03 +#define UDESCSUB_AC_MIXER_UNIT 0x04 +#define UDESCSUB_AC_SELECTOR_UNIT 0x05 +#define UDESCSUB_AC_FEATURE_UNIT 0x06 + +#define UDESCSUB_AC_V1_PROCESSING_UNIT 0x07 +#define UDESCSUB_AC_V1_EXTENSION_UNIT 0x08 + +#define UDESCSUB_AC_V2_EFFECT_UNIT 0x07 +#define UDESCSUB_AC_V2_PROCESSING_UNIT 0x08 +#define UDESCSUB_AC_V2_EXTENSION_UNIT 0x09 +#define UDESCSUB_AC_V2_CLOCK_SOURCE 0x0A +#define UDESCSUB_AC_V2_CLOCK_SELECTOR 0x0B +#define UDESCSUB_AC_V2_CLOCK_MULTIPLIER 0x0C +#define UDESCSUB_AC_V2_SAMPLE_RATE_CONVERTER 0x0D /* The first fields are identical to usb_endpoint_descriptor_t */ typedef struct { @@ -145,7 +161,7 @@ struct usb_audio_unit { uByte bUnitId; }; -/* UDESCSUB_AC_INPUT */ +/* UDESCSUB_AC_INPUT_TERMINAL */ struct usb_audio_input_terminal { uByte bLength; uByte bDescriptorType; @@ -159,7 +175,7 @@ struct usb_audio_input_terminal { uByte iTerminal; } UPACKED; -/* UDESCSUB_AC_OUTPUT */ +/* UDESCSUB_AC_OUTPUT_TERMINAL */ struct usb_audio_output_terminal { uByte bLength; uByte bDescriptorType; @@ -171,7 +187,7 @@ struct usb_audio_output_terminal { uByte iTerminal; } UPACKED; -/* UDESCSUB_AC_MIXER */ +/* UDESCSUB_AC_MIXER_UNIT */ struct usb_audio_mixer_unit { uByte bLength; uByte bDescriptorType; @@ -189,7 +205,7 @@ struct usb_audio_mixer_unit_1 { /*uByte iMixer;*/ } UPACKED; -/* UDESCSUB_AC_SELECTOR */ +/* UDESCSUB_AC_SELECTOR_UNIT */ struct usb_audio_selector_unit { uByte bLength; uByte bDescriptorType; @@ -200,7 +216,7 @@ struct usb_audio_selector_unit { /* uByte iSelector; */ } UPACKED; -/* UDESCSUB_AC_FEATURE */ +/* UDESCSUB_AC_FEATURE_UNIT */ struct usb_audio_feature_unit { uByte bLength; uByte bDescriptorType; @@ -212,7 +228,7 @@ struct usb_audio_feature_unit { /* uByte iFeature; */ } UPACKED; -/* UDESCSUB_AC_PROCESSING */ +/* UDESCSUB_AC_V1_PROCESSING_UNIT */ struct usb_audio_processing_unit { uByte bLength; uByte bDescriptorType; @@ -238,7 +254,7 @@ struct usb_audio_processing_unit_updown { uWord waModes[255]; /* [bNrModes] */ } UPACKED; -/* UDESCSUB_AC_EXTENSION */ +/* UDESCSUB_AC_V1_EXTENSION_UNIT */ struct usb_audio_extension_unit { uByte bLength; uByte bDescriptorType; From 9bf10f0f6f7422353568e31c524ac1f84e61448b Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 00:38:50 +0000 Subject: [PATCH 02/10] uaudio(4): Rename USB audio 1.0 endpoint descriptor type. Only v1 has this peculiar endpoint descriptor structure; v2 does not. --- sys/dev/usb/uaudio.c | 12 ++++++------ sys/dev/usb/uaudioreg.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 541c3e04d5e3..78df991983a0 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -133,8 +133,8 @@ struct as_info { */ struct usbd_interface * ifaceh; const usb_interface_descriptor_t *idesc; - const usb_endpoint_descriptor_audio_t *edesc; - const usb_endpoint_descriptor_audio_t *edesc1; + const usb_endpoint_descriptor_audio_v1_t *edesc; + const usb_endpoint_descriptor_audio_v1_t *edesc1; const struct usb_audio_streaming_type1_descriptor *asf1desc; struct audio_format *aformat; int sc_busy; /* currently used */ @@ -1542,8 +1542,8 @@ uaudio_process_as(struct uaudio_softc *sc, const char *tbuf, int *offsp, { const struct usb_audio_streaming_interface_descriptor *asid; const struct usb_audio_streaming_type1_descriptor *asf1d; - const usb_endpoint_descriptor_audio_t *ed; - const usb_endpoint_descriptor_audio_t *epdesc1; + const usb_endpoint_descriptor_audio_v1_t *ed; + const usb_endpoint_descriptor_audio_v1_t *epdesc1; const struct usb_audio_streaming_endpoint_descriptor *sed; int format, chan __unused, prec, enc; int dir, type, sync, epcount; @@ -1597,7 +1597,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *tbuf, int *offsp, goto ignore; switch (epcount) { case 1: - ed = (const usb_endpoint_descriptor_audio_t *) desc; + ed = (const usb_endpoint_descriptor_audio_v1_t *) desc; DPRINTF("endpoint[0] bLength=%d bDescriptorType=%d " "bEndpointAddress=%d bmAttributes=%#x wMaxPacketSize=%d " "bInterval=%d bRefresh=%d bSynchAddress=%d\n", @@ -1608,7 +1608,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *tbuf, int *offsp, return USBD_INVAL; break; case 2: - epdesc1 = (const usb_endpoint_descriptor_audio_t *) desc; + epdesc1 = (const usb_endpoint_descriptor_audio_v1_t *) desc; DPRINTF("endpoint[1] bLength=%d " "bDescriptorType=%d bEndpointAddress=%d " "bmAttributes=%#x wMaxPacketSize=%d bInterval=%d " diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index 62b4490825ab..2f52daa6ad28 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -79,7 +79,7 @@ typedef struct { */ uByte bRefresh; uByte bSynchAddress; -} UPACKED usb_endpoint_descriptor_audio_t; +} UPACKED usb_endpoint_descriptor_audio_v1_t; /* generic, for iteration */ typedef struct { From 7760eed485646d5f99f0c92d970720085f41480f Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 00:40:46 +0000 Subject: [PATCH 03/10] uaudio(4): Rename USB audio 1.0 control descriptor type. Will reuse the name for the common part of v1 and v2 to discriminate the version, and another type for v2. --- sys/dev/usb/uaudio.c | 4 ++-- sys/dev/usb/uaudioreg.h | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 78df991983a0..27e78a63e137 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1914,7 +1914,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc { struct io_terminal* iot; const usb_interface_descriptor_t *id; - const struct usb_audio_control_descriptor *acdp; + const struct usb_audio_control_descriptor_v1 *acdp; const uaudio_cs_descriptor_t *dp; const struct usb_audio_output_terminal *pot; struct terminal_list *tml; @@ -1937,7 +1937,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc /* A class-specific AC interface header should follow. */ ibuf = tbuf + offs; ibufend = tbuf + size; - acdp = (const struct usb_audio_control_descriptor *)ibuf; + acdp = (const struct usb_audio_control_descriptor_v1 *)ibuf; if (acdp->bDescriptorType != UDESC_CS_INTERFACE || acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER) return USBD_INVAL; diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index 2f52daa6ad28..a88630b55bc7 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -88,10 +88,11 @@ typedef struct { uByte bDescriptorSubtype; } UPACKED uaudio_cs_descriptor_t; -struct usb_audio_control_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; +/* USB Audio 1.0, 4.3.2 Class-Specific AC Interface Descriptor, p. 37 */ +struct usb_audio_control_descriptor_v1 { + uByte bLength; /* 8 + .bInCollection */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_HEADER */ uWord bcdADC; uWord wTotalLength; uByte bInCollection; From a09236ca6a8b5403ed25cf582e1558335ad9d771 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 00:42:22 +0000 Subject: [PATCH 04/10] uaudio(4): Rename UAUDIO_VERSION -> UAUDIO_VERSION_1. Add UAUDIO_VERSION_2 for future use. --- sys/dev/usb/uaudio.c | 2 +- sys/dev/usb/uaudioreg.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 27e78a63e137..85affc5a454d 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1943,7 +1943,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc return USBD_INVAL; if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) && - UGETW(acdp->bcdADC) != UAUDIO_VERSION) + UGETW(acdp->bcdADC) != UAUDIO_VERSION_1) return USBD_INVAL; sc->sc_audio_rev = UGETW(acdp->bcdADC); diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index a88630b55bc7..a87ab4afaf0c 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -30,7 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define UAUDIO_VERSION 0x100 +#define UAUDIO_VERSION_1 0x100 +#define UAUDIO_VERSION_2 0x200 #define UDESC_CS_CONFIG 0x22 #define UDESC_CS_STRING 0x23 From 0293665fa0e7d9ff28d3923043bc195f8062c731 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 00:44:57 +0000 Subject: [PATCH 05/10] uaudio(4): Add include guards to uaudioreg.h. --- sys/dev/usb/uaudioreg.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index a87ab4afaf0c..7c64676f580d 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -30,6 +30,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _DEV_USB_UAUDIOREG_H_ +#define _DEV_USB_UAUDIOREG_H_ + #define UAUDIO_VERSION_1 0x100 #define UAUDIO_VERSION_2 0x200 @@ -419,3 +422,5 @@ struct usb_audio_extension_unit_1 { #define DR_THRESHOLD_CONTROL 4 #define DR_ATTACK_TIME_CONTROL 5 #define DR_RELEASE_TIME_CONTROL 6 + +#endif /* _DEV_USB_UAUDIOREG_H_ */ From e5fe9c1ddc84b2a05c3c834e3a27b75d83fcd737 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 00:47:53 +0000 Subject: [PATCH 06/10] uaudio(4): Cite spec for register definitions in uaudioreg.h. --- sys/dev/usb/uaudioreg.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index 7c64676f580d..11eff5d31e7e 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -33,6 +33,16 @@ #ifndef _DEV_USB_UAUDIOREG_H_ #define _DEV_USB_UAUDIOREG_H_ +/* + * USB Audio 1.0: Universal Serial Bus Device Class Definition for + * Audio Devices, Release 1.0, March 18, 1998. + * https://www.usb.org/sites/default/files/audio10.pdf + * + * USB Audio 2.0: Universal Serial Bus Device Class Definition for + * Audio Devices, Release 2.0, May 31, 2006. + * https://www.usb.org/sites/default/files/Audio2.0_final.zip + */ + #define UAUDIO_VERSION_1 0x100 #define UAUDIO_VERSION_2 0x200 From 0ab231dc12ae807fbae9a079d481f1755e75513d Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 01:21:04 +0000 Subject: [PATCH 07/10] uaudio(4): Sprinkle some citations and ctasserts into uaudioreg.h. --- sys/dev/usb/uaudioreg.h | 96 +++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index 11eff5d31e7e..ce8ddedc441d 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -94,6 +94,7 @@ typedef struct { uByte bRefresh; uByte bSynchAddress; } UPACKED usb_endpoint_descriptor_audio_v1_t; +__CTASSERT(sizeof(usb_endpoint_descriptor_audio_v1_t) == 9); /* generic, for iteration */ typedef struct { @@ -113,19 +114,25 @@ struct usb_audio_control_descriptor_v1 { uByte baInterfaceNr[1]; } UPACKED; +/* USB Audio 1.0, 4.5.2 Class-Specific AS Interface Descriptor, pp. 59-60 */ struct usb_audio_streaming_interface_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 7 */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* AS_GENERAL */ uByte bTerminalLink; uByte bDelay; uWord wFormatTag; } UPACKED; +__CTASSERT(sizeof(struct usb_audio_streaming_interface_descriptor) == 7); +/* + * USB Audio 1.0, 4.6.1.2 Class-Specific AS Isochronous Audio Data + * Endpoint Descriptor, pp. 62-63 + */ struct usb_audio_streaming_endpoint_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 7 */ + uByte bDescriptorType; /* UDESC_CS_ENDPOINT */ + uByte bDescriptorSubtype; /* EP_GENERAL */ uByte bmAttributes; #define UA_SED_FREQ_CONTROL 0x01 #define UA_SED_PITCH_CONTROL 0x02 @@ -133,12 +140,14 @@ struct usb_audio_streaming_endpoint_descriptor { uByte bLockDelayUnits; uWord wLockDelay; } UPACKED; +__CTASSERT(sizeof(struct usb_audio_streaming_endpoint_descriptor) == 7); +/* USB Audio 1.0, Appendix B.3.4.2.1.3 Type I Format Type Descriptor, p. 111 */ struct usb_audio_streaming_type1_descriptor { uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bFormatType; + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* FORMAT_TYPE */ + uByte bFormatType; /* FORMAT_TYPE_I */ uByte bNrChannels; uByte bSubFrameSize; uByte bBitResolution; @@ -150,6 +159,7 @@ struct usb_audio_streaming_type1_descriptor { #define UA_SAMP_HI(p) UA_GETSAMP(p, 1) } UPACKED; +/* USB Audio 1.0, 3.7.2.3 Audio Channel Cluster Format, pp. 33-34 */ struct usb_audio_cluster { uByte bNrChannels; uWord wChannelConfig; @@ -176,11 +186,11 @@ struct usb_audio_unit { uByte bUnitId; }; -/* UDESCSUB_AC_INPUT_TERMINAL */ +/* USB Audio 1.0, 4.3.2.1 Input Terminal Descriptor, pp. 38-39 */ struct usb_audio_input_terminal { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 12 */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_INPUT_TERMINAL */ uByte bTerminalId; uWord wTerminalType; uByte bAssocTerminal; @@ -189,24 +199,27 @@ struct usb_audio_input_terminal { uByte iChannelNames; uByte iTerminal; } UPACKED; +__CTASSERT(sizeof(struct usb_audio_input_terminal) == 12); -/* UDESCSUB_AC_OUTPUT_TERMINAL */ +/* USB Audio 1.0, 4.3.2.2 Ouptut Terminal Descriptor, pp. 39-40 */ struct usb_audio_output_terminal { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 9 */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_OUTPUT_TERMINAL */ uByte bTerminalId; uWord wTerminalType; uByte bAssocTerminal; uByte bSourceId; uByte iTerminal; } UPACKED; +__CTASSERT(sizeof(struct usb_audio_output_terminal) == 9); -/* UDESCSUB_AC_MIXER_UNIT */ +/* USB Audio 1.0, 4.3.2.3 Mixer Unit Descriptor, pp. 40-42 */ struct usb_audio_mixer_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 10 + .bNrInPins + * + \sum .bNrChannels */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_MIXER_UNIT */ uByte bUnitId; uByte bNrInPins; uByte baSourceId[255]; /* [bNrInPins] */ @@ -220,41 +233,41 @@ struct usb_audio_mixer_unit_1 { /*uByte iMixer;*/ } UPACKED; -/* UDESCSUB_AC_SELECTOR_UNIT */ +/* USB Audio 1.0, 4.3.2.4 Selector Unit Descriptor, pp. 42-43 */ struct usb_audio_selector_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 6 + .bNrInPins */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_SELECTOR_UNIT */ uByte bUnitId; uByte bNrInPins; uByte baSourceId[255]; /* [bNrInPins] */ /* uByte iSelector; */ } UPACKED; -/* UDESCSUB_AC_FEATURE_UNIT */ +/* USB Audio 1.0, 4.3.2.5 Feature Unit Descriptor, pp. 43-44 */ struct usb_audio_feature_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 7 + (ch + 1)*n */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_FEATURE_UNIT */ uByte bUnitId; uByte bSourceId; - uByte bControlSize; + uByte bControlSize; /* n */ uByte bmaControls[255]; /* size for more than enough */ /* uByte iFeature; */ } UPACKED; -/* UDESCSUB_AC_V1_PROCESSING_UNIT */ +/* USB Audio 1.0, 4.3.2.6 Processing Unit Descriptor, pp. 44-45 */ struct usb_audio_processing_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 13 + p + n + x */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype;/* UDESCSUB_AC_V1_PROCESSING_UNIT */ uByte bUnitId; uWord wProcessType; - uByte bNrInPins; + uByte bNrInPins; /* p */ uByte baSourceId[255]; /* [bNrInPins] */ /* struct usb_audio_processing_unit_1 */ } UPACKED; -struct usb_audio_processing_unit_1{ +struct usb_audio_processing_unit_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; @@ -263,20 +276,21 @@ struct usb_audio_processing_unit_1{ #define UA_PROC_ENABLE_MASK 1 } UPACKED; +/* USB Audio 1.0, 4.3.2.6.1 Up/Down-mix Processing Unit Descriptor */ struct usb_audio_processing_unit_updown { uByte iProcessing; uByte bNrModes; uWord waModes[255]; /* [bNrModes] */ } UPACKED; -/* UDESCSUB_AC_V1_EXTENSION_UNIT */ +/* USB Audio 1.0, 4.3.2.7 Extension Unit Descriptor, pp. 55-57 */ struct usb_audio_extension_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; + uByte bLength; /* 13 + p + n */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_V1_EXTENSION_UNIT */ uByte bUnitId; uWord wExtensionCode; - uByte bNrInPins; + uByte bNrInPins; /* p */ uByte baSourceId[255]; /* [bNrInPins] */ /* struct usb_audio_extension_unit_1 */ } UPACKED; From 5f6ff7155c8025c9618a0dba7583371a08062c71 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 01:31:09 +0000 Subject: [PATCH 08/10] uaudio(4): Make case of bUnitID and bTerminalID match spec. No functional change intended except for debug output messages. --- sys/dev/usb/uaudio.c | 58 ++++++++++++++++++++--------------------- sys/dev/usb/uaudioreg.h | 16 ++++++------ 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 85affc5a454d..19bffdcff587 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -736,10 +736,10 @@ uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) d = iot[id].d.it; #ifdef UAUDIO_DEBUG - DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x " + DPRINTFN(2,"bTerminalID=%d wTerminalType=0x%04x " "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " "iChannelNames=%d iTerminal=%d\n", - d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, + d->bTerminalID, UGETW(d->wTerminalType), d->bAssocTerminal, d->bNrChannels, UGETW(d->wChannelConfig), d->iChannelNames, d->iTerminal); #endif @@ -757,9 +757,9 @@ uaudio_add_output(struct uaudio_softc *sc, const struct usb_audio_output_terminal *d; d = iot[id].d.ot; - DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x " + DPRINTFN(2,"bTerminalID=%d wTerminalType=0x%04x " "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", - d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, + d->bTerminalID, UGETW(d->wTerminalType), d->bAssocTerminal, d->bSourceId, d->iTerminal); #endif } @@ -774,8 +774,8 @@ uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) struct mixerctl mix; d = iot[id].d.mu; - DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", - d->bUnitId, d->bNrInPins); + DPRINTFN(2,"bUnitID=%d bNrInPins=%d\n", + d->bUnitID, d->bNrInPins); /* Compute the number of input channels */ ichs = 0; @@ -788,7 +788,7 @@ uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) DPRINTFN(2,"ichs=%d ochs=%d\n", ichs, ochs); bm = d1->bmControls; - mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); + mix.wIndex = MAKE(d->bUnitID, sc->sc_ac_iface); uaudio_determine_class(&iot[id], &mix); mix.type = MIX_SIGNED_16; mix.ctlunit = AudioNvolume; @@ -816,7 +816,7 @@ uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) MAKE(p+c+1, o+1); } snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s", - d->bUnitId, uaudio_id_name(sc, iot, + d->bUnitID, uaudio_id_name(sc, iot, d->baSourceId[i])); mix.nchan = chs; uaudio_mixer_add_ctl(sc, &mix); @@ -837,9 +837,9 @@ uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int int i, wp; d = iot[id].d.su; - DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", - d->bUnitId, d->bNrInPins); - mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); + DPRINTFN(2,"bUnitID=%d bNrInPins=%d\n", + d->bUnitID, d->bNrInPins); + mix.wIndex = MAKE(d->bUnitID, sc->sc_ac_iface); mix.wValue[0] = MAKE(0, 0); uaudio_determine_class(&iot[id], &mix); mix.nchan = 1; @@ -848,7 +848,7 @@ uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int mix.minval = 1; mix.maxval = d->bNrInPins; mix.mul = mix.maxval - mix.minval; - wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId); + wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitID); for (i = 1; i <= d->bNrInPins; i++) { wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp, "i%d", d->baSourceId[i - 1]); @@ -1116,13 +1116,13 @@ uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int i cmask |= GET(chan); } - DPRINTFN(1,"bUnitId=%d, " + DPRINTFN(1,"bUnitID=%d, " "%d channels, mmask=0x%04x, cmask=0x%04x\n", - d->bUnitId, nchan, mmask, cmask); + d->bUnitID, nchan, mmask, cmask); if (nchan > MIX_MAX_CHAN) nchan = MIX_MAX_CHAN; - unit = d->bUnitId; + unit = d->bUnitID; mix.wIndex = MAKE(unit, sc->sc_ac_iface); for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) { fumask = FU_MASK(ctl); @@ -1221,21 +1221,21 @@ uaudio_add_processing_updown(struct uaudio_softc *sc, &d->baSourceId[d->bNrInPins]; ud = (const struct usb_audio_processing_unit_updown *) &d1->bmControls[d1->bControlSize]; - DPRINTFN(2,"bUnitId=%d bNrModes=%d\n", - d->bUnitId, ud->bNrModes); + DPRINTFN(2,"bUnitID=%d bNrModes=%d\n", + d->bUnitID, ud->bNrModes); if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) { DPRINTF("%s", "no mode select\n"); return; } - mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); + mix.wIndex = MAKE(d->bUnitID, sc->sc_ac_iface); mix.nchan = 1; mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0); uaudio_determine_class(&iot[id], &mix); mix.type = MIX_ON_OFF; /* XXX */ mix.ctlunit = ""; - snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId); + snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitID); for (i = 0; i < ud->bNrModes; i++) { DPRINTFN(2,"i=%d bm=%#x\n", @@ -1257,18 +1257,18 @@ uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, in d1 = (const struct usb_audio_processing_unit_1 *) &d->baSourceId[d->bNrInPins]; ptype = UGETW(d->wProcessType); - DPRINTFN(2,"wProcessType=%d bUnitId=%d " - "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins); + DPRINTFN(2,"wProcessType=%d bUnitID=%d " + "bNrInPins=%d\n", ptype, d->bUnitID, d->bNrInPins); if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) { - mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); + mix.wIndex = MAKE(d->bUnitID, sc->sc_ac_iface); mix.nchan = 1; mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0); uaudio_determine_class(&iot[id], &mix); mix.type = MIX_ON_OFF; mix.ctlunit = ""; snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable", - d->bUnitId, ptype); + d->bUnitID, ptype); uaudio_mixer_add_ctl(sc, &mix); } @@ -1285,7 +1285,7 @@ uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, in #ifdef UAUDIO_DEBUG aprint_debug( "uaudio_add_processing: unit %d, type=%d not impl.\n", - d->bUnitId, ptype); + d->bUnitID, ptype); #endif break; } @@ -1301,21 +1301,21 @@ uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int d = iot[id].d.eu; d1 = (const struct usb_audio_extension_unit_1 *) &d->baSourceId[d->bNrInPins]; - DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", - d->bUnitId, d->bNrInPins); + DPRINTFN(2,"bUnitID=%d bNrInPins=%d\n", + d->bUnitID, d->bNrInPins); if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU) return; if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { - mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); + mix.wIndex = MAKE(d->bUnitID, sc->sc_ac_iface); mix.nchan = 1; mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0); uaudio_determine_class(&iot[id], &mix); mix.type = MIX_ON_OFF; mix.ctlunit = ""; snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable", - d->bUnitId); + d->bUnitID); uaudio_mixer_add_ctl(sc, &mix); } } @@ -1970,7 +1970,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc } if (dp->bDescriptorType != UDESC_CS_INTERFACE) break; - i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId; + i = ((const struct usb_audio_input_terminal *)dp)->bTerminalID; iot[i].d.desc = dp; if (i > ndps) ndps = i; diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index ce8ddedc441d..bbed3da0e545 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -183,7 +183,7 @@ struct usb_audio_unit { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; - uByte bUnitId; + uByte bUnitID; }; /* USB Audio 1.0, 4.3.2.1 Input Terminal Descriptor, pp. 38-39 */ @@ -191,7 +191,7 @@ struct usb_audio_input_terminal { uByte bLength; /* 12 */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_INPUT_TERMINAL */ - uByte bTerminalId; + uByte bTerminalID; uWord wTerminalType; uByte bAssocTerminal; uByte bNrChannels; @@ -206,7 +206,7 @@ struct usb_audio_output_terminal { uByte bLength; /* 9 */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_OUTPUT_TERMINAL */ - uByte bTerminalId; + uByte bTerminalID; uWord wTerminalType; uByte bAssocTerminal; uByte bSourceId; @@ -220,7 +220,7 @@ struct usb_audio_mixer_unit { * + \sum .bNrChannels */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_MIXER_UNIT */ - uByte bUnitId; + uByte bUnitID; uByte bNrInPins; uByte baSourceId[255]; /* [bNrInPins] */ /* struct usb_audio_mixer_unit_1 */ @@ -238,7 +238,7 @@ struct usb_audio_selector_unit { uByte bLength; /* 6 + .bNrInPins */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_SELECTOR_UNIT */ - uByte bUnitId; + uByte bUnitID; uByte bNrInPins; uByte baSourceId[255]; /* [bNrInPins] */ /* uByte iSelector; */ @@ -249,7 +249,7 @@ struct usb_audio_feature_unit { uByte bLength; /* 7 + (ch + 1)*n */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_FEATURE_UNIT */ - uByte bUnitId; + uByte bUnitID; uByte bSourceId; uByte bControlSize; /* n */ uByte bmaControls[255]; /* size for more than enough */ @@ -261,7 +261,7 @@ struct usb_audio_processing_unit { uByte bLength; /* 13 + p + n + x */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype;/* UDESCSUB_AC_V1_PROCESSING_UNIT */ - uByte bUnitId; + uByte bUnitID; uWord wProcessType; uByte bNrInPins; /* p */ uByte baSourceId[255]; /* [bNrInPins] */ @@ -288,7 +288,7 @@ struct usb_audio_extension_unit { uByte bLength; /* 13 + p + n */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_V1_EXTENSION_UNIT */ - uByte bUnitId; + uByte bUnitID; uWord wExtensionCode; uByte bNrInPins; /* p */ uByte baSourceId[255]; /* [bNrInPins] */ From f77f9e522b8ef7510c2f225bd8b890a3e696d051 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 01:33:17 +0000 Subject: [PATCH 09/10] uaudio(4): Version all the terminal/unit descriptors. Formats all changed in v2. --- sys/dev/usb/uaudio.c | 54 ++++++++++++++++++++--------------------- sys/dev/usb/uaudioreg.h | 30 +++++++++++------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 19bffdcff587..bcb8cc1ae4da 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -219,13 +219,13 @@ struct terminal_list { struct io_terminal { union { const uaudio_cs_descriptor_t *desc; - const struct usb_audio_input_terminal *it; - const struct usb_audio_output_terminal *ot; - const struct usb_audio_mixer_unit *mu; - const struct usb_audio_selector_unit *su; - const struct usb_audio_feature_unit *fu; - const struct usb_audio_processing_unit *pu; - const struct usb_audio_extension_unit *eu; + const struct usb_audio_input_terminal_v1 *it; + const struct usb_audio_output_terminal_v1 *ot; + const struct usb_audio_mixer_unit_v1 *mu; + const struct usb_audio_selector_unit_v1 *su; + const struct usb_audio_feature_unit_v1 *fu; + const struct usb_audio_processing_unit_v1 *pu; + const struct usb_audio_extension_unit_v1 *eu; } d; int inputs_size; struct terminal_list **inputs; /* list of source input terminals */ @@ -732,7 +732,7 @@ uaudio_get_cluster(int id, const struct io_terminal *iot) Static void uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_input_terminal *d; + const struct usb_audio_input_terminal_v1 *d; d = iot[id].d.it; #ifdef UAUDIO_DEBUG @@ -754,7 +754,7 @@ uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { #ifdef UAUDIO_DEBUG - const struct usb_audio_output_terminal *d; + const struct usb_audio_output_terminal_v1 *d; d = iot[id].d.ot; DPRINTFN(2,"bTerminalID=%d wTerminalType=0x%04x " @@ -767,8 +767,8 @@ uaudio_add_output(struct uaudio_softc *sc, Static void uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_mixer_unit *d; - const struct usb_audio_mixer_unit_1 *d1; + const struct usb_audio_mixer_unit_v1 *d; + const struct usb_audio_mixer_unit_v1_1 *d1; int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; const uByte *bm; struct mixerctl mix; @@ -783,7 +783,7 @@ uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; /* and the number of output channels */ - d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; + d1 = (const struct usb_audio_mixer_unit_v1_1 *)&d->baSourceId[d->bNrInPins]; ochs = d1->bNrChannels; DPRINTFN(2,"ichs=%d ochs=%d\n", ichs, ochs); @@ -832,7 +832,7 @@ uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) Static void uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_selector_unit *d; + const struct usb_audio_selector_unit_v1 *d; struct mixerctl mix; int i, wp; @@ -1089,7 +1089,7 @@ uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) Static void uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_feature_unit *d; + const struct usb_audio_feature_unit_v1 *d; const uByte *ctls; int ctlsize; int nchan; @@ -1210,16 +1210,16 @@ Static void uaudio_add_processing_updown(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_processing_unit *d; - const struct usb_audio_processing_unit_1 *d1; - const struct usb_audio_processing_unit_updown *ud; + const struct usb_audio_processing_unit_v1 *d; + const struct usb_audio_processing_unit_v1_1 *d1; + const struct usb_audio_processing_unit_v1_updown *ud; struct mixerctl mix; int i; d = iot[id].d.pu; - d1 = (const struct usb_audio_processing_unit_1 *) + d1 = (const struct usb_audio_processing_unit_v1_1 *) &d->baSourceId[d->bNrInPins]; - ud = (const struct usb_audio_processing_unit_updown *) + ud = (const struct usb_audio_processing_unit_v1_updown *) &d1->bmControls[d1->bControlSize]; DPRINTFN(2,"bUnitID=%d bNrModes=%d\n", d->bUnitID, ud->bNrModes); @@ -1248,13 +1248,13 @@ uaudio_add_processing_updown(struct uaudio_softc *sc, Static void uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_processing_unit *d; - const struct usb_audio_processing_unit_1 *d1; + const struct usb_audio_processing_unit_v1 *d; + const struct usb_audio_processing_unit_v1_1 *d1; int ptype; struct mixerctl mix; d = iot[id].d.pu; - d1 = (const struct usb_audio_processing_unit_1 *) + d1 = (const struct usb_audio_processing_unit_v1_1 *) &d->baSourceId[d->bNrInPins]; ptype = UGETW(d->wProcessType); DPRINTFN(2,"wProcessType=%d bUnitID=%d " @@ -1294,12 +1294,12 @@ uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, in Static void uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id) { - const struct usb_audio_extension_unit *d; - const struct usb_audio_extension_unit_1 *d1; + const struct usb_audio_extension_unit_v1 *d; + const struct usb_audio_extension_unit_v1_1 *d1; struct mixerctl mix; d = iot[id].d.eu; - d1 = (const struct usb_audio_extension_unit_1 *) + d1 = (const struct usb_audio_extension_unit_v1_1 *) &d->baSourceId[d->bNrInPins]; DPRINTFN(2,"bUnitID=%d bNrInPins=%d\n", d->bUnitID, d->bNrInPins); @@ -1916,7 +1916,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc const usb_interface_descriptor_t *id; const struct usb_audio_control_descriptor_v1 *acdp; const uaudio_cs_descriptor_t *dp; - const struct usb_audio_output_terminal *pot; + const struct usb_audio_output_terminal_v1 *pot; struct terminal_list *tml; const char *tbuf, *ibuf, *ibufend; int size, offs, ndps, i, j; @@ -1970,7 +1970,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc } if (dp->bDescriptorType != UDESC_CS_INTERFACE) break; - i = ((const struct usb_audio_input_terminal *)dp)->bTerminalID; + i = ((const struct usb_audio_input_terminal_v1 *)dp)->bTerminalID; iot[i].d.desc = dp; if (i > ndps) ndps = i; diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index bbed3da0e545..f23840e1ec4f 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -187,7 +187,7 @@ struct usb_audio_unit { }; /* USB Audio 1.0, 4.3.2.1 Input Terminal Descriptor, pp. 38-39 */ -struct usb_audio_input_terminal { +struct usb_audio_input_terminal_v1 { uByte bLength; /* 12 */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_INPUT_TERMINAL */ @@ -199,10 +199,10 @@ struct usb_audio_input_terminal { uByte iChannelNames; uByte iTerminal; } UPACKED; -__CTASSERT(sizeof(struct usb_audio_input_terminal) == 12); +__CTASSERT(sizeof(struct usb_audio_input_terminal_v1) == 12); /* USB Audio 1.0, 4.3.2.2 Ouptut Terminal Descriptor, pp. 39-40 */ -struct usb_audio_output_terminal { +struct usb_audio_output_terminal_v1 { uByte bLength; /* 9 */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_OUTPUT_TERMINAL */ @@ -212,10 +212,10 @@ struct usb_audio_output_terminal { uByte bSourceId; uByte iTerminal; } UPACKED; -__CTASSERT(sizeof(struct usb_audio_output_terminal) == 9); +__CTASSERT(sizeof(struct usb_audio_output_terminal_v1) == 9); /* USB Audio 1.0, 4.3.2.3 Mixer Unit Descriptor, pp. 40-42 */ -struct usb_audio_mixer_unit { +struct usb_audio_mixer_unit_v1 { uByte bLength; /* 10 + .bNrInPins * + \sum .bNrChannels */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ @@ -225,7 +225,7 @@ struct usb_audio_mixer_unit { uByte baSourceId[255]; /* [bNrInPins] */ /* struct usb_audio_mixer_unit_1 */ } UPACKED; -struct usb_audio_mixer_unit_1 { +struct usb_audio_mixer_unit_v1_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; @@ -234,7 +234,7 @@ struct usb_audio_mixer_unit_1 { } UPACKED; /* USB Audio 1.0, 4.3.2.4 Selector Unit Descriptor, pp. 42-43 */ -struct usb_audio_selector_unit { +struct usb_audio_selector_unit_v1 { uByte bLength; /* 6 + .bNrInPins */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_SELECTOR_UNIT */ @@ -245,7 +245,7 @@ struct usb_audio_selector_unit { } UPACKED; /* USB Audio 1.0, 4.3.2.5 Feature Unit Descriptor, pp. 43-44 */ -struct usb_audio_feature_unit { +struct usb_audio_feature_unit_v1 { uByte bLength; /* 7 + (ch + 1)*n */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_FEATURE_UNIT */ @@ -257,7 +257,7 @@ struct usb_audio_feature_unit { } UPACKED; /* USB Audio 1.0, 4.3.2.6 Processing Unit Descriptor, pp. 44-45 */ -struct usb_audio_processing_unit { +struct usb_audio_processing_unit_v1 { uByte bLength; /* 13 + p + n + x */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype;/* UDESCSUB_AC_V1_PROCESSING_UNIT */ @@ -265,9 +265,9 @@ struct usb_audio_processing_unit { uWord wProcessType; uByte bNrInPins; /* p */ uByte baSourceId[255]; /* [bNrInPins] */ - /* struct usb_audio_processing_unit_1 */ + /* struct usb_audio_processing_unit_v1_1 */ } UPACKED; -struct usb_audio_processing_unit_1 { +struct usb_audio_processing_unit_v1_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; @@ -277,14 +277,14 @@ struct usb_audio_processing_unit_1 { } UPACKED; /* USB Audio 1.0, 4.3.2.6.1 Up/Down-mix Processing Unit Descriptor */ -struct usb_audio_processing_unit_updown { +struct usb_audio_processing_unit_v1_updown { uByte iProcessing; uByte bNrModes; uWord waModes[255]; /* [bNrModes] */ } UPACKED; /* USB Audio 1.0, 4.3.2.7 Extension Unit Descriptor, pp. 55-57 */ -struct usb_audio_extension_unit { +struct usb_audio_extension_unit_v1 { uByte bLength; /* 13 + p + n */ uByte bDescriptorType; /* UDESC_CS_INTERFACE */ uByte bDescriptorSubtype; /* UDESCSUB_AC_V1_EXTENSION_UNIT */ @@ -292,9 +292,9 @@ struct usb_audio_extension_unit { uWord wExtensionCode; uByte bNrInPins; /* p */ uByte baSourceId[255]; /* [bNrInPins] */ - /* struct usb_audio_extension_unit_1 */ + /* struct usb_audio_extension_unit_v1_1 */ } UPACKED; -struct usb_audio_extension_unit_1 { +struct usb_audio_extension_unit_v1_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; From 8dd46a3aa3f179338eee1bfdc0dc0c7a542029ea Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 5 Feb 2022 11:14:49 +0000 Subject: [PATCH 10/10] WIP: some usb audio v2 crap --- sys/dev/usb/uaudioreg.h | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index f23840e1ec4f..3d8164b8b304 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -103,6 +103,14 @@ typedef struct { uByte bDescriptorSubtype; } UPACKED uaudio_cs_descriptor_t; +/* Common structure for version detection in v1 and v2 */ +struct usb_audio_control_descriptor { + uByte bLength; + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_HEADER */ + uWord bcdADC; +} UPACKED; + /* USB Audio 1.0, 4.3.2 Class-Specific AC Interface Descriptor, p. 37 */ struct usb_audio_control_descriptor_v1 { uByte bLength; /* 8 + .bInCollection */ @@ -114,6 +122,64 @@ struct usb_audio_control_descriptor_v1 { uByte baInterfaceNr[1]; } UPACKED; +/* USB Audio 2.0, 4.7.2 Class-Specific AC Interface Descriptor, p. 48 */ +struct usb_audio_control_descriptor_v2 { + uByte bLength; /* 9 */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_HEADER */ + uWord bcdADC; + uByte bCategory; + uWord wTotalLength; + uByte bmControls; +#define USB_AUDIO_CONTROL(n) __BITS(2*(n), 2*(n) + 1) +#define USB_AUDIO_CONTROL_NONE 0 +#define USB_AUDIO_CONTROL_RO 1 +#define USB_AUDIO_CONTROL_RW 3 +} UPACKED; +__CTASSERT(sizeof(struct usb_audio_control_descriptor_v2) == 9); + +/* USB Audio 2.0, 4.7.2.1 Clock Source Descriptor, pp. 49-50 */ +struct usb_audio_clock_source_descriptor_v2 { + uByte bLength; /* 8 */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_V2_CLOCK_SOURCE */ + uByte bClockID; + uByte bmAttributes; + uByte bmControls; + uByte bAssocTerminal; + uByte iClockSource; +}; +__CTASSERT(sizeof(struct usb_audio_clock_source_descriptor_v2) == 8); + +/* USB Audio 2.0, 4.7.2.2 Clock Selector Descriptor, pp. 50-51 */ +struct usb_audio_clock_selector_descriptor_v2 { + uByte bLength; /* 7 + p */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; /* UDESCSUB_AC_V2_CLOCK_SELECTOR */ + uByte bClockID; + uByte bNrInPins; /* p */ + uByte baCSourceID[]; +}; +struct usb_audio_clock_selector_desctail_v2 { + uByte bmControls; + uByte iClockSelector; +}; +__CTASSERT(sizeof(struct usb_audio_clock_selector_descriptor_v2) == 5); +__CTASSERT(sizeof(struct usb_audio_clock_selector_desctail_v2) == 2); + +/* USB Audio 2.0, 4.7.2.3 Clock Multiplier Descriptor, pp. 51-52 */ +struct usb_audio_clock_multiplier_descriptor_v2 { + uByte bLength; /* 7 */ + uByte bDescriptorType; /* UDESC_CS_INTERFACE */ + uByte bDescriptorSubtype; + /* UDESCSUB_AC_V2_CLOCK_MULTIPLIER */ + uByte bClockID; + uByte bCSourceID; + uByte bmControls; + uByte iClockMultiplier; +}; +__CTASSERT(sizeof(struct usb_audio_clock_multiplier_descriptor_v2) == 7); + /* USB Audio 1.0, 4.5.2 Class-Specific AS Interface Descriptor, pp. 59-60 */ struct usb_audio_streaming_interface_descriptor { uByte bLength; /* 7 */