|
@@ -760,92 +760,39 @@ EXPORT_SYMBOL(snd_info_create_card_entry);
|
|
|
|
|
|
static void snd_info_disconnect(struct snd_info_entry *entry)
|
|
static void snd_info_disconnect(struct snd_info_entry *entry)
|
|
{
|
|
{
|
|
- struct list_head *p, *n;
|
|
|
|
|
|
+ struct snd_info_entry *p, *n;
|
|
|
|
|
|
- list_for_each_safe(p, n, &entry->children) {
|
|
|
|
- snd_info_disconnect(list_entry(p, struct snd_info_entry, list));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (! entry->p)
|
|
|
|
|
|
+ if (!entry->p)
|
|
return;
|
|
return;
|
|
|
|
+ list_for_each_entry_safe(p, n, &entry->children, list)
|
|
|
|
+ snd_info_disconnect(p);
|
|
list_del_init(&entry->list);
|
|
list_del_init(&entry->list);
|
|
proc_remove(entry->p);
|
|
proc_remove(entry->p);
|
|
entry->p = NULL;
|
|
entry->p = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-static int snd_info_dev_free_entry(struct snd_device *device)
|
|
|
|
-{
|
|
|
|
- struct snd_info_entry *entry = device->device_data;
|
|
|
|
- snd_info_free_entry(entry);
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int snd_info_dev_register_entry(struct snd_device *device)
|
|
|
|
-{
|
|
|
|
- struct snd_info_entry *entry = device->device_data;
|
|
|
|
- return snd_info_register(entry);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * snd_card_proc_new - create an info entry for the given card
|
|
|
|
- * @card: the card instance
|
|
|
|
- * @name: the file name
|
|
|
|
- * @entryp: the pointer to store the new info entry
|
|
|
|
- *
|
|
|
|
- * Creates a new info entry and assigns it to the given card.
|
|
|
|
- * Unlike snd_info_create_card_entry(), this function registers the
|
|
|
|
- * info entry as an ALSA device component, so that it can be
|
|
|
|
- * unregistered/released without explicit call.
|
|
|
|
- * Also, you don't have to register this entry via snd_info_register(),
|
|
|
|
- * since this will be registered by snd_card_register() automatically.
|
|
|
|
- *
|
|
|
|
- * The parent is assumed as card->proc_root.
|
|
|
|
- *
|
|
|
|
- * For releasing this entry, use snd_device_free() instead of
|
|
|
|
- * snd_info_free_entry().
|
|
|
|
- *
|
|
|
|
- * Return: Zero if successful, or a negative error code on failure.
|
|
|
|
- */
|
|
|
|
-int snd_card_proc_new(struct snd_card *card, const char *name,
|
|
|
|
- struct snd_info_entry **entryp)
|
|
|
|
-{
|
|
|
|
- static struct snd_device_ops ops = {
|
|
|
|
- .dev_free = snd_info_dev_free_entry,
|
|
|
|
- .dev_register = snd_info_dev_register_entry,
|
|
|
|
- /* disconnect is done via snd_info_card_disconnect() */
|
|
|
|
- };
|
|
|
|
- struct snd_info_entry *entry;
|
|
|
|
- int err;
|
|
|
|
-
|
|
|
|
- entry = snd_info_create_card_entry(card, name, card->proc_root);
|
|
|
|
- if (! entry)
|
|
|
|
- return -ENOMEM;
|
|
|
|
- if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) {
|
|
|
|
- snd_info_free_entry(entry);
|
|
|
|
- return err;
|
|
|
|
- }
|
|
|
|
- if (entryp)
|
|
|
|
- *entryp = entry;
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-EXPORT_SYMBOL(snd_card_proc_new);
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* snd_info_free_entry - release the info entry
|
|
* snd_info_free_entry - release the info entry
|
|
* @entry: the info entry
|
|
* @entry: the info entry
|
|
*
|
|
*
|
|
- * Releases the info entry. Don't call this after registered.
|
|
|
|
|
|
+ * Releases the info entry.
|
|
*/
|
|
*/
|
|
void snd_info_free_entry(struct snd_info_entry * entry)
|
|
void snd_info_free_entry(struct snd_info_entry * entry)
|
|
{
|
|
{
|
|
- if (entry == NULL)
|
|
|
|
|
|
+ struct snd_info_entry *p, *n;
|
|
|
|
+
|
|
|
|
+ if (!entry)
|
|
return;
|
|
return;
|
|
if (entry->p) {
|
|
if (entry->p) {
|
|
mutex_lock(&info_mutex);
|
|
mutex_lock(&info_mutex);
|
|
snd_info_disconnect(entry);
|
|
snd_info_disconnect(entry);
|
|
mutex_unlock(&info_mutex);
|
|
mutex_unlock(&info_mutex);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /* free all children at first */
|
|
|
|
+ list_for_each_entry_safe(p, n, &entry->children, list)
|
|
|
|
+ snd_info_free_entry(p);
|
|
|
|
+
|
|
kfree(entry->name);
|
|
kfree(entry->name);
|
|
if (entry->private_free)
|
|
if (entry->private_free)
|
|
entry->private_free(entry);
|
|
entry->private_free(entry);
|