diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-21 10:33:51 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:29:28 -0500 |
commit | d25695056ff2e1e048cfc8d7dbafaf80c3c46d5d (patch) | |
tree | d639f0a40b176de26140428c1d4107c4546911f3 /sound/pci/hda/hda_generic.c | |
parent | 54d174031576a2855c49611d83d4946bde81b504 (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.c | 23 |
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 @@ | |||
32 | struct hda_gnode { | 32 | struct 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) { |