aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-03-23 19:35:45 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-23 19:35:45 -0400
commit65b3864b85485a91f70988e1a222e3935bce87e4 (patch)
tree425063aeaa3c22f3956cc4dc7fc3d8173e9bd172 /sound/core
parentbafdb7278cb6a215a8a451024fa1604d790cb7b4 (diff)
parent118dd6bfe7e0cddc8ab417ead19cc76000e92773 (diff)
Merge branch 'topic/ctl-list-cleanup' into for-linus
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/init.c42
1 files changed, 15 insertions, 27 deletions
diff --git a/sound/core/init.c b/sound/core/init.c
index dc4b80c7f311..fd56afe846ed 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -208,6 +208,7 @@ int snd_card_create(int idx, const char *xid,
208 INIT_LIST_HEAD(&card->controls); 208 INIT_LIST_HEAD(&card->controls);
209 INIT_LIST_HEAD(&card->ctl_files); 209 INIT_LIST_HEAD(&card->ctl_files);
210 spin_lock_init(&card->files_lock); 210 spin_lock_init(&card->files_lock);
211 INIT_LIST_HEAD(&card->files_list);
211 init_waitqueue_head(&card->shutdown_sleep); 212 init_waitqueue_head(&card->shutdown_sleep);
212#ifdef CONFIG_PM 213#ifdef CONFIG_PM
213 mutex_init(&card->power_lock); 214 mutex_init(&card->power_lock);
@@ -274,6 +275,7 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
274 list_for_each_entry(_df, &shutdown_files, shutdown_list) { 275 list_for_each_entry(_df, &shutdown_files, shutdown_list) {
275 if (_df->file == file) { 276 if (_df->file == file) {
276 df = _df; 277 df = _df;
278 list_del_init(&df->shutdown_list);
277 break; 279 break;
278 } 280 }
279 } 281 }
@@ -362,8 +364,7 @@ int snd_card_disconnect(struct snd_card *card)
362 /* phase 2: replace file->f_op with special dummy operations */ 364 /* phase 2: replace file->f_op with special dummy operations */
363 365
364 spin_lock(&card->files_lock); 366 spin_lock(&card->files_lock);
365 mfile = card->files; 367 list_for_each_entry(mfile, &card->files_list, list) {
366 while (mfile) {
367 file = mfile->file; 368 file = mfile->file;
368 369
369 /* it's critical part, use endless loop */ 370 /* it's critical part, use endless loop */
@@ -376,8 +377,6 @@ int snd_card_disconnect(struct snd_card *card)
376 377
377 mfile->file->f_op = &snd_shutdown_f_ops; 378 mfile->file->f_op = &snd_shutdown_f_ops;
378 fops_get(mfile->file->f_op); 379 fops_get(mfile->file->f_op);
379
380 mfile = mfile->next;
381 } 380 }
382 spin_unlock(&card->files_lock); 381 spin_unlock(&card->files_lock);
383 382
@@ -457,7 +456,7 @@ int snd_card_free_when_closed(struct snd_card *card)
457 return ret; 456 return ret;
458 457
459 spin_lock(&card->files_lock); 458 spin_lock(&card->files_lock);
460 if (card->files == NULL) 459 if (list_empty(&card->files_list))
461 free_now = 1; 460 free_now = 1;
462 else 461 else
463 card->free_on_last_close = 1; 462 card->free_on_last_close = 1;
@@ -477,7 +476,7 @@ int snd_card_free(struct snd_card *card)
477 return ret; 476 return ret;
478 477
479 /* wait, until all devices are ready for the free operation */ 478 /* wait, until all devices are ready for the free operation */
480 wait_event(card->shutdown_sleep, card->files == NULL); 479 wait_event(card->shutdown_sleep, list_empty(&card->files_list));
481 snd_card_do_free(card); 480 snd_card_do_free(card);
482 return 0; 481 return 0;
483} 482}
@@ -824,15 +823,13 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
824 return -ENOMEM; 823 return -ENOMEM;
825 mfile->file = file; 824 mfile->file = file;
826 mfile->disconnected_f_op = NULL; 825 mfile->disconnected_f_op = NULL;
827 mfile->next = NULL;
828 spin_lock(&card->files_lock); 826 spin_lock(&card->files_lock);
829 if (card->shutdown) { 827 if (card->shutdown) {
830 spin_unlock(&card->files_lock); 828 spin_unlock(&card->files_lock);
831 kfree(mfile); 829 kfree(mfile);
832 return -ENODEV; 830 return -ENODEV;
833 } 831 }
834 mfile->next = card->files; 832 list_add(&mfile->list, &card->files_list);
835 card->files = mfile;
836 spin_unlock(&card->files_lock); 833 spin_unlock(&card->files_lock);
837 return 0; 834 return 0;
838} 835}
@@ -854,29 +851,20 @@ EXPORT_SYMBOL(snd_card_file_add);
854 */ 851 */
855int snd_card_file_remove(struct snd_card *card, struct file *file) 852int snd_card_file_remove(struct snd_card *card, struct file *file)
856{ 853{
857 struct snd_monitor_file *mfile, *pfile = NULL; 854 struct snd_monitor_file *mfile, *found = NULL;
858 int last_close = 0; 855 int last_close = 0;
859 856
860 spin_lock(&card->files_lock); 857 spin_lock(&card->files_lock);
861 mfile = card->files; 858 list_for_each_entry(mfile, &card->files_list, list) {
862 while (mfile) {
863 if (mfile->file == file) { 859 if (mfile->file == file) {
864 if (pfile) 860 list_del(&mfile->list);
865 pfile->next = mfile->next; 861 if (mfile->disconnected_f_op)
866 else 862 fops_put(mfile->disconnected_f_op);
867 card->files = mfile->next; 863 found = mfile;
868 break; 864 break;
869 } 865 }
870 pfile = mfile;
871 mfile = mfile->next;
872 }
873 if (mfile && mfile->disconnected_f_op) {
874 fops_put(mfile->disconnected_f_op);
875 spin_lock(&shutdown_lock);
876 list_del(&mfile->shutdown_list);
877 spin_unlock(&shutdown_lock);
878 } 866 }
879 if (card->files == NULL) 867 if (list_empty(&card->files_list))
880 last_close = 1; 868 last_close = 1;
881 spin_unlock(&card->files_lock); 869 spin_unlock(&card->files_lock);
882 if (last_close) { 870 if (last_close) {
@@ -884,11 +872,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
884 if (card->free_on_last_close) 872 if (card->free_on_last_close)
885 snd_card_do_free(card); 873 snd_card_do_free(card);
886 } 874 }
887 if (!mfile) { 875 if (!found) {
888 snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); 876 snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
889 return -ENOENT; 877 return -ENOENT;
890 } 878 }
891 kfree(mfile); 879 kfree(found);
892 return 0; 880 return 0;
893} 881}
894 882