ALSA: info: Register proc entries recursively, too
authorTakashi Iwai <tiwai@suse.de>
Mon, 18 May 2015 07:20:24 +0000 (09:20 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 18 May 2015 07:20:24 +0000 (09:20 +0200)
The commit [c560a6797e3b: ALSA: core: Remove child proc file elements
recursively] converted snd_card_proc_new() with the normal
snd_info_*() call and removed snd_device chain for such info
entries. However, it misses one point: the creation of the proc entry
was managed by snd_device chain in the former code, and now it's also
gone, which results in no proc files creation at all.  Mea culpa.

This patch makes snd_info_card_register() creating the all pending
child proc entries in a shot.  Also, since snd_card_register() might
be called multiple times, this function is also changed to be callable
multiple times.

Along with the changes above, now the linked list of snd_info_entry is
added at creation time instead of snd_info_register() for keeping eyes
of pending info entries.

Fixes: c560a6797e3b ('ALSA: core: Remove child proc file elements recursively')
Reported-by: "Lu, Han" <han.lu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/info.c
sound/core/init.c

index 5662793746838715a4c5255569b01253a8adc6eb..13b174464cc82d4154d348dc8fdb715975d2939d 100644 (file)
@@ -515,22 +515,51 @@ int snd_info_card_create(struct snd_card *card)
        return 0;
 }
 
+/* register all pending info entries */
+static int snd_info_register_recursive(struct snd_info_entry *entry)
+{
+       struct snd_info_entry *p;
+       int err;
+
+       if (!entry->p) {
+               err = snd_info_register(entry);
+               if (err < 0)
+                       return err;
+       }
+
+       list_for_each_entry(p, &entry->children, list) {
+               err = snd_info_register_recursive(p);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
 /*
  * register the card proc file
  * called from init.c
+ * can be called multiple times for reinitialization
  */
 int snd_info_card_register(struct snd_card *card)
 {
        struct proc_dir_entry *p;
+       int err;
 
        if (snd_BUG_ON(!card))
                return -ENXIO;
 
+       err = snd_info_register_recursive(card->proc_root);
+       if (err < 0)
+               return err;
+
        if (!strcmp(card->id, card->proc_root->name))
                return 0;
 
+       if (card->proc_root_link)
+               return 0;
        p = proc_symlink(card->id, snd_proc_root->p, card->proc_root->name);
-       if (p == NULL)
+       if (!p)
                return -ENOMEM;
        card->proc_root_link = p;
        return 0;
@@ -705,6 +734,8 @@ struct snd_info_entry *snd_info_create_module_entry(struct module * module,
        if (entry) {
                entry->module = module;
                entry->parent = parent;
+               if (parent)
+                       list_add_tail(&entry->list, &parent->children);
        }
        return entry;
 }
@@ -730,6 +761,8 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
                entry->module = card->module;
                entry->card = card;
                entry->parent = parent;
+               if (parent)
+                       list_add_tail(&entry->list, &parent->children);
        }
        return entry;
 }
@@ -816,8 +849,6 @@ int snd_info_register(struct snd_info_entry * entry)
                proc_set_size(p, entry->size);
        }
        entry->p = p;
-       if (entry->parent)
-               list_add_tail(&entry->list, &entry->parent->children);
        mutex_unlock(&info_mutex);
        return 0;
 }
index 769a783757ff293085dc69372a6b7c38c50b16ba..f8abd2d8144e121ea4884b027d1933ec8d655828 100644 (file)
@@ -107,26 +107,20 @@ static void snd_card_id_read(struct snd_info_entry *entry,
        snd_iprintf(buffer, "%s\n", entry->card->id);
 }
 
-static inline int init_info_for_card(struct snd_card *card)
+static int init_info_for_card(struct snd_card *card)
 {
        int err;
        struct snd_info_entry *entry;
 
-       if ((err = snd_info_card_register(card)) < 0) {
-               dev_dbg(card->dev, "unable to create card info\n");
-               return err;
-       }
-       if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
+       entry = snd_info_create_card_entry(card, "id", card->proc_root);
+       if (!entry) {
                dev_dbg(card->dev, "unable to create card entry\n");
                return err;
        }
        entry->c.text.read = snd_card_id_read;
-       if (snd_info_register(entry) < 0) {
-               snd_info_free_entry(entry);
-               entry = NULL;
-       }
        card->proc_id = entry;
-       return 0;
+
+       return snd_info_card_register(card);
 }
 #else /* !CONFIG_PROC_FS */
 #define init_info_for_card(card)
@@ -756,7 +750,7 @@ int snd_card_register(struct snd_card *card)
        if (snd_cards[card->number]) {
                /* already registered */
                mutex_unlock(&snd_card_mutex);
-               return 0;
+               return snd_info_card_register(card); /* register pending info */
        }
        if (*card->id) {
                /* make a unique id name from the given string */