aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/timer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-06-23 08:38:23 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:36:58 -0400
commitc461482c8072bb073e6146db320d3da85cdc89ad (patch)
tree3b69cfd292a488a8cb57ac9b040bd2b1b1a1e26d /sound/core/timer.c
parent746d4a02e68499fc6c1f8d0c43d2271853ade181 (diff)
[ALSA] Unregister device files at disconnection
Orignally proposed by Sam Revitch <sam.revitch@gmail.com>. Unregister device files at disconnection to avoid the futher accesses. Also, the dev_unregister callback is removed and replaced with the combination of disconnect + free. A new function snd_card_free_when_closed() is introduced, which is used in USB disconnect callback. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r--sound/core/timer.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 52ecbe1e9ab..7e5e562fe35 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -88,7 +88,7 @@ static DEFINE_MUTEX(register_mutex);
88static int snd_timer_free(struct snd_timer *timer); 88static int snd_timer_free(struct snd_timer *timer);
89static int snd_timer_dev_free(struct snd_device *device); 89static int snd_timer_dev_free(struct snd_device *device);
90static int snd_timer_dev_register(struct snd_device *device); 90static int snd_timer_dev_register(struct snd_device *device);
91static int snd_timer_dev_unregister(struct snd_device *device); 91static int snd_timer_dev_disconnect(struct snd_device *device);
92 92
93static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left); 93static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left);
94 94
@@ -773,7 +773,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
773 static struct snd_device_ops ops = { 773 static struct snd_device_ops ops = {
774 .dev_free = snd_timer_dev_free, 774 .dev_free = snd_timer_dev_free,
775 .dev_register = snd_timer_dev_register, 775 .dev_register = snd_timer_dev_register,
776 .dev_unregister = snd_timer_dev_unregister 776 .dev_disconnect = snd_timer_dev_disconnect,
777 }; 777 };
778 778
779 snd_assert(tid != NULL, return -EINVAL); 779 snd_assert(tid != NULL, return -EINVAL);
@@ -813,6 +813,21 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
813static int snd_timer_free(struct snd_timer *timer) 813static int snd_timer_free(struct snd_timer *timer)
814{ 814{
815 snd_assert(timer != NULL, return -ENXIO); 815 snd_assert(timer != NULL, return -ENXIO);
816
817 mutex_lock(&register_mutex);
818 if (! list_empty(&timer->open_list_head)) {
819 struct list_head *p, *n;
820 struct snd_timer_instance *ti;
821 snd_printk(KERN_WARNING "timer %p is busy?\n", timer);
822 list_for_each_safe(p, n, &timer->open_list_head) {
823 list_del_init(p);
824 ti = list_entry(p, struct snd_timer_instance, open_list);
825 ti->timer = NULL;
826 }
827 }
828 list_del(&timer->device_list);
829 mutex_unlock(&register_mutex);
830
816 if (timer->private_free) 831 if (timer->private_free)
817 timer->private_free(timer); 832 timer->private_free(timer);
818 kfree(timer); 833 kfree(timer);
@@ -867,30 +882,13 @@ static int snd_timer_dev_register(struct snd_device *dev)
867 return 0; 882 return 0;
868} 883}
869 884
870static int snd_timer_unregister(struct snd_timer *timer) 885static int snd_timer_dev_disconnect(struct snd_device *device)
871{ 886{
872 struct list_head *p, *n; 887 struct snd_timer *timer = device->device_data;
873 struct snd_timer_instance *ti;
874
875 snd_assert(timer != NULL, return -ENXIO);
876 mutex_lock(&register_mutex); 888 mutex_lock(&register_mutex);
877 if (! list_empty(&timer->open_list_head)) { 889 list_del_init(&timer->device_list);
878 snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
879 list_for_each_safe(p, n, &timer->open_list_head) {
880 list_del_init(p);
881 ti = list_entry(p, struct snd_timer_instance, open_list);
882 ti->timer = NULL;
883 }
884 }
885 list_del(&timer->device_list);
886 mutex_unlock(&register_mutex); 890 mutex_unlock(&register_mutex);
887 return snd_timer_free(timer); 891 return 0;
888}
889
890static int snd_timer_dev_unregister(struct snd_device *device)
891{
892 struct snd_timer *timer = device->device_data;
893 return snd_timer_unregister(timer);
894} 892}
895 893
896void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp) 894void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp)
@@ -955,11 +953,6 @@ int snd_timer_global_register(struct snd_timer *timer)
955 return snd_timer_dev_register(&dev); 953 return snd_timer_dev_register(&dev);
956} 954}
957 955
958int snd_timer_global_unregister(struct snd_timer *timer)
959{
960 return snd_timer_unregister(timer);
961}
962
963/* 956/*
964 * System timer 957 * System timer
965 */ 958 */
@@ -1982,7 +1975,7 @@ static void __exit alsa_timer_exit(void)
1982 /* unregister the system timer */ 1975 /* unregister the system timer */
1983 list_for_each_safe(p, n, &snd_timer_list) { 1976 list_for_each_safe(p, n, &snd_timer_list) {
1984 struct snd_timer *timer = list_entry(p, struct snd_timer, device_list); 1977 struct snd_timer *timer = list_entry(p, struct snd_timer, device_list);
1985 snd_timer_unregister(timer); 1978 snd_timer_free(timer);
1986 } 1979 }
1987 snd_timer_proc_done(); 1980 snd_timer_proc_done();
1988#ifdef SNDRV_OSS_INFO_DEV_TIMERS 1981#ifdef SNDRV_OSS_INFO_DEV_TIMERS
@@ -2005,5 +1998,4 @@ EXPORT_SYMBOL(snd_timer_notify);
2005EXPORT_SYMBOL(snd_timer_global_new); 1998EXPORT_SYMBOL(snd_timer_global_new);
2006EXPORT_SYMBOL(snd_timer_global_free); 1999EXPORT_SYMBOL(snd_timer_global_free);
2007EXPORT_SYMBOL(snd_timer_global_register); 2000EXPORT_SYMBOL(snd_timer_global_register);
2008EXPORT_SYMBOL(snd_timer_global_unregister);
2009EXPORT_SYMBOL(snd_timer_interrupt); 2001EXPORT_SYMBOL(snd_timer_interrupt);