ALSA: hda: Fix regression of hdmi eld control created based on invalid pcm
authorWang YanQing <udknight@gmail.com>
Sun, 3 Sep 2017 13:18:49 +0000 (21:18 +0800)
committerTakashi Iwai <tiwai@suse.de>
Sun, 3 Sep 2017 14:33:42 +0000 (16:33 +0200)
Commit fb087eaaef72 ("ALSA: hda - hdmi eld control created based on pcm")
forget to filter out invalid pcm numbers, if there is only one invalid pcm
number, then this issue causes we create eld control for invalid pcm silently,
but when there are more than one invalid pcm numbers, then this issue bring
probe error looks like below dmesg:
"
kernel: [    1.647283] snd_hda_intel 0000:00:03.0: bound 0000:00:02.0 (ops 0xc2967540)
kernel: [    1.651192] snd_hda_intel 0000:00:03.0: Too many HDMI devices
kernel: [    1.651195] snd_hda_intel 0000:00:03.0: Consider building the kernel with CONFIG_SND_DYNAMIC_MINORS=y
kernel: [    1.651197] snd_hda_intel 0000:00:03.0: Too many HDMI devices
kernel: [    1.651199] snd_hda_intel 0000:00:03.0: Consider building the kernel with CONFIG_SND_DYNAMIC_MINORS=y
kernel: [    1.651201] snd_hda_intel 0000:00:03.0: Too many HDMI devices
kernel: [    1.651203] snd_hda_intel 0000:00:03.0: Consider building the kernel with CONFIG_SND_DYNAMIC_MINORS=y
kernel: [    1.651676] snd_hda_intel 0000:00:03.0: control 3:0:0:ELD:0 is already present
kernel: [    1.651787] snd_hda_codec_hdmi: probe of hdaudioC0D0 failed with error -16
"

This patch add invalid pcm number filter before calling hdmi_create_eld_ctl.

Fixes: fb087eaaef72 ("ALSA: hda - hdmi eld control created based on pcm")
Signed-off-by: Wang YanQing <udknight@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/patch_hdmi.c

index 821aad374a0695a46c4c265365b71a81aa134412..3db26c451837cf0e2893d1071c1a699465d89e1b 100644 (file)
@@ -3213,8 +3213,10 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
                        continue; /* no substreams assigned */
 
                dev = get_empty_pcm_device(bus, cpcm->pcm_type);
-               if (dev < 0)
+               if (dev < 0) {
+                       cpcm->device = SNDRV_PCM_INVALID_DEVICE;
                        continue; /* no fatal error */
+               }
                cpcm->device = dev;
                err =  snd_hda_attach_pcm_stream(bus, codec, cpcm);
                if (err < 0) {
index 60ce1cfc300f9cb419acbc67425076c120829f13..681c360f29f9d628cf4462c9bb7ef92879f27d91 100644 (file)
@@ -164,6 +164,7 @@ enum {
        HDA_PCM_NTYPES
 };
 
+#define SNDRV_PCM_INVALID_DEVICE       (-1)
 /* for PCM creation */
 struct hda_pcm {
        char *name;
index 53f9311370dec18fabdc0cb03820f7f24c1dab1d..2b64fabd5faa5f1e85681592910fd61ad2aa89f9 100644 (file)
@@ -2126,7 +2126,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
 static int generic_hdmi_build_controls(struct hda_codec *codec)
 {
        struct hdmi_spec *spec = codec->spec;
-       int err;
+       int dev, err;
        int pin_idx, pcm_idx;
 
 
@@ -2154,11 +2154,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
                        return err;
                snd_hda_spdif_ctls_unassign(codec, pcm_idx);
 
-               /* add control for ELD Bytes */
-               err = hdmi_create_eld_ctl(codec, pcm_idx,
-                                       get_pcm_rec(spec, pcm_idx)->device);
-               if (err < 0)
-                       return err;
+               dev = get_pcm_rec(spec, pcm_idx)->device;
+               if (dev != SNDRV_PCM_INVALID_DEVICE) {
+                       /* add control for ELD Bytes */
+                       err = hdmi_create_eld_ctl(codec, pcm_idx, dev);
+                       if (err < 0)
+                               return err;
+               }
        }
 
        for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {