]> www.infradead.org Git - linux.git/commitdiff
ALSA: hda: Return -EINVAL for invalid volume/switch inputs
authorTakashi Iwai <tiwai@suse.de>
Sun, 16 Jun 2024 07:34:43 +0000 (09:34 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 18 Jun 2024 10:00:18 +0000 (12:00 +0200)
So far the HD-audio driver has been tolerant about the input values
and accepts any values by correcting the amp volume and switch values
internally.  But now our own selftest starts complaining about this
behavior, so let's be picky and change the behavior to return -EINVAL
for invalid input values instead.

Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
Closes: https://lore.kernel.org/r/1d44be36-9bb9-4d82-8953-5ae2a4f09405@molgen.mpg.de
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/20240616073454.16512-3-tiwai@suse.de
sound/pci/hda/hda_codec.c

index 325e8f0b99a82911f8509490de7b725a44f7e3b5..3dd1bda0c5c69ef4be01b9e40d3d08124f30792e 100644 (file)
@@ -1496,7 +1496,7 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid,
        /* ofs = 0: raw max value */
        maxval = get_amp_max_value(codec, nid, dir, 0);
        if (val > maxval)
-               val = maxval;
+               return -EINVAL;
        return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
                                        HDA_AMP_VOLMASK, val);
 }
@@ -1547,13 +1547,21 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
        unsigned int ofs = get_amp_offset(kcontrol);
        long *valp = ucontrol->value.integer.value;
        int change = 0;
+       int err;
 
        if (chs & 1) {
-               change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
+               err = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
+               if (err < 0)
+                       return err;
+               change |= err;
                valp++;
        }
-       if (chs & 2)
-               change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
+       if (chs & 2) {
+               err = update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
+               if (err < 0)
+                       return err;
+               change |= err;
+       }
        return change;
 }
 EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put);
@@ -2149,15 +2157,20 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
        int change = 0;
 
        if (chs & 1) {
+               if (*valp < 0 || *valp > 1)
+                       return -EINVAL;
                change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
                                                  HDA_AMP_MUTE,
                                                  *valp ? 0 : HDA_AMP_MUTE);
                valp++;
        }
-       if (chs & 2)
+       if (chs & 2) {
+               if (*valp < 0 || *valp > 1)
+                       return -EINVAL;
                change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
                                                   HDA_AMP_MUTE,
                                                   *valp ? 0 : HDA_AMP_MUTE);
+       }
        hda_call_check_power_status(codec, nid);
        return change;
 }