Skip to content

Commit

Permalink
ALSA: hda - Fix snd_hda_get_num_raw_conns() to return a correct value
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
tiwai committed Mar 12, 2013
1 parent 281a6ac commit b5f82b1
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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 (conn_list) {
if (conns >= max_conns)
return -ENOSPC;
conn_list[conns] = n;
}
conns++;
}
} else {
if (conn_list) {
if (conns >= max_conns)
return -ENOSPC;
conn_list[conns++] = n;
conn_list[conns] = val;
}
} else {
if (conns >= max_conns)
return -ENOSPC;
conn_list[conns++] = val;
conns++;
}
prev_nid = val;
}
Expand Down

0 comments on commit b5f82b1

Please sign in to comment.