summaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-05-18 09:20:24 +0200
committerTakashi Iwai <tiwai@suse.de>2015-05-18 09:20:24 +0200
commit2471b6c80a70e80de69f5ff4c37187c3912e5874 (patch)
tree1ff4e00c3f81ef260561bedabdc820634a70464f /sound/core
parent90a409aad45dedc41129e0ec257b41de901b8897 (diff)
downloadlinux-2471b6c80a70e80de69f5ff4c37187c3912e5874.tar.gz
linux-2471b6c80a70e80de69f5ff4c37187c3912e5874.tar.bz2
linux-2471b6c80a70e80de69f5ff4c37187c3912e5874.zip
ALSA: info: Register proc entries recursively, too
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>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/info.c37
-rw-r--r--sound/core/init.c18
2 files changed, 40 insertions, 15 deletions
diff --git a/sound/core/info.c b/sound/core/info.c
index 566279374683..13b174464cc8 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -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;
}
diff --git a/sound/core/init.c b/sound/core/init.c
index 769a783757ff..f8abd2d8144e 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -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 */