mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 12:31:52 -04:00
ALSA: usb-audio: Add error checks against get_min_max*()
All callers of get_min_max*() ignore the latter's return code completely. This means to ignore temporary errors at the probe time. However, it is not optimal and leads to some maintenance burdens. Return -EAGAIN for temporary errors, and check against it in the callers of get_min_max*(). If any other error occurs, bail out of the caller early. Suggested-by: Takashi Iwai <tiwai@suse.de> Link: https://lore.kernel.org/r/87ldewi4j8.wl-tiwai@suse.de Signed-off-by: Rong Zhang <i@rong.moe> Link: https://patch.msgid.link/20260411-uac-sticky-mixer-v1-1-29d62717befd@rong.moe Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
@@ -1264,7 +1264,7 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
|
|||||||
"%d:%d: cannot get min/max values for control %d (id %d)\n",
|
"%d:%d: cannot get min/max values for control %d (id %d)\n",
|
||||||
cval->head.id, mixer_ctrl_intf(cval->head.mixer),
|
cval->head.id, mixer_ctrl_intf(cval->head.mixer),
|
||||||
cval->control, cval->head.id);
|
cval->control, cval->head.id);
|
||||||
return -EINVAL;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (get_ctl_value(cval, UAC_GET_RES,
|
if (get_ctl_value(cval, UAC_GET_RES,
|
||||||
(cval->control << 8) | minchn,
|
(cval->control << 8) | minchn,
|
||||||
@@ -1388,6 +1388,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,
|
|||||||
struct snd_ctl_elem_info *uinfo)
|
struct snd_ctl_elem_info *uinfo)
|
||||||
{
|
{
|
||||||
struct usb_mixer_elem_info *cval = snd_kcontrol_chip(kcontrol);
|
struct usb_mixer_elem_info *cval = snd_kcontrol_chip(kcontrol);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (cval->val_type == USB_MIXER_BOOLEAN ||
|
if (cval->val_type == USB_MIXER_BOOLEAN ||
|
||||||
cval->val_type == USB_MIXER_INV_BOOLEAN)
|
cval->val_type == USB_MIXER_INV_BOOLEAN)
|
||||||
@@ -1398,8 +1399,9 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,
|
|||||||
if (cval->val_type != USB_MIXER_BOOLEAN &&
|
if (cval->val_type != USB_MIXER_BOOLEAN &&
|
||||||
cval->val_type != USB_MIXER_INV_BOOLEAN) {
|
cval->val_type != USB_MIXER_INV_BOOLEAN) {
|
||||||
if (!cval->initialized) {
|
if (!cval->initialized) {
|
||||||
get_min_max_with_quirks(cval, 0, kcontrol);
|
ret = get_min_max_with_quirks(cval, 0, kcontrol);
|
||||||
if (cval->initialized && cval->dBmin >= cval->dBmax) {
|
if ((ret >= 0 || ret == -EAGAIN) &&
|
||||||
|
cval->initialized && cval->dBmin >= cval->dBmax) {
|
||||||
kcontrol->vd[0].access &=
|
kcontrol->vd[0].access &=
|
||||||
~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
|
~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
|
||||||
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
|
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
|
||||||
@@ -1743,6 +1745,7 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer,
|
|||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
struct usb_mixer_elem_info *cval;
|
struct usb_mixer_elem_info *cval;
|
||||||
const struct usbmix_name_map *map;
|
const struct usbmix_name_map *map;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (control == UAC_FU_GRAPHIC_EQUALIZER) {
|
if (control == UAC_FU_GRAPHIC_EQUALIZER) {
|
||||||
/* FIXME: not supported yet */
|
/* FIXME: not supported yet */
|
||||||
@@ -1856,10 +1859,10 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get min/max values */
|
/* get min/max values */
|
||||||
get_min_max_with_quirks(cval, 0, kctl);
|
ret = get_min_max_with_quirks(cval, 0, kctl);
|
||||||
|
|
||||||
/* skip a bogus volume range */
|
/* skip a bogus volume range */
|
||||||
if (cval->max <= cval->min) {
|
if ((ret < 0 && ret != -EAGAIN) || cval->max <= cval->min) {
|
||||||
usb_audio_dbg(mixer->chip,
|
usb_audio_dbg(mixer->chip,
|
||||||
"[%d] FU [%s] skipped due to invalid volume\n",
|
"[%d] FU [%s] skipped due to invalid volume\n",
|
||||||
cval->head.id, kctl->id.name);
|
cval->head.id, kctl->id.name);
|
||||||
@@ -2233,6 +2236,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
|
|||||||
unsigned int i, len;
|
unsigned int i, len;
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
const struct usbmix_name_map *map;
|
const struct usbmix_name_map *map;
|
||||||
|
int ret;
|
||||||
|
|
||||||
map = find_map(state->map, unitid, 0);
|
map = find_map(state->map, unitid, 0);
|
||||||
if (check_ignored_ctl(map))
|
if (check_ignored_ctl(map))
|
||||||
@@ -2255,7 +2259,11 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get min/max values */
|
/* get min/max values */
|
||||||
get_min_max(cval, 0);
|
ret = get_min_max(cval, 0);
|
||||||
|
if (ret < 0 && ret != -EAGAIN) {
|
||||||
|
usb_mixer_elem_info_free(cval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
|
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
|
||||||
if (!kctl) {
|
if (!kctl) {
|
||||||
@@ -2627,7 +2635,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_min_max(cval, valinfo->min_value);
|
err = get_min_max(cval, valinfo->min_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_XU_CLOCK_RATE:
|
case USB_XU_CLOCK_RATE:
|
||||||
@@ -2639,11 +2647,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
|
|||||||
cval->max = 5;
|
cval->max = 5;
|
||||||
cval->res = 1;
|
cval->res = 1;
|
||||||
cval->initialized = 1;
|
cval->initialized = 1;
|
||||||
|
err = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
get_min_max(cval, valinfo->min_value);
|
err = get_min_max(cval, valinfo->min_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (err < 0 && err != -EAGAIN) {
|
||||||
|
usb_mixer_elem_info_free(cval);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
err = get_cur_ctl_value(cval, cval->control << 8, &val);
|
err = get_cur_ctl_value(cval, cval->control << 8, &val);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user