From 92f1dbc3d652771285780c7a3b56e8d6a8c109b8 Mon Sep 17 00:00:00 2001 From: hselasky Date: Mon, 13 Apr 2020 16:26:15 +0000 Subject: [PATCH] MFC r359323: Be more intelligent when classifying USB audio terminal types, so that we don't end up using SOUND_MIXER_VOLUME for all undefined types. Sponsored by: Mellanox Technologies git-svn-id: svn://svn.freebsd.org/base/stable/10@359878 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/sound/usb/uaudio.c | 63 ++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 065774421..03c518698 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -4515,52 +4515,61 @@ static const struct uaudio_tt_to_feature uaudio_tt_to_feature[] = { {UATF_MULTITRACK, SOUND_MIXER_VOLUME}, {0xffff, SOUND_MIXER_VOLUME}, - /* default */ - {0x0000, SOUND_MIXER_VOLUME}, + /* end */ + {} }; static uint16_t -uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot, - struct uaudio_mixer_node *mix) +uaudio_mixer_feature_name_sub(uint16_t terminal_type) { const struct uaudio_tt_to_feature *uat = uaudio_tt_to_feature; - uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix); - - if ((mix->class == UAC_RECORD) && (terminal_type == 0)) { - return (SOUND_MIXER_IMIX); - } - while (uat->terminal_type) { - if (uat->terminal_type == terminal_type) { - break; + uint16_t retval; + + while (1) { + if (uat->terminal_type == 0) { + switch (terminal_type >> 8) { + case UATI_UNDEFINED >> 8: + retval = SOUND_MIXER_RECLEV; + goto done; + case UATO_UNDEFINED >> 8: + retval = SOUND_MIXER_PCM; + goto done; + default: + retval = SOUND_MIXER_VOLUME; + goto done; + } + } else if (uat->terminal_type == terminal_type) { + retval = uat->feature; + goto done; } uat++; } - +done: DPRINTF("terminal_type=0x%04x -> %d\n", - terminal_type, uat->feature); + terminal_type, retval); + return (retval); +} - return (uat->feature); +static uint16_t +uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot, + struct uaudio_mixer_node *mix) +{ + uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix); + + if (mix->class == UAC_RECORD && terminal_type == 0) + return (SOUND_MIXER_IMIX); + return (uaudio_mixer_feature_name_sub(terminal_type)); } static uint16_t uaudio20_mixer_feature_name(const struct uaudio_terminal_node *iot, struct uaudio_mixer_node *mix) { - const struct uaudio_tt_to_feature *uat; uint16_t terminal_type = uaudio20_mixer_determine_class(iot, mix); - if ((mix->class == UAC_RECORD) && (terminal_type == 0)) + if (mix->class == UAC_RECORD && terminal_type == 0) return (SOUND_MIXER_IMIX); - - for (uat = uaudio_tt_to_feature; uat->terminal_type != 0; uat++) { - if (uat->terminal_type == terminal_type) - break; - } - - DPRINTF("terminal_type=0x%04x -> %d\n", - terminal_type, uat->feature); - - return (uat->feature); + return (uaudio_mixer_feature_name_sub(terminal_type)); } static const struct uaudio_terminal_node * -- 2.42.0