diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-02-23 18:35:21 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-03-09 17:16:11 +0300 |
commit | 118dd6bfe7e0cddc8ab417ead19cc76000e92773 (patch) | |
tree | db3ca7e6432887291cfac2627c2307939c9c497b | |
parent | fec6c6fec3e20637bee5d276fb61dd8b49a3f9cc (diff) | |
download | linux-118dd6bfe7e0cddc8ab417ead19cc76000e92773.tar.xz |
ALSA: Clean up snd_monitor_file management
Use the standard linked list for snd_monitor_file management.
Also, move the list deletion of shutdown_list element into
snd_disconnect_release() (for simplification).
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | include/sound/core.h | 6 | ||||
-rw-r--r-- | sound/core/init.c | 42 |
2 files changed, 18 insertions, 30 deletions
diff --git a/include/sound/core.h b/include/sound/core.h index f632484bc743..bd4529e0c27e 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -97,9 +97,9 @@ struct snd_device { struct snd_monitor_file { struct file *file; - struct snd_monitor_file *next; const struct file_operations *disconnected_f_op; - struct list_head shutdown_list; + struct list_head shutdown_list; /* still need to shutdown */ + struct list_head list; /* link of monitor files */ }; /* main structure for soundcard */ @@ -134,7 +134,7 @@ struct snd_card { struct snd_info_entry *proc_id; /* the card id */ struct proc_dir_entry *proc_root_link; /* number link to real id */ - struct snd_monitor_file *files; /* all files associated to this card */ + struct list_head files_list; /* all files associated to this card */ struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */ spinlock_t files_lock; /* lock the files for this card */ diff --git a/sound/core/init.c b/sound/core/init.c index 0d5520c415d3..05c6da554cbf 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -195,6 +195,7 @@ struct snd_card *snd_card_new(int idx, const char *xid, INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); + INIT_LIST_HEAD(&card->files_list); init_waitqueue_head(&card->shutdown_sleep); #ifdef CONFIG_PM mutex_init(&card->power_lock); @@ -259,6 +260,7 @@ static int snd_disconnect_release(struct inode *inode, struct file *file) list_for_each_entry(_df, &shutdown_files, shutdown_list) { if (_df->file == file) { df = _df; + list_del_init(&df->shutdown_list); break; } } @@ -347,8 +349,7 @@ int snd_card_disconnect(struct snd_card *card) /* phase 2: replace file->f_op with special dummy operations */ spin_lock(&card->files_lock); - mfile = card->files; - while (mfile) { + list_for_each_entry(mfile, &card->files_list, list) { file = mfile->file; /* it's critical part, use endless loop */ @@ -361,8 +362,6 @@ int snd_card_disconnect(struct snd_card *card) mfile->file->f_op = &snd_shutdown_f_ops; fops_get(mfile->file->f_op); - - mfile = mfile->next; } spin_unlock(&card->files_lock); @@ -442,7 +441,7 @@ int snd_card_free_when_closed(struct snd_card *card) return ret; spin_lock(&card->files_lock); - if (card->files == NULL) + if (list_empty(&card->files_list)) free_now = 1; else card->free_on_last_close = 1; @@ -462,7 +461,7 @@ int snd_card_free(struct snd_card *card) return ret; /* wait, until all devices are ready for the free operation */ - wait_event(card->shutdown_sleep, card->files == NULL); + wait_event(card->shutdown_sleep, list_empty(&card->files_list)); snd_card_do_free(card); return 0; } @@ -809,15 +808,13 @@ int snd_card_file_add(struct snd_card *card, struct file *file) return -ENOMEM; mfile->file = file; mfile->disconnected_f_op = NULL; - mfile->next = NULL; spin_lock(&card->files_lock); if (card->shutdown) { spin_unlock(&card->files_lock); kfree(mfile); return -ENODEV; } - mfile->next = card->files; - card->files = mfile; + list_add(&mfile->list, &card->files_list); spin_unlock(&card->files_lock); return 0; } @@ -839,29 +836,20 @@ EXPORT_SYMBOL(snd_card_file_add); */ int snd_card_file_remove(struct snd_card *card, struct file *file) { - struct snd_monitor_file *mfile, *pfile = NULL; + struct snd_monitor_file *mfile, *found = NULL; int last_close = 0; spin_lock(&card->files_lock); - mfile = card->files; - while (mfile) { + list_for_each_entry(mfile, &card->files_list, list) { if (mfile->file == file) { - if (pfile) - pfile->next = mfile->next; - else - card->files = mfile->next; + list_del(&mfile->list); + if (mfile->disconnected_f_op) + fops_put(mfile->disconnected_f_op); + found = mfile; break; } - pfile = mfile; - mfile = mfile->next; - } - if (mfile && mfile->disconnected_f_op) { - fops_put(mfile->disconnected_f_op); - spin_lock(&shutdown_lock); - list_del(&mfile->shutdown_list); - spin_unlock(&shutdown_lock); } - if (card->files == NULL) + if (list_empty(&card->files_list)) last_close = 1; spin_unlock(&card->files_lock); if (last_close) { @@ -869,11 +857,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) if (card->free_on_last_close) snd_card_do_free(card); } - if (!mfile) { + if (!found) { snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); return -ENOENT; } - kfree(mfile); + kfree(found); return 0; } |