diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 654dc8935c915b7561793d47749575335fbb9c80..26c420de91c3c3eeb88777f847ae962ba984df40 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -311,35 +311,35 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); static bool add_conn_list(struct snd_array *array, hda_nid_t nid); -static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, - hda_nid_t *src, int len); /** * snd_hda_get_connections - get connection list * @codec: the HDA codec * @nid: NID to parse - * @conn_list: connection list array - * @max_conns: max. number of connections to store + * @listp: the pointer to store NID list * * Parses the connection list of the given widget and stores the list * of NIDs. * * Returns the number of connections, or a negative error code. */ -int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, - hda_nid_t *conn_list, int max_conns) +int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, + const hda_nid_t **listp) { struct snd_array *array = &codec->conn_lists; int i, len, old_used; hda_nid_t list[HDA_MAX_CONNECTIONS]; + hda_nid_t *p; /* look up the cached results */ for (i = 0; i < array->used; ) { - hda_nid_t *p = snd_array_elem(array, i); + p = snd_array_elem(array, i); len = p[1]; - if (nid == *p) - return copy_conn_list(nid, conn_list, max_conns, - p + 2, len); + if (nid == *p) { + if (listp) + *listp = p + 2; + return len; + } i += len + 2; } @@ -355,12 +355,46 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, if (!add_conn_list(array, list[i])) goto error_add; - return copy_conn_list(nid, conn_list, max_conns, list, len); + p = snd_array_elem(array, old_used); + if (listp) + *listp = p + 2; + return len; error_add: array->used = old_used; return -ENOMEM; } +EXPORT_SYMBOL_HDA(snd_hda_get_conn_list); + +/** + * snd_hda_get_connections - copy connection list + * @codec: the HDA codec + * @nid: NID to parse + * @conn_list: connection list array + * @max_conns: max. number of connections to store + * + * Parses the connection list of the given widget and stores the list + * of NIDs. + * + * Returns the number of connections, or a negative error code. + */ +int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *conn_list, int max_conns) +{ + const hda_nid_t *list; + int len = snd_hda_get_conn_list(codec, nid, &list); + + if (len <= 0) + return len; + if (len > max_conns) { + snd_printk(KERN_ERR "hda_codec: " + "Too many connections %d for NID 0x%x\n", + len, nid); + return -EINVAL; + } + memcpy(conn_list, list, len * sizeof(hda_nid_t)); + return len; +} EXPORT_SYMBOL_HDA(snd_hda_get_connections); static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, @@ -471,19 +505,6 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid) return true; } -static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, - hda_nid_t *src, int len) -{ - if (len > max_dst) { - snd_printk(KERN_ERR "hda_codec: " - "Too many connections %d for NID 0x%x\n", - len, nid); - return -EINVAL; - } - memcpy(dst, src, len * sizeof(hda_nid_t)); - return len; -} - /** * snd_hda_queue_unsol_event - add an unsolicited event to queue * @bus: the BUS diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 070efac7e20710fb94a2424b277538ff1c04eb2e..c71cd7fb6d11c8924dff64981d97c33ebbd869ee 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -903,6 +903,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); +int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, + const hda_nid_t **listp); int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, u32 *ratesp, u64 *formatsp, unsigned int *bpsp);