[PATCH 3/4] ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks

Cássio Gabriel
2026-04-19T20:31:36Z

Several US-16x08 mixer put callbacks log failed control URBs but
still return success to userspace. That hides device write failures
even though the requested value was not applied.

Return the negative write error instead in the route, master, bus,
channel, and EQ switch put callbacks.

Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/usb/mixer_us16x08.c | 49 +++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
index 8a02964e5d7b..fcf7dfa4aa84 100644
--- a/sound/usb/mixer_us16x08.c
+++ b/sound/usb/mixer_us16x08.c
@@ -224,14 +224,14 @@ static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,

err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));

- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
+ return err;
}

- return err > 0 ? 1 : 0;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
+ return 1;
}

static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
@@ -283,14 +283,14 @@ static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
buf[5] = index + 1;
err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));

- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
+ return err;
}

- return err > 0 ? 1 : 0;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
+ return 1;
}

static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
@@ -324,14 +324,14 @@ static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
break;
}

- if (err > 0) {
- elem->cached |= 1;
- elem->cache_val[0] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
+ return err;
}

- return err > 0 ? 1 : 0;
+ elem->cached |= 1;
+ elem->cache_val[0] = val;
+ return 1;
}

static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
@@ -392,14 +392,14 @@ static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol,

err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));

- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
+ return err;
}

- return err > 0 ? 1 : 0;
+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
+ return 1;
}

static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
@@ -529,13 +529,13 @@ static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
msleep(15);
}

- if (err > 0) {
- elem->cached |= 1 << index;
- elem->cache_val[index] = val;
- } else {
+ if (err < 0) {
usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
+ return err;
}

+ elem->cached |= 1 << index;
+ elem->cache_val[index] = val;
return 1;
}

@@ -1418,4 +1418,3 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)

return 0;
}
-

--
2.53.0