Commit d2569505 authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[ALSA] hda-codec - Allocate connection lists dynamically in generic parser

Modules: HDA generic driver

Allocate connection lists dynamically in generic parser.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 54d17403
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
struct hda_gnode { struct hda_gnode {
hda_nid_t nid; /* NID of this widget */ hda_nid_t nid; /* NID of this widget */
unsigned short nconns; /* number of input connections */ unsigned short nconns; /* number of input connections */
hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; /* input connections */ hda_nid_t *conn_list;
hda_nid_t slist[2]; /* temporay list */
unsigned int wid_caps; /* widget capabilities */ unsigned int wid_caps; /* widget capabilities */
unsigned char type; /* widget type */ unsigned char type; /* widget type */
unsigned char pin_ctl; /* pin controls */ unsigned char pin_ctl; /* pin controls */
...@@ -84,6 +85,8 @@ static void snd_hda_generic_free(struct hda_codec *codec) ...@@ -84,6 +85,8 @@ static void snd_hda_generic_free(struct hda_codec *codec)
/* free all widgets */ /* free all widgets */
list_for_each_safe(p, n, &spec->nid_list) { list_for_each_safe(p, n, &spec->nid_list) {
struct hda_gnode *node = list_entry(p, struct hda_gnode, list); struct hda_gnode *node = list_entry(p, struct hda_gnode, list);
if (node->conn_list != node->slist)
kfree(node->conn_list);
kfree(node); kfree(node);
} }
kfree(spec); kfree(spec);
...@@ -97,18 +100,32 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid ...@@ -97,18 +100,32 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
{ {
struct hda_gnode *node; struct hda_gnode *node;
int nconns; int nconns;
hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
node = kzalloc(sizeof(*node), GFP_KERNEL); node = kzalloc(sizeof(*node), GFP_KERNEL);
if (node == NULL) if (node == NULL)
return -ENOMEM; return -ENOMEM;
node->nid = nid; node->nid = nid;
nconns = snd_hda_get_connections(codec, nid, node->conn_list, HDA_MAX_CONNECTIONS); nconns = snd_hda_get_connections(codec, nid, conn_list,
HDA_MAX_CONNECTIONS);
if (nconns < 0) { if (nconns < 0) {
kfree(node); kfree(node);
return nconns; return nconns;
} }
if (nconns <= ARRAY_SIZE(node->slist))
node->conn_list = node->slist;
else {
node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns,
GFP_KERNEL);
if (! node->conn_list) {
snd_printk(KERN_ERR "hda-generic: cannot malloc\n");
kfree(node);
return -ENOMEM;
}
}
memcpy(node->conn_list, conn_list, nconns);
node->nconns = nconns; node->nconns = nconns;
node->wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); node->wid_caps = get_wcaps(codec, nid);
node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
if (node->type == AC_WID_PIN) { if (node->type == AC_WID_PIN) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment