ALSA: hda - Fix snd_hda_get_num_raw_conns() to return a correct value
In the connection list expansion in hda_codec.c and hda_proc.c, the value returned from snd_hda_get_num_raw_conns() is used as the array size to store the connection list. However, the function returns simply a raw value of the AC_PAR_CONNLIST_LEN parameter, and the widget list with ranges isn't considered there. Thus it may return a smaller size than the actual list, which results in -ENOSPC in snd_hda_get_raw_conections(). This patch fixes the bug by parsing the connection list correctly also for snd_hda_get_num_raw_conns(). Reported-and-tested-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
281a6ac0f5
commit
b5f82b1044
|
@ -494,7 +494,7 @@ static unsigned int get_num_conns(struct hda_codec *codec, hda_nid_t nid)
|
|||
|
||||
int snd_hda_get_num_raw_conns(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
return get_num_conns(codec, nid) & AC_CLIST_LENGTH;
|
||||
return snd_hda_get_raw_connections(codec, nid, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -517,9 +517,6 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
|
|||
hda_nid_t prev_nid;
|
||||
int null_count = 0;
|
||||
|
||||
if (snd_BUG_ON(!conn_list || max_conns <= 0))
|
||||
return -EINVAL;
|
||||
|
||||
parm = get_num_conns(codec, nid);
|
||||
if (!parm)
|
||||
return 0;
|
||||
|
@ -545,7 +542,8 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
|
|||
AC_VERB_GET_CONNECT_LIST, 0);
|
||||
if (parm == -1 && codec->bus->rirb_error)
|
||||
return -EIO;
|
||||
conn_list[0] = parm & mask;
|
||||
if (conn_list)
|
||||
conn_list[0] = parm & mask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -580,14 +578,20 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
|
|||
continue;
|
||||
}
|
||||
for (n = prev_nid + 1; n <= val; n++) {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns++] = n;
|
||||
if (conn_list) {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns] = n;
|
||||
}
|
||||
conns++;
|
||||
}
|
||||
} else {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns++] = val;
|
||||
if (conn_list) {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns] = val;
|
||||
}
|
||||
conns++;
|
||||
}
|
||||
prev_nid = val;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue