|
@@ -78,6 +78,7 @@ struct snd_info_private_data {
|
|
|
|
|
|
static int snd_info_version_init(void);
|
|
|
static int snd_info_version_done(void);
|
|
|
+static void snd_info_disconnect(struct snd_info_entry *entry);
|
|
|
|
|
|
|
|
|
/* resize the proc r/w buffer */
|
|
@@ -304,7 +305,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
|
|
|
mutex_lock(&info_mutex);
|
|
|
p = PDE(inode);
|
|
|
entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
|
|
|
- if (entry == NULL || entry->disconnected) {
|
|
|
+ if (entry == NULL || ! entry->p) {
|
|
|
mutex_unlock(&info_mutex);
|
|
|
return -ENODEV;
|
|
|
}
|
|
@@ -586,10 +587,10 @@ int __exit snd_info_done(void)
|
|
|
snd_info_version_done();
|
|
|
if (snd_proc_root) {
|
|
|
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
|
|
|
- snd_info_unregister(snd_seq_root);
|
|
|
+ snd_info_free_entry(snd_seq_root);
|
|
|
#endif
|
|
|
#ifdef CONFIG_SND_OSSEMUL
|
|
|
- snd_info_unregister(snd_oss_root);
|
|
|
+ snd_info_free_entry(snd_oss_root);
|
|
|
#endif
|
|
|
snd_remove_proc_entry(&proc_root, snd_proc_root);
|
|
|
}
|
|
@@ -648,17 +649,28 @@ int snd_info_card_register(struct snd_card *card)
|
|
|
* de-register the card proc file
|
|
|
* called from init.c
|
|
|
*/
|
|
|
-int snd_info_card_free(struct snd_card *card)
|
|
|
+void snd_info_card_disconnect(struct snd_card *card)
|
|
|
{
|
|
|
- snd_assert(card != NULL, return -ENXIO);
|
|
|
+ snd_assert(card != NULL, return);
|
|
|
+ mutex_lock(&info_mutex);
|
|
|
if (card->proc_root_link) {
|
|
|
snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
|
|
|
card->proc_root_link = NULL;
|
|
|
}
|
|
|
- if (card->proc_root) {
|
|
|
- snd_info_unregister(card->proc_root);
|
|
|
- card->proc_root = NULL;
|
|
|
- }
|
|
|
+ if (card->proc_root)
|
|
|
+ snd_info_disconnect(card->proc_root);
|
|
|
+ mutex_unlock(&info_mutex);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * release the card proc file resources
|
|
|
+ * called from init.c
|
|
|
+ */
|
|
|
+int snd_info_card_free(struct snd_card *card)
|
|
|
+{
|
|
|
+ snd_assert(card != NULL, return -ENXIO);
|
|
|
+ snd_info_free_entry(card->proc_root);
|
|
|
+ card->proc_root = NULL;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -767,6 +779,8 @@ static struct snd_info_entry *snd_info_create_entry(const char *name)
|
|
|
entry->mode = S_IFREG | S_IRUGO;
|
|
|
entry->content = SNDRV_INFO_CONTENT_TEXT;
|
|
|
mutex_init(&entry->access);
|
|
|
+ INIT_LIST_HEAD(&entry->children);
|
|
|
+ INIT_LIST_HEAD(&entry->list);
|
|
|
return entry;
|
|
|
}
|
|
|
|
|
@@ -819,30 +833,35 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
|
|
|
|
|
|
EXPORT_SYMBOL(snd_info_create_card_entry);
|
|
|
|
|
|
-static int snd_info_dev_free_entry(struct snd_device *device)
|
|
|
+static void snd_info_disconnect(struct snd_info_entry *entry)
|
|
|
{
|
|
|
- struct snd_info_entry *entry = device->device_data;
|
|
|
- snd_info_free_entry(entry);
|
|
|
- return 0;
|
|
|
-}
|
|
|
+ struct list_head *p, *n;
|
|
|
+ struct proc_dir_entry *root;
|
|
|
|
|
|
-static int snd_info_dev_register_entry(struct snd_device *device)
|
|
|
-{
|
|
|
- struct snd_info_entry *entry = device->device_data;
|
|
|
- return snd_info_register(entry);
|
|
|
+ list_for_each_safe(p, n, &entry->children) {
|
|
|
+ snd_info_disconnect(list_entry(p, struct snd_info_entry, list));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (! entry->p)
|
|
|
+ return;
|
|
|
+ list_del_init(&entry->list);
|
|
|
+ root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
|
|
|
+ snd_assert(root, return);
|
|
|
+ snd_remove_proc_entry(root, entry->p);
|
|
|
+ entry->p = NULL;
|
|
|
}
|
|
|
|
|
|
-static int snd_info_dev_disconnect_entry(struct snd_device *device)
|
|
|
+static int snd_info_dev_free_entry(struct snd_device *device)
|
|
|
{
|
|
|
struct snd_info_entry *entry = device->device_data;
|
|
|
- entry->disconnected = 1;
|
|
|
+ snd_info_free_entry(entry);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int snd_info_dev_unregister_entry(struct snd_device *device)
|
|
|
+static int snd_info_dev_register_entry(struct snd_device *device)
|
|
|
{
|
|
|
struct snd_info_entry *entry = device->device_data;
|
|
|
- return snd_info_unregister(entry);
|
|
|
+ return snd_info_register(entry);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -871,8 +890,7 @@ int snd_card_proc_new(struct snd_card *card, const char *name,
|
|
|
static struct snd_device_ops ops = {
|
|
|
.dev_free = snd_info_dev_free_entry,
|
|
|
.dev_register = snd_info_dev_register_entry,
|
|
|
- .dev_disconnect = snd_info_dev_disconnect_entry,
|
|
|
- .dev_unregister = snd_info_dev_unregister_entry
|
|
|
+ /* disconnect is done via snd_info_card_disconnect() */
|
|
|
};
|
|
|
struct snd_info_entry *entry;
|
|
|
int err;
|
|
@@ -901,6 +919,11 @@ void snd_info_free_entry(struct snd_info_entry * entry)
|
|
|
{
|
|
|
if (entry == NULL)
|
|
|
return;
|
|
|
+ if (entry->p) {
|
|
|
+ mutex_lock(&info_mutex);
|
|
|
+ snd_info_disconnect(entry);
|
|
|
+ mutex_unlock(&info_mutex);
|
|
|
+ }
|
|
|
kfree(entry->name);
|
|
|
if (entry->private_free)
|
|
|
entry->private_free(entry);
|
|
@@ -935,38 +958,14 @@ int snd_info_register(struct snd_info_entry * entry)
|
|
|
p->size = entry->size;
|
|
|
p->data = entry;
|
|
|
entry->p = p;
|
|
|
+ if (entry->parent)
|
|
|
+ list_add_tail(&entry->list, &entry->parent->children);
|
|
|
mutex_unlock(&info_mutex);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
EXPORT_SYMBOL(snd_info_register);
|
|
|
|
|
|
-/**
|
|
|
- * snd_info_unregister - de-register the info entry
|
|
|
- * @entry: the info entry
|
|
|
- *
|
|
|
- * De-registers the info entry and releases the instance.
|
|
|
- *
|
|
|
- * Returns zero if successful, or a negative error code on failure.
|
|
|
- */
|
|
|
-int snd_info_unregister(struct snd_info_entry * entry)
|
|
|
-{
|
|
|
- struct proc_dir_entry *root;
|
|
|
-
|
|
|
- if (! entry)
|
|
|
- return 0;
|
|
|
- snd_assert(entry->p != NULL, return -ENXIO);
|
|
|
- root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
|
|
|
- snd_assert(root, return -ENXIO);
|
|
|
- mutex_lock(&info_mutex);
|
|
|
- snd_remove_proc_entry(root, entry->p);
|
|
|
- mutex_unlock(&info_mutex);
|
|
|
- snd_info_free_entry(entry);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-EXPORT_SYMBOL(snd_info_unregister);
|
|
|
-
|
|
|
/*
|
|
|
|
|
|
*/
|
|
@@ -999,8 +998,7 @@ static int __init snd_info_version_init(void)
|
|
|
|
|
|
static int __exit snd_info_version_done(void)
|
|
|
{
|
|
|
- if (snd_info_version_entry)
|
|
|
- snd_info_unregister(snd_info_version_entry);
|
|
|
+ snd_info_free_entry(snd_info_version_entry);
|
|
|
return 0;
|
|
|
}
|
|
|
|