ALSA: hda - Add snd_hda_get_conn_list() helper function
Takashi Iwai [Fri, 24 Jun 2011 12:10:28 +0000 (14:10 +0200)]
Add a new helper function snd_hda_get_conn_list().
Unlike snd_hda_get_connections(), this function doesn't copy the
connection-list but gives the raw pointer for the cached list.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h

index 654dc89..26c420d 100644 (file)
@@ -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
index 070efac..c71cd7f 100644 (file)
@@ -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);