ALSA: usb-audio: Propagate write errors in generic mixer put callbacks

mixer_ctl_feature_put(), mixer_ctl_procunit_put(), and
mixer_ctl_selector_put() ignore failures from their SET_CUR helper
routines and report the control as changed whenever the requested
value differs from the current one.

If the device rejects the write, userspace still sees success although
the hardware state did not change. Propagate write failures instead,
using filter_error() so ignore_ctl_error keeps the same semantics as
the existing get paths.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260419-usb-write-error-propagation-v1-1-5a3bd4a673ae@gmail.com
This commit is contained in:
Cássio Gabriel 2026-04-19 17:30:29 -03:00 committed by Takashi Iwai
parent b3163bf3ad
commit 87a6f2fa6e

View File

@ -1526,7 +1526,10 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
val = get_abs_value(cval, val);
if (oval != val) {
snd_usb_set_cur_mix_value(cval, c + 1, cnt, val);
err = snd_usb_set_cur_mix_value(cval, c + 1,
cnt, val);
if (err < 0)
return filter_error(cval, err);
changed = 1;
}
cnt++;
@ -1541,7 +1544,9 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
val = get_abs_value(cval, val);
if (val != oval) {
snd_usb_set_cur_mix_value(cval, 0, 0, val);
err = snd_usb_set_cur_mix_value(cval, 0, 0, val);
if (err < 0)
return filter_error(cval, err);
changed = 1;
}
}
@ -2466,7 +2471,9 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
val = get_abs_value(cval, val);
if (val != oval) {
set_cur_ctl_value(cval, cval->control << 8, val);
err = set_cur_ctl_value(cval, cval->control << 8, val);
if (err < 0)
return filter_error(cval, err);
return 1;
}
return 0;
@ -2832,7 +2839,9 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
val = get_abs_value(cval, val);
if (val != oval) {
set_cur_ctl_value(cval, cval->control << 8, val);
err = set_cur_ctl_value(cval, cval->control << 8, val);
if (err < 0)
return filter_error(cval, err);
return 1;
}
return 0;