diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-03-23 19:35:45 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-03-23 19:35:45 -0400 |
commit | 65b3864b85485a91f70988e1a222e3935bce87e4 (patch) | |
tree | 425063aeaa3c22f3956cc4dc7fc3d8173e9bd172 /sound | |
parent | bafdb7278cb6a215a8a451024fa1604d790cb7b4 (diff) | |
parent | 118dd6bfe7e0cddc8ab417ead19cc76000e92773 (diff) |
Merge branch 'topic/ctl-list-cleanup' into for-linus
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/init.c | 42 |
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 | */ |
855 | int snd_card_file_remove(struct snd_card *card, struct file *file) | 852 | int 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 | ||