diff options
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r-- | sound/usb/mixer.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 81b2db0edd5f..721d12130d0c 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -292,6 +292,11 @@ static int uac2_ctl_value_size(int val_type) * retrieve a mixer value */ +static inline int mixer_ctrl_intf(struct usb_mixer_interface *mixer) +{ + return get_iface_desc(mixer->hostif)->bInterfaceNumber; +} + static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) { @@ -306,7 +311,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, return -EIO; while (timeout-- > 0) { - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx, idx, buf, val_len); @@ -354,7 +359,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, if (ret) goto error; - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx, idx, buf, size); @@ -479,7 +484,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, return -EIO; while (timeout-- > 0) { - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, @@ -901,6 +906,12 @@ static int parse_term_effect_unit(struct mixer_build *state, struct usb_audio_term *term, void *p1, int id) { + struct uac2_effect_unit_descriptor *d = p1; + int err; + + err = __check_input_term(state, d->bSourceID, term); + if (err < 0) + return err; term->type = UAC3_EFFECT_UNIT << 16; /* virtual type */ term->id = id; return 0; @@ -1203,7 +1214,7 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { usb_audio_err(cval->head.mixer->chip, "%d:%d: cannot get min/max values for control %d (id %d)\n", - cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip), + cval->head.id, mixer_ctrl_intf(cval->head.mixer), cval->control, cval->head.id); return -EINVAL; } @@ -1422,7 +1433,7 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol, if (ret) goto error; - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); if (cval->head.mixer->protocol == UAC_VERSION_2) { struct uac2_connectors_ctl_blk uac2_conn; @@ -1674,6 +1685,16 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer, /* get min/max values */ get_min_max_with_quirks(cval, 0, kctl); + /* skip a bogus volume range */ + if (cval->max <= cval->min) { + usb_audio_dbg(mixer->chip, + "[%d] FU [%s] skipped due to invalid volume\n", + cval->head.id, kctl->id.name); + snd_ctl_free_one(kctl); + return; + } + + if (control == UAC_FU_VOLUME) { check_mapped_dB(map, cval); if (cval->dBmin < cval->dBmax || !cval->initialized) { @@ -3203,7 +3224,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, list_for_each_entry(mixer, &chip->mixer_list, list) { snd_iprintf(buffer, "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n", - chip->usb_id, snd_usb_ctrl_intf(chip), + chip->usb_id, mixer_ctrl_intf(mixer), mixer->ignore_ctl_error); snd_iprintf(buffer, "Card: %s\n", chip->card->longname); for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { |