aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_proc.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-02-07 12:18:19 -0500
committerTakashi Iwai <tiwai@suse.de>2013-02-07 14:01:08 -0500
commit4eea30914facd2c99061cd70e5b05d3c76c743a2 (patch)
treeb65f4322f33b80f20211962fe337d4eb2b50b630 /sound/pci/hda/hda_proc.c
parentc1279f8787f9cddd2f4a7d6abc15375b30b80501 (diff)
ALSA: hda - Remove limit of widget connections
Currently we set the max number of connections to be 32, but there seems codec that gives longer connection lists like AD1988, and we see errors in proc output and else. (Though, in the case of AD1988, it's a list of all codecs connected to a single vendor widget, so this must be something fishy, but it's still valid from the h/w design POV.) This patch tries to remove this restriction. For efficiency, we still use the fixed size array in the parser, but takes a dynamic array when the size is reported to be greater than that. Now the fixed array size is found only in patch_hdmi.c, but it should be fine, as the codec itself can't support so many pins. Reported-by: Raymond Yau <superquad.vortex2@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_proc.c')
-rw-r--r--sound/pci/hda/hda_proc.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 5e02f26606b6..0fee8fae590a 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/slab.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include "hda_codec.h" 27#include "hda_codec.h"
27#include "hda_local.h" 28#include "hda_local.h"
@@ -623,7 +624,7 @@ static void print_codec_info(struct snd_info_entry *entry,
623 snd_hda_param_read(codec, nid, 624 snd_hda_param_read(codec, nid,
624 AC_PAR_AUDIO_WIDGET_CAP); 625 AC_PAR_AUDIO_WIDGET_CAP);
625 unsigned int wid_type = get_wcaps_type(wid_caps); 626 unsigned int wid_type = get_wcaps_type(wid_caps);
626 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 627 hda_nid_t *conn = NULL;
627 int conn_len = 0; 628 int conn_len = 0;
628 629
629 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, 630 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
@@ -660,9 +661,18 @@ static void print_codec_info(struct snd_info_entry *entry,
660 if (wid_type == AC_WID_VOL_KNB) 661 if (wid_type == AC_WID_VOL_KNB)
661 wid_caps |= AC_WCAP_CONN_LIST; 662 wid_caps |= AC_WCAP_CONN_LIST;
662 663
663 if (wid_caps & AC_WCAP_CONN_LIST) 664 if (wid_caps & AC_WCAP_CONN_LIST) {
664 conn_len = snd_hda_get_raw_connections(codec, nid, conn, 665 conn_len = snd_hda_get_num_raw_conns(codec, nid);
665 HDA_MAX_CONNECTIONS); 666 if (conn_len > 0) {
667 conn = kmalloc(sizeof(hda_nid_t) * conn_len,
668 GFP_KERNEL);
669 if (!conn)
670 return;
671 if (snd_hda_get_raw_connections(codec, nid, conn,
672 conn_len) < 0)
673 conn_len = 0;
674 }
675 }
666 676
667 if (wid_caps & AC_WCAP_IN_AMP) { 677 if (wid_caps & AC_WCAP_IN_AMP) {
668 snd_iprintf(buffer, " Amp-In caps: "); 678 snd_iprintf(buffer, " Amp-In caps: ");
@@ -735,6 +745,8 @@ static void print_codec_info(struct snd_info_entry *entry,
735 745
736 if (codec->proc_widget_hook) 746 if (codec->proc_widget_hook)
737 codec->proc_widget_hook(buffer, codec, nid); 747 codec->proc_widget_hook(buffer, codec, nid);
748
749 kfree(conn);
738 } 750 }
739 snd_hda_power_down(codec); 751 snd_hda_power_down(codec);
740} 752}