aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_generic.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-21 10:33:51 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:29:28 -0500
commitd25695056ff2e1e048cfc8d7dbafaf80c3c46d5d (patch)
treed639f0a40b176de26140428c1d4107c4546911f3 /sound/pci/hda/hda_generic.c
parent54d174031576a2855c49611d83d4946bde81b504 (diff)
[ALSA] hda-codec - Allocate connection lists dynamically in generic parser
Modules: HDA generic driver Allocate connection lists dynamically in generic parser. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r--sound/pci/hda/hda_generic.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 863e8c6d29a8..39edfcfd3abd 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -32,7 +32,8 @@
32struct hda_gnode { 32struct hda_gnode {
33 hda_nid_t nid; /* NID of this widget */ 33 hda_nid_t nid; /* NID of this widget */
34 unsigned short nconns; /* number of input connections */ 34 unsigned short nconns; /* number of input connections */
35 hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; /* input connections */ 35 hda_nid_t *conn_list;
36 hda_nid_t slist[2]; /* temporay list */
36 unsigned int wid_caps; /* widget capabilities */ 37 unsigned int wid_caps; /* widget capabilities */
37 unsigned char type; /* widget type */ 38 unsigned char type; /* widget type */
38 unsigned char pin_ctl; /* pin controls */ 39 unsigned char pin_ctl; /* pin controls */
@@ -84,6 +85,8 @@ static void snd_hda_generic_free(struct hda_codec *codec)
84 /* free all widgets */ 85 /* free all widgets */
85 list_for_each_safe(p, n, &spec->nid_list) { 86 list_for_each_safe(p, n, &spec->nid_list) {
86 struct hda_gnode *node = list_entry(p, struct hda_gnode, list); 87 struct hda_gnode *node = list_entry(p, struct hda_gnode, list);
88 if (node->conn_list != node->slist)
89 kfree(node->conn_list);
87 kfree(node); 90 kfree(node);
88 } 91 }
89 kfree(spec); 92 kfree(spec);
@@ -97,18 +100,32 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
97{ 100{
98 struct hda_gnode *node; 101 struct hda_gnode *node;
99 int nconns; 102 int nconns;
103 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
100 104
101 node = kzalloc(sizeof(*node), GFP_KERNEL); 105 node = kzalloc(sizeof(*node), GFP_KERNEL);
102 if (node == NULL) 106 if (node == NULL)
103 return -ENOMEM; 107 return -ENOMEM;
104 node->nid = nid; 108 node->nid = nid;
105 nconns = snd_hda_get_connections(codec, nid, node->conn_list, HDA_MAX_CONNECTIONS); 109 nconns = snd_hda_get_connections(codec, nid, conn_list,
110 HDA_MAX_CONNECTIONS);
106 if (nconns < 0) { 111 if (nconns < 0) {
107 kfree(node); 112 kfree(node);
108 return nconns; 113 return nconns;
109 } 114 }
115 if (nconns <= ARRAY_SIZE(node->slist))
116 node->conn_list = node->slist;
117 else {
118 node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns,
119 GFP_KERNEL);
120 if (! node->conn_list) {
121 snd_printk(KERN_ERR "hda-generic: cannot malloc\n");
122 kfree(node);
123 return -ENOMEM;
124 }
125 }
126 memcpy(node->conn_list, conn_list, nconns);
110 node->nconns = nconns; 127 node->nconns = nconns;
111 node->wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 128 node->wid_caps = get_wcaps(codec, nid);
112 node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 129 node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
113 130
114 if (node->type == AC_WID_PIN) { 131 if (node->type == AC_WID_PIN) {