diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/Kconfig | 6 | ||||
-rw-r--r-- | sound/core/Makefile | 3 | ||||
-rw-r--r-- | sound/core/control.c | 18 | ||||
-rw-r--r-- | sound/core/hwdep.c | 10 | ||||
-rw-r--r-- | sound/core/info.c | 2 | ||||
-rw-r--r-- | sound/core/init.c | 7 | ||||
-rw-r--r-- | sound/core/memory.c | 216 | ||||
-rw-r--r-- | sound/core/misc.c | 14 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 62 | ||||
-rw-r--r-- | sound/core/oss/pcm_oss.c | 20 | ||||
-rw-r--r-- | sound/core/pcm.c | 3 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 5 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 18 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 12 | ||||
-rw-r--r-- | sound/core/rtctimer.c | 24 | ||||
-rw-r--r-- | sound/core/seq/seq_instr.c | 12 | ||||
-rw-r--r-- | sound/core/seq/seq_lock.c | 3 | ||||
-rw-r--r-- | sound/core/seq/seq_memory.c | 3 | ||||
-rw-r--r-- | sound/core/seq/seq_midi.c | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_timer.c | 29 | ||||
-rw-r--r-- | sound/core/sound.c | 24 | ||||
-rw-r--r-- | sound/core/timer.c | 380 | ||||
-rw-r--r-- | sound/core/wrappers.c | 50 |
23 files changed, 358 insertions, 565 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 48cf45cfd0b7..82718836f937 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig | |||
@@ -127,12 +127,6 @@ config SND_DEBUG | |||
127 | help | 127 | help |
128 | Say Y here to enable ALSA debug code. | 128 | Say Y here to enable ALSA debug code. |
129 | 129 | ||
130 | config SND_DEBUG_MEMORY | ||
131 | bool "Debug memory" | ||
132 | depends on SND_DEBUG | ||
133 | help | ||
134 | Say Y here to enable debugging of memory allocations. | ||
135 | |||
136 | config SND_DEBUG_DETECT | 130 | config SND_DEBUG_DETECT |
137 | bool "Debug detection" | 131 | bool "Debug detection" |
138 | depends on SND_DEBUG | 132 | depends on SND_DEBUG |
diff --git a/sound/core/Makefile b/sound/core/Makefile index 969d75528bde..5a01c76d02e8 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile | |||
@@ -3,8 +3,7 @@ | |||
3 | # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz> | 3 | # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | snd-objs := sound.o init.o memory.o info.o control.o misc.o \ | 6 | snd-objs := sound.o init.o memory.o info.o control.o misc.o device.o |
7 | device.o wrappers.o | ||
8 | ifeq ($(CONFIG_ISA_DMA_API),y) | 7 | ifeq ($(CONFIG_ISA_DMA_API),y) |
9 | snd-objs += isadma.o | 8 | snd-objs += isadma.o |
10 | endif | 9 | endif |
diff --git a/sound/core/control.c b/sound/core/control.c index 736edf358e05..212c46a94376 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -144,7 +144,7 @@ void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id) | |||
144 | snd_ctl_file_t *ctl; | 144 | snd_ctl_file_t *ctl; |
145 | snd_kctl_event_t *ev; | 145 | snd_kctl_event_t *ev; |
146 | 146 | ||
147 | snd_runtime_check(card != NULL && id != NULL, return); | 147 | snd_assert(card != NULL && id != NULL, return); |
148 | read_lock(&card->ctl_files_rwlock); | 148 | read_lock(&card->ctl_files_rwlock); |
149 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | 149 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) |
150 | card->mixer_oss_change_count++; | 150 | card->mixer_oss_change_count++; |
@@ -193,8 +193,8 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access) | |||
193 | snd_kcontrol_t *kctl; | 193 | snd_kcontrol_t *kctl; |
194 | unsigned int idx; | 194 | unsigned int idx; |
195 | 195 | ||
196 | snd_runtime_check(control != NULL, return NULL); | 196 | snd_assert(control != NULL, return NULL); |
197 | snd_runtime_check(control->count > 0, return NULL); | 197 | snd_assert(control->count > 0, return NULL); |
198 | kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL); | 198 | kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL); |
199 | if (kctl == NULL) | 199 | if (kctl == NULL) |
200 | return NULL; | 200 | return NULL; |
@@ -220,7 +220,7 @@ snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * ncontrol, void *private_ | |||
220 | snd_kcontrol_t kctl; | 220 | snd_kcontrol_t kctl; |
221 | unsigned int access; | 221 | unsigned int access; |
222 | 222 | ||
223 | snd_runtime_check(ncontrol != NULL, return NULL); | 223 | snd_assert(ncontrol != NULL, return NULL); |
224 | snd_assert(ncontrol->info != NULL, return NULL); | 224 | snd_assert(ncontrol->info != NULL, return NULL); |
225 | memset(&kctl, 0, sizeof(kctl)); | 225 | memset(&kctl, 0, sizeof(kctl)); |
226 | kctl.id.iface = ncontrol->iface; | 226 | kctl.id.iface = ncontrol->iface; |
@@ -309,7 +309,7 @@ int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol) | |||
309 | snd_ctl_elem_id_t id; | 309 | snd_ctl_elem_id_t id; |
310 | unsigned int idx; | 310 | unsigned int idx; |
311 | 311 | ||
312 | snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); | 312 | snd_assert(card != NULL && kcontrol != NULL, return -EINVAL); |
313 | snd_assert(kcontrol->info != NULL, return -EINVAL); | 313 | snd_assert(kcontrol->info != NULL, return -EINVAL); |
314 | id = kcontrol->id; | 314 | id = kcontrol->id; |
315 | down_write(&card->controls_rwsem); | 315 | down_write(&card->controls_rwsem); |
@@ -355,7 +355,7 @@ int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol) | |||
355 | snd_ctl_elem_id_t id; | 355 | snd_ctl_elem_id_t id; |
356 | unsigned int idx; | 356 | unsigned int idx; |
357 | 357 | ||
358 | snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); | 358 | snd_assert(card != NULL && kcontrol != NULL, return -EINVAL); |
359 | list_del(&kcontrol->list); | 359 | list_del(&kcontrol->list); |
360 | card->controls_count -= kcontrol->count; | 360 | card->controls_count -= kcontrol->count; |
361 | id = kcontrol->id; | 361 | id = kcontrol->id; |
@@ -468,7 +468,7 @@ snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid) | |||
468 | struct list_head *list; | 468 | struct list_head *list; |
469 | snd_kcontrol_t *kctl; | 469 | snd_kcontrol_t *kctl; |
470 | 470 | ||
471 | snd_runtime_check(card != NULL && numid != 0, return NULL); | 471 | snd_assert(card != NULL && numid != 0, return NULL); |
472 | list_for_each(list, &card->controls) { | 472 | list_for_each(list, &card->controls) { |
473 | kctl = snd_kcontrol(list); | 473 | kctl = snd_kcontrol(list); |
474 | if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) | 474 | if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) |
@@ -494,7 +494,7 @@ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id) | |||
494 | struct list_head *list; | 494 | struct list_head *list; |
495 | snd_kcontrol_t *kctl; | 495 | snd_kcontrol_t *kctl; |
496 | 496 | ||
497 | snd_runtime_check(card != NULL && id != NULL, return NULL); | 497 | snd_assert(card != NULL && id != NULL, return NULL); |
498 | if (id->numid != 0) | 498 | if (id->numid != 0) |
499 | return snd_ctl_find_numid(card, id->numid); | 499 | return snd_ctl_find_numid(card, id->numid); |
500 | list_for_each(list, &card->controls) { | 500 | list_for_each(list, &card->controls) { |
@@ -1215,7 +1215,7 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head | |||
1215 | struct list_head *list; | 1215 | struct list_head *list; |
1216 | snd_kctl_ioctl_t *p; | 1216 | snd_kctl_ioctl_t *p; |
1217 | 1217 | ||
1218 | snd_runtime_check(fcn != NULL, return -EINVAL); | 1218 | snd_assert(fcn != NULL, return -EINVAL); |
1219 | down_write(&snd_ioctl_rwsem); | 1219 | down_write(&snd_ioctl_rwsem); |
1220 | list_for_each(list, lists) { | 1220 | list_for_each(list, lists) { |
1221 | p = list_entry(list, snd_kctl_ioctl_t, list); | 1221 | p = list_entry(list, snd_kctl_ioctl_t, list); |
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 9383f1294fb5..e91cee35a4b9 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c | |||
@@ -81,20 +81,16 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) | |||
81 | int err; | 81 | int err; |
82 | wait_queue_t wait; | 82 | wait_queue_t wait; |
83 | 83 | ||
84 | switch (major) { | 84 | if (major == snd_major) { |
85 | case CONFIG_SND_MAJOR: | ||
86 | cardnum = SNDRV_MINOR_CARD(iminor(inode)); | 85 | cardnum = SNDRV_MINOR_CARD(iminor(inode)); |
87 | device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP; | 86 | device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP; |
88 | break; | ||
89 | #ifdef CONFIG_SND_OSSEMUL | 87 | #ifdef CONFIG_SND_OSSEMUL |
90 | case SOUND_MAJOR: | 88 | } else if (major == SOUND_MAJOR) { |
91 | cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); | 89 | cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); |
92 | device = 0; | 90 | device = 0; |
93 | break; | ||
94 | #endif | 91 | #endif |
95 | default: | 92 | } else |
96 | return -ENXIO; | 93 | return -ENXIO; |
97 | } | ||
98 | cardnum %= SNDRV_CARDS; | 94 | cardnum %= SNDRV_CARDS; |
99 | device %= SNDRV_MINOR_HWDEPS; | 95 | device %= SNDRV_MINOR_HWDEPS; |
100 | hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device]; | 96 | hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device]; |
diff --git a/sound/core/info.c b/sound/core/info.c index 37024d68a26e..39f9b97d9219 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -566,7 +566,6 @@ int __init snd_info_init(void) | |||
566 | } | 566 | } |
567 | #endif | 567 | #endif |
568 | snd_info_version_init(); | 568 | snd_info_version_init(); |
569 | snd_memory_info_init(); | ||
570 | snd_minor_info_init(); | 569 | snd_minor_info_init(); |
571 | snd_minor_info_oss_init(); | 570 | snd_minor_info_oss_init(); |
572 | snd_card_info_init(); | 571 | snd_card_info_init(); |
@@ -578,7 +577,6 @@ int __exit snd_info_done(void) | |||
578 | snd_card_info_done(); | 577 | snd_card_info_done(); |
579 | snd_minor_info_oss_done(); | 578 | snd_minor_info_oss_done(); |
580 | snd_minor_info_done(); | 579 | snd_minor_info_done(); |
581 | snd_memory_info_done(); | ||
582 | snd_info_version_done(); | 580 | snd_info_version_done(); |
583 | if (snd_proc_root) { | 581 | if (snd_proc_root) { |
584 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 582 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) |
diff --git a/sound/core/init.c b/sound/core/init.c index 41e224986f35..d9ee27ae9a51 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -420,7 +420,7 @@ int snd_card_register(snd_card_t * card) | |||
420 | int err; | 420 | int err; |
421 | snd_info_entry_t *entry; | 421 | snd_info_entry_t *entry; |
422 | 422 | ||
423 | snd_runtime_check(card != NULL, return -EINVAL); | 423 | snd_assert(card != NULL, return -EINVAL); |
424 | if ((err = snd_device_register_all(card)) < 0) | 424 | if ((err = snd_device_register_all(card)) < 0) |
425 | return err; | 425 | return err; |
426 | write_lock(&snd_card_rwlock); | 426 | write_lock(&snd_card_rwlock); |
@@ -524,7 +524,8 @@ int __init snd_card_info_init(void) | |||
524 | snd_info_entry_t *entry; | 524 | snd_info_entry_t *entry; |
525 | 525 | ||
526 | entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); | 526 | entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); |
527 | snd_runtime_check(entry != NULL, return -ENOMEM); | 527 | if (! entry) |
528 | return -ENOMEM; | ||
528 | entry->c.text.read_size = PAGE_SIZE; | 529 | entry->c.text.read_size = PAGE_SIZE; |
529 | entry->c.text.read = snd_card_info_read; | 530 | entry->c.text.read = snd_card_info_read; |
530 | if (snd_info_register(entry) < 0) { | 531 | if (snd_info_register(entry) < 0) { |
@@ -840,7 +841,7 @@ static int snd_generic_resume(struct device *dev) | |||
840 | card = get_snd_generic_card(dev); | 841 | card = get_snd_generic_card(dev); |
841 | if (card->power_state == SNDRV_CTL_POWER_D0) | 842 | if (card->power_state == SNDRV_CTL_POWER_D0) |
842 | return 0; | 843 | return 0; |
843 | if (card->pm_suspend) | 844 | if (card->pm_resume) |
844 | card->pm_resume(card); | 845 | card->pm_resume(card); |
845 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 846 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
846 | return 0; | 847 | return 0; |
diff --git a/sound/core/memory.c b/sound/core/memory.c index 7d8e2eebba51..862d62d2e144 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | 2 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> |
3 | * | 3 | * |
4 | * Memory allocation helpers. | 4 | * Misc memory accessors |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -20,221 +20,9 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <sound/driver.h> | 23 | #include <linux/config.h> |
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | #include <linux/init.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/time.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <sound/core.h> | ||
31 | #include <sound/info.h> | ||
32 | |||
33 | /* | ||
34 | * memory allocation helpers and debug routines | ||
35 | */ | ||
36 | |||
37 | #ifdef CONFIG_SND_DEBUG_MEMORY | ||
38 | |||
39 | struct snd_alloc_track { | ||
40 | unsigned long magic; | ||
41 | void *caller; | ||
42 | size_t size; | ||
43 | struct list_head list; | ||
44 | long data[0]; | ||
45 | }; | ||
46 | |||
47 | #define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data) | ||
48 | |||
49 | static long snd_alloc_kmalloc; | ||
50 | static long snd_alloc_vmalloc; | ||
51 | static LIST_HEAD(snd_alloc_kmalloc_list); | ||
52 | static LIST_HEAD(snd_alloc_vmalloc_list); | ||
53 | static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock); | ||
54 | static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock); | ||
55 | #define KMALLOC_MAGIC 0x87654321 | ||
56 | #define VMALLOC_MAGIC 0x87654320 | ||
57 | static snd_info_entry_t *snd_memory_info_entry; | ||
58 | |||
59 | void __init snd_memory_init(void) | ||
60 | { | ||
61 | snd_alloc_kmalloc = 0; | ||
62 | snd_alloc_vmalloc = 0; | ||
63 | } | ||
64 | |||
65 | void snd_memory_done(void) | ||
66 | { | ||
67 | struct list_head *head; | ||
68 | struct snd_alloc_track *t; | ||
69 | |||
70 | if (snd_alloc_kmalloc > 0) | ||
71 | snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc); | ||
72 | if (snd_alloc_vmalloc > 0) | ||
73 | snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc); | ||
74 | list_for_each_prev(head, &snd_alloc_kmalloc_list) { | ||
75 | t = list_entry(head, struct snd_alloc_track, list); | ||
76 | if (t->magic != KMALLOC_MAGIC) { | ||
77 | snd_printk(KERN_ERR "Corrupted kmalloc\n"); | ||
78 | break; | ||
79 | } | ||
80 | snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller); | ||
81 | } | ||
82 | list_for_each_prev(head, &snd_alloc_vmalloc_list) { | ||
83 | t = list_entry(head, struct snd_alloc_track, list); | ||
84 | if (t->magic != VMALLOC_MAGIC) { | ||
85 | snd_printk(KERN_ERR "Corrupted vmalloc\n"); | ||
86 | break; | ||
87 | } | ||
88 | snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller) | ||
93 | { | ||
94 | unsigned long cpu_flags; | ||
95 | struct snd_alloc_track *t; | ||
96 | void *ptr; | ||
97 | |||
98 | ptr = snd_wrapper_kmalloc(size + sizeof(struct snd_alloc_track), flags); | ||
99 | if (ptr != NULL) { | ||
100 | t = (struct snd_alloc_track *)ptr; | ||
101 | t->magic = KMALLOC_MAGIC; | ||
102 | t->caller = caller; | ||
103 | spin_lock_irqsave(&snd_alloc_kmalloc_lock, cpu_flags); | ||
104 | list_add_tail(&t->list, &snd_alloc_kmalloc_list); | ||
105 | spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, cpu_flags); | ||
106 | t->size = size; | ||
107 | snd_alloc_kmalloc += size; | ||
108 | ptr = t->data; | ||
109 | } | ||
110 | return ptr; | ||
111 | } | ||
112 | |||
113 | #define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0)); | ||
114 | void *snd_hidden_kmalloc(size_t size, gfp_t flags) | ||
115 | { | ||
116 | return _snd_kmalloc(size, flags); | ||
117 | } | ||
118 | |||
119 | void *snd_hidden_kzalloc(size_t size, gfp_t flags) | ||
120 | { | ||
121 | void *ret = _snd_kmalloc(size, flags); | ||
122 | if (ret) | ||
123 | memset(ret, 0, size); | ||
124 | return ret; | ||
125 | } | ||
126 | EXPORT_SYMBOL(snd_hidden_kzalloc); | ||
127 | |||
128 | void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags) | ||
129 | { | ||
130 | void *ret = NULL; | ||
131 | if (n != 0 && size > INT_MAX / n) | ||
132 | return ret; | ||
133 | return snd_hidden_kzalloc(n * size, flags); | ||
134 | } | ||
135 | |||
136 | void snd_hidden_kfree(const void *obj) | ||
137 | { | ||
138 | unsigned long flags; | ||
139 | struct snd_alloc_track *t; | ||
140 | if (obj == NULL) | ||
141 | return; | ||
142 | t = snd_alloc_track_entry(obj); | ||
143 | if (t->magic != KMALLOC_MAGIC) { | ||
144 | snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0)); | ||
145 | return; | ||
146 | } | ||
147 | spin_lock_irqsave(&snd_alloc_kmalloc_lock, flags); | ||
148 | list_del(&t->list); | ||
149 | spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, flags); | ||
150 | t->magic = 0; | ||
151 | snd_alloc_kmalloc -= t->size; | ||
152 | obj = t; | ||
153 | snd_wrapper_kfree(obj); | ||
154 | } | ||
155 | |||
156 | void *snd_hidden_vmalloc(unsigned long size) | ||
157 | { | ||
158 | void *ptr; | ||
159 | ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track)); | ||
160 | if (ptr) { | ||
161 | struct snd_alloc_track *t = (struct snd_alloc_track *)ptr; | ||
162 | t->magic = VMALLOC_MAGIC; | ||
163 | t->caller = __builtin_return_address(0); | ||
164 | spin_lock(&snd_alloc_vmalloc_lock); | ||
165 | list_add_tail(&t->list, &snd_alloc_vmalloc_list); | ||
166 | spin_unlock(&snd_alloc_vmalloc_lock); | ||
167 | t->size = size; | ||
168 | snd_alloc_vmalloc += size; | ||
169 | ptr = t->data; | ||
170 | } | ||
171 | return ptr; | ||
172 | } | ||
173 | |||
174 | void snd_hidden_vfree(void *obj) | ||
175 | { | ||
176 | struct snd_alloc_track *t; | ||
177 | if (obj == NULL) | ||
178 | return; | ||
179 | t = snd_alloc_track_entry(obj); | ||
180 | if (t->magic != VMALLOC_MAGIC) { | ||
181 | snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0)); | ||
182 | return; | ||
183 | } | ||
184 | spin_lock(&snd_alloc_vmalloc_lock); | ||
185 | list_del(&t->list); | ||
186 | spin_unlock(&snd_alloc_vmalloc_lock); | ||
187 | t->magic = 0; | ||
188 | snd_alloc_vmalloc -= t->size; | ||
189 | obj = t; | ||
190 | snd_wrapper_vfree(obj); | ||
191 | } | ||
192 | |||
193 | char *snd_hidden_kstrdup(const char *s, gfp_t flags) | ||
194 | { | ||
195 | int len; | ||
196 | char *buf; | ||
197 | |||
198 | if (!s) return NULL; | ||
199 | |||
200 | len = strlen(s) + 1; | ||
201 | buf = _snd_kmalloc(len, flags); | ||
202 | if (buf) | ||
203 | memcpy(buf, s, len); | ||
204 | return buf; | ||
205 | } | ||
206 | |||
207 | static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) | ||
208 | { | ||
209 | snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc); | ||
210 | snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc); | ||
211 | } | ||
212 | |||
213 | int __init snd_memory_info_init(void) | ||
214 | { | ||
215 | snd_info_entry_t *entry; | ||
216 | |||
217 | entry = snd_info_create_module_entry(THIS_MODULE, "meminfo", NULL); | ||
218 | if (entry) { | ||
219 | entry->c.text.read_size = 256; | ||
220 | entry->c.text.read = snd_memory_info_read; | ||
221 | if (snd_info_register(entry) < 0) { | ||
222 | snd_info_free_entry(entry); | ||
223 | entry = NULL; | ||
224 | } | ||
225 | } | ||
226 | snd_memory_info_entry = entry; | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | int __exit snd_memory_info_done(void) | ||
231 | { | ||
232 | if (snd_memory_info_entry) | ||
233 | snd_info_unregister(snd_memory_info_entry); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | #endif /* CONFIG_SND_DEBUG_MEMORY */ | ||
238 | 26 | ||
239 | /** | 27 | /** |
240 | * copy_to_user_fromio - copy data from mmio-space to user-space | 28 | * copy_to_user_fromio - copy data from mmio-space to user-space |
diff --git a/sound/core/misc.c b/sound/core/misc.c index 1a81fe4df218..b53e563c09e6 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c | |||
@@ -23,17 +23,15 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/ioport.h> | ||
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
27 | 28 | ||
28 | int snd_task_name(struct task_struct *task, char *name, size_t size) | 29 | void release_and_free_resource(struct resource *res) |
29 | { | 30 | { |
30 | unsigned int idx; | 31 | if (res) { |
31 | 32 | release_resource(res); | |
32 | snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL); | 33 | kfree(res); |
33 | for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++) | 34 | } |
34 | name[idx] = task->comm[idx]; | ||
35 | name[idx] = '\0'; | ||
36 | return 0; | ||
37 | } | 35 | } |
38 | 36 | ||
39 | #ifdef CONFIG_SND_VERBOSE_PRINTK | 37 | #ifdef CONFIG_SND_VERBOSE_PRINTK |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 69e1059112d1..214933cf5d49 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -521,9 +521,13 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer, | |||
521 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | 521 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
522 | if (uinfo == NULL || uctl == NULL) | 522 | if (uinfo == NULL || uctl == NULL) |
523 | goto __unalloc; | 523 | goto __unalloc; |
524 | snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); | 524 | if (kctl->info(kctl, uinfo)) |
525 | snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc); | 525 | goto __unalloc; |
526 | snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc); | 526 | if (kctl->get(kctl, uctl)) |
527 | goto __unalloc; | ||
528 | if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN && | ||
529 | uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1) | ||
530 | goto __unalloc; | ||
527 | *left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]); | 531 | *left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]); |
528 | if (uinfo->count > 1) | 532 | if (uinfo->count > 1) |
529 | *right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]); | 533 | *right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]); |
@@ -555,8 +559,10 @@ static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer, | |||
555 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | 559 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
556 | if (uinfo == NULL || uctl == NULL) | 560 | if (uinfo == NULL || uctl == NULL) |
557 | goto __unalloc; | 561 | goto __unalloc; |
558 | snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); | 562 | if (kctl->info(kctl, uinfo)) |
559 | snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc); | 563 | goto __unalloc; |
564 | if (kctl->get(kctl, uctl)) | ||
565 | goto __unalloc; | ||
560 | if (!uctl->value.integer.value[0]) { | 566 | if (!uctl->value.integer.value[0]) { |
561 | *left = 0; | 567 | *left = 0; |
562 | if (uinfo->count == 1) | 568 | if (uinfo->count == 1) |
@@ -616,12 +622,16 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer, | |||
616 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | 622 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
617 | if (uinfo == NULL || uctl == NULL) | 623 | if (uinfo == NULL || uctl == NULL) |
618 | goto __unalloc; | 624 | goto __unalloc; |
619 | snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); | 625 | if (kctl->info(kctl, uinfo)) |
620 | snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc); | 626 | goto __unalloc; |
627 | if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN && | ||
628 | uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1) | ||
629 | goto __unalloc; | ||
621 | uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max); | 630 | uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max); |
622 | if (uinfo->count > 1) | 631 | if (uinfo->count > 1) |
623 | uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max); | 632 | uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max); |
624 | snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc); | 633 | if ((res = kctl->put(kctl, uctl)) < 0) |
634 | goto __unalloc; | ||
625 | if (res > 0) | 635 | if (res > 0) |
626 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); | 636 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); |
627 | __unalloc: | 637 | __unalloc: |
@@ -653,7 +663,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer, | |||
653 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | 663 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
654 | if (uinfo == NULL || uctl == NULL) | 664 | if (uinfo == NULL || uctl == NULL) |
655 | goto __unalloc; | 665 | goto __unalloc; |
656 | snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); | 666 | if (kctl->info(kctl, uinfo)) |
667 | goto __unalloc; | ||
657 | if (uinfo->count > 1) { | 668 | if (uinfo->count > 1) { |
658 | uctl->value.integer.value[0] = left > 0 ? 1 : 0; | 669 | uctl->value.integer.value[0] = left > 0 ? 1 : 0; |
659 | uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0; | 670 | uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0; |
@@ -664,7 +675,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer, | |||
664 | } else { | 675 | } else { |
665 | uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0; | 676 | uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0; |
666 | } | 677 | } |
667 | snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc); | 678 | if ((res = kctl->put(kctl, uctl)) < 0) |
679 | goto __unalloc; | ||
668 | if (res > 0) | 680 | if (res > 0) |
669 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); | 681 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); |
670 | __unalloc: | 682 | __unalloc: |
@@ -776,9 +788,14 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int | |||
776 | } | 788 | } |
777 | down_read(&card->controls_rwsem); | 789 | down_read(&card->controls_rwsem); |
778 | kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); | 790 | kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); |
779 | snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock); | 791 | if (! kctl) { |
780 | snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock); | 792 | err = -ENOENT; |
781 | snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock); | 793 | goto __unlock; |
794 | } | ||
795 | if ((err = kctl->info(kctl, uinfo)) < 0) | ||
796 | goto __unlock; | ||
797 | if ((err = kctl->get(kctl, uctl)) < 0) | ||
798 | goto __unlock; | ||
782 | for (idx = 0; idx < 32; idx++) { | 799 | for (idx = 0; idx < 32; idx++) { |
783 | if (!(mixer->mask_recsrc & (1 << idx))) | 800 | if (!(mixer->mask_recsrc & (1 << idx))) |
784 | continue; | 801 | continue; |
@@ -821,8 +838,12 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int | |||
821 | } | 838 | } |
822 | down_read(&card->controls_rwsem); | 839 | down_read(&card->controls_rwsem); |
823 | kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); | 840 | kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); |
824 | snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock); | 841 | if (! kctl) { |
825 | snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock); | 842 | err = -ENOENT; |
843 | goto __unlock; | ||
844 | } | ||
845 | if ((err = kctl->info(kctl, uinfo)) < 0) | ||
846 | goto __unlock; | ||
826 | for (idx = 0; idx < 32; idx++) { | 847 | for (idx = 0; idx < 32; idx++) { |
827 | if (!(mixer->mask_recsrc & (1 << idx))) | 848 | if (!(mixer->mask_recsrc & (1 << idx))) |
828 | continue; | 849 | continue; |
@@ -836,10 +857,11 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int | |||
836 | break; | 857 | break; |
837 | slot = NULL; | 858 | slot = NULL; |
838 | } | 859 | } |
839 | snd_runtime_check(slot != NULL, goto __unlock); | 860 | if (! slot) |
861 | goto __unlock; | ||
840 | for (idx = 0; idx < uinfo->count; idx++) | 862 | for (idx = 0; idx < uinfo->count; idx++) |
841 | uctl->value.enumerated.item[idx] = slot->capture_item; | 863 | uctl->value.enumerated.item[idx] = slot->capture_item; |
842 | snd_runtime_check((err = kctl->put(kctl, uctl)) >= 0, ); | 864 | err = kctl->put(kctl, uctl); |
843 | if (err > 0) | 865 | if (err > 0) |
844 | snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); | 866 | snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); |
845 | err = 0; | 867 | err = 0; |
@@ -1008,7 +1030,8 @@ static int snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_os | |||
1008 | up_read(&mixer->card->controls_rwsem); | 1030 | up_read(&mixer->card->controls_rwsem); |
1009 | if (slot.present != 0) { | 1031 | if (slot.present != 0) { |
1010 | pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL); | 1032 | pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL); |
1011 | snd_runtime_check(pslot != NULL, return -ENOMEM); | 1033 | if (! pslot) |
1034 | return -ENOMEM; | ||
1012 | *pslot = slot; | 1035 | *pslot = slot; |
1013 | pslot->signature = SNDRV_MIXER_OSS_SIGNATURE; | 1036 | pslot->signature = SNDRV_MIXER_OSS_SIGNATURE; |
1014 | pslot->assigned = ptr; | 1037 | pslot->assigned = ptr; |
@@ -1271,7 +1294,8 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int cmd) | |||
1271 | card, 0, | 1294 | card, 0, |
1272 | &snd_mixer_oss_reg, | 1295 | &snd_mixer_oss_reg, |
1273 | name)) < 0) { | 1296 | name)) < 0) { |
1274 | snd_printk("unable to register OSS mixer device %i:%i\n", card->number, 0); | 1297 | snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n", |
1298 | card->number, 0); | ||
1275 | kfree(mixer); | 1299 | kfree(mixer); |
1276 | return err; | 1300 | return err; |
1277 | } | 1301 | } |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 842c28b2ed55..bcc970759134 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -1821,6 +1821,17 @@ static int snd_pcm_oss_open_file(struct file *file, | |||
1821 | } | 1821 | } |
1822 | 1822 | ||
1823 | 1823 | ||
1824 | static int snd_task_name(struct task_struct *task, char *name, size_t size) | ||
1825 | { | ||
1826 | unsigned int idx; | ||
1827 | |||
1828 | snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL); | ||
1829 | for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++) | ||
1830 | name[idx] = task->comm[idx]; | ||
1831 | name[idx] = '\0'; | ||
1832 | return 0; | ||
1833 | } | ||
1834 | |||
1824 | static int snd_pcm_oss_open(struct inode *inode, struct file *file) | 1835 | static int snd_pcm_oss_open(struct inode *inode, struct file *file) |
1825 | { | 1836 | { |
1826 | int minor = iminor(inode); | 1837 | int minor = iminor(inode); |
@@ -2446,7 +2457,8 @@ static void register_oss_dsp(snd_pcm_t *pcm, int index) | |||
2446 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM, | 2457 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM, |
2447 | pcm->card, index, &snd_pcm_oss_reg, | 2458 | pcm->card, index, &snd_pcm_oss_reg, |
2448 | name) < 0) { | 2459 | name) < 0) { |
2449 | snd_printk("unable to register OSS PCM device %i:%i\n", pcm->card->number, pcm->device); | 2460 | snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n", |
2461 | pcm->card->number, pcm->device); | ||
2450 | } | 2462 | } |
2451 | } | 2463 | } |
2452 | 2464 | ||
@@ -2528,11 +2540,13 @@ static int __init alsa_pcm_oss_init(void) | |||
2528 | /* check device map table */ | 2540 | /* check device map table */ |
2529 | for (i = 0; i < SNDRV_CARDS; i++) { | 2541 | for (i = 0; i < SNDRV_CARDS; i++) { |
2530 | if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) { | 2542 | if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) { |
2531 | snd_printk("invalid dsp_map[%d] = %d\n", i, dsp_map[i]); | 2543 | snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n", |
2544 | i, dsp_map[i]); | ||
2532 | dsp_map[i] = 0; | 2545 | dsp_map[i] = 0; |
2533 | } | 2546 | } |
2534 | if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) { | 2547 | if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) { |
2535 | snd_printk("invalid adsp_map[%d] = %d\n", i, adsp_map[i]); | 2548 | snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n", |
2549 | i, adsp_map[i]); | ||
2536 | adsp_map[i] = 1; | 2550 | adsp_map[i] = 1; |
2537 | } | 2551 | } |
2538 | } | 2552 | } |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 1be470e942ef..184e74b75ba9 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -273,7 +273,8 @@ static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buff | |||
273 | snd_pcm_info_t *info; | 273 | snd_pcm_info_t *info; |
274 | int err; | 274 | int err; |
275 | 275 | ||
276 | snd_runtime_check(substream, return); | 276 | if (! substream) |
277 | return; | ||
277 | 278 | ||
278 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 279 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
279 | if (! info) { | 280 | if (! info) { |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 0503980c23d9..3dbf9bf2ac16 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -152,13 +152,12 @@ static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(snd_pcm_substream_t *s | |||
152 | if (pos == SNDRV_PCM_POS_XRUN) | 152 | if (pos == SNDRV_PCM_POS_XRUN) |
153 | return pos; /* XRUN */ | 153 | return pos; /* XRUN */ |
154 | if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) | 154 | if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) |
155 | snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec); | 155 | getnstimeofday((struct timespec *)&runtime->status->tstamp); |
156 | #ifdef CONFIG_SND_DEBUG | 156 | #ifdef CONFIG_SND_DEBUG |
157 | if (pos >= runtime->buffer_size) { | 157 | if (pos >= runtime->buffer_size) { |
158 | snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size); | 158 | snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size); |
159 | } else | 159 | } |
160 | #endif | 160 | #endif |
161 | snd_runtime_check(pos < runtime->buffer_size, return 0); | ||
162 | pos -= pos % runtime->min_align; | 161 | pos -= pos % runtime->min_align; |
163 | return pos; | 162 | return pos; |
164 | } | 163 | } |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index e97b2d162cc7..16e252f54954 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -565,9 +565,9 @@ int snd_pcm_status(snd_pcm_substream_t *substream, | |||
565 | if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) | 565 | if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) |
566 | status->tstamp = runtime->status->tstamp; | 566 | status->tstamp = runtime->status->tstamp; |
567 | else | 567 | else |
568 | snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec); | 568 | getnstimeofday(&status->tstamp); |
569 | } else | 569 | } else |
570 | snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec); | 570 | getnstimeofday(&status->tstamp); |
571 | status->appl_ptr = runtime->control->appl_ptr; | 571 | status->appl_ptr = runtime->control->appl_ptr; |
572 | status->hw_ptr = runtime->status->hw_ptr; | 572 | status->hw_ptr = runtime->status->hw_ptr; |
573 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 573 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
@@ -652,7 +652,7 @@ static void snd_pcm_trigger_tstamp(snd_pcm_substream_t *substream) | |||
652 | if (runtime->trigger_master == NULL) | 652 | if (runtime->trigger_master == NULL) |
653 | return; | 653 | return; |
654 | if (runtime->trigger_master == substream) { | 654 | if (runtime->trigger_master == substream) { |
655 | snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec); | 655 | getnstimeofday(&runtime->trigger_tstamp); |
656 | } else { | 656 | } else { |
657 | snd_pcm_trigger_tstamp(runtime->trigger_master); | 657 | snd_pcm_trigger_tstamp(runtime->trigger_master); |
658 | runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp; | 658 | runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp; |
@@ -1522,7 +1522,6 @@ static int snd_pcm_drop(snd_pcm_substream_t *substream) | |||
1522 | 1522 | ||
1523 | 1523 | ||
1524 | /* WARNING: Don't forget to fput back the file */ | 1524 | /* WARNING: Don't forget to fput back the file */ |
1525 | extern int snd_major; | ||
1526 | static struct file *snd_pcm_file_fd(int fd) | 1525 | static struct file *snd_pcm_file_fd(int fd) |
1527 | { | 1526 | { |
1528 | struct file *file; | 1527 | struct file *file; |
@@ -2053,7 +2052,8 @@ static int snd_pcm_open(struct inode *inode, struct file *file) | |||
2053 | snd_pcm_file_t *pcm_file; | 2052 | snd_pcm_file_t *pcm_file; |
2054 | wait_queue_t wait; | 2053 | wait_queue_t wait; |
2055 | 2054 | ||
2056 | snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO); | 2055 | if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES) |
2056 | return -ENXIO; | ||
2057 | pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)]; | 2057 | pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)]; |
2058 | if (pcm == NULL) { | 2058 | if (pcm == NULL) { |
2059 | err = -ENODEV; | 2059 | err = -ENODEV; |
@@ -2445,14 +2445,8 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream, | |||
2445 | return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; | 2445 | return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; |
2446 | case SNDRV_PCM_IOCTL_INFO: | 2446 | case SNDRV_PCM_IOCTL_INFO: |
2447 | return snd_pcm_info_user(substream, arg); | 2447 | return snd_pcm_info_user(substream, arg); |
2448 | case SNDRV_PCM_IOCTL_TSTAMP: | 2448 | case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */ |
2449 | { | ||
2450 | int xarg; | ||
2451 | if (get_user(xarg, (int __user *)arg)) | ||
2452 | return -EFAULT; | ||
2453 | substream->runtime->tstamp_timespec = xarg ? 1 : 0; | ||
2454 | return 0; | 2449 | return 0; |
2455 | } | ||
2456 | case SNDRV_PCM_IOCTL_HW_REFINE: | 2450 | case SNDRV_PCM_IOCTL_HW_REFINE: |
2457 | return snd_pcm_hw_refine_user(substream, arg); | 2451 | return snd_pcm_hw_refine_user(substream, arg); |
2458 | case SNDRV_PCM_IOCTL_HW_PARAMS: | 2452 | case SNDRV_PCM_IOCTL_HW_PARAMS: |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 7c20eafecb8a..d033e61c05c7 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -378,24 +378,20 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
378 | struct list_head *list; | 378 | struct list_head *list; |
379 | snd_ctl_file_t *kctl; | 379 | snd_ctl_file_t *kctl; |
380 | 380 | ||
381 | switch (maj) { | 381 | if (maj == snd_major) { |
382 | case CONFIG_SND_MAJOR: | ||
383 | cardnum = SNDRV_MINOR_CARD(iminor(inode)); | 382 | cardnum = SNDRV_MINOR_CARD(iminor(inode)); |
384 | cardnum %= SNDRV_CARDS; | 383 | cardnum %= SNDRV_CARDS; |
385 | device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI; | 384 | device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI; |
386 | device %= SNDRV_MINOR_RAWMIDIS; | 385 | device %= SNDRV_MINOR_RAWMIDIS; |
387 | break; | ||
388 | #ifdef CONFIG_SND_OSSEMUL | 386 | #ifdef CONFIG_SND_OSSEMUL |
389 | case SOUND_MAJOR: | 387 | } else if (maj == SOUND_MAJOR) { |
390 | cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); | 388 | cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); |
391 | cardnum %= SNDRV_CARDS; | 389 | cardnum %= SNDRV_CARDS; |
392 | device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ? | 390 | device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ? |
393 | midi_map[cardnum] : amidi_map[cardnum]; | 391 | midi_map[cardnum] : amidi_map[cardnum]; |
394 | break; | ||
395 | #endif | 392 | #endif |
396 | default: | 393 | } else |
397 | return -ENXIO; | 394 | return -ENXIO; |
398 | } | ||
399 | 395 | ||
400 | rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; | 396 | rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; |
401 | if (rmidi == NULL) | 397 | if (rmidi == NULL) |
@@ -411,7 +407,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
411 | if (err < 0) | 407 | if (err < 0) |
412 | return -ENODEV; | 408 | return -ENODEV; |
413 | fflags = snd_rawmidi_file_flags(file); | 409 | fflags = snd_rawmidi_file_flags(file); |
414 | if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */ | 410 | if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */ |
415 | fflags |= SNDRV_RAWMIDI_LFLG_APPEND; | 411 | fflags |= SNDRV_RAWMIDI_LFLG_APPEND; |
416 | fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK; | 412 | fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK; |
417 | rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL); | 413 | rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL); |
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index bd5d584d284d..c3c18568207e 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c | |||
@@ -60,7 +60,6 @@ static struct _snd_timer_hardware rtc_hw = { | |||
60 | 60 | ||
61 | static int rtctimer_freq = RTC_FREQ; /* frequency */ | 61 | static int rtctimer_freq = RTC_FREQ; /* frequency */ |
62 | static snd_timer_t *rtctimer; | 62 | static snd_timer_t *rtctimer; |
63 | static atomic_t rtc_inc = ATOMIC_INIT(0); | ||
64 | static rtc_task_t rtc_task; | 63 | static rtc_task_t rtc_task; |
65 | 64 | ||
66 | 65 | ||
@@ -94,7 +93,6 @@ rtctimer_start(snd_timer_t *timer) | |||
94 | snd_assert(rtc != NULL, return -EINVAL); | 93 | snd_assert(rtc != NULL, return -EINVAL); |
95 | rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq); | 94 | rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq); |
96 | rtc_control(rtc, RTC_PIE_ON, 0); | 95 | rtc_control(rtc, RTC_PIE_ON, 0); |
97 | atomic_set(&rtc_inc, 0); | ||
98 | return 0; | 96 | return 0; |
99 | } | 97 | } |
100 | 98 | ||
@@ -112,12 +110,7 @@ rtctimer_stop(snd_timer_t *timer) | |||
112 | */ | 110 | */ |
113 | static void rtctimer_interrupt(void *private_data) | 111 | static void rtctimer_interrupt(void *private_data) |
114 | { | 112 | { |
115 | int ticks; | 113 | snd_timer_interrupt(private_data, 1); |
116 | |||
117 | atomic_inc(&rtc_inc); | ||
118 | ticks = atomic_read(&rtc_inc); | ||
119 | snd_timer_interrupt((snd_timer_t*)private_data, ticks); | ||
120 | atomic_sub(ticks, &rtc_inc); | ||
121 | } | 114 | } |
122 | 115 | ||
123 | 116 | ||
@@ -126,17 +119,13 @@ static void rtctimer_interrupt(void *private_data) | |||
126 | */ | 119 | */ |
127 | static int __init rtctimer_init(void) | 120 | static int __init rtctimer_init(void) |
128 | { | 121 | { |
129 | int order, err; | 122 | int err; |
130 | snd_timer_t *timer; | 123 | snd_timer_t *timer; |
131 | 124 | ||
132 | if (rtctimer_freq < 2 || rtctimer_freq > 8192) { | 125 | if (rtctimer_freq < 2 || rtctimer_freq > 8192 || |
133 | snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq); | 126 | (rtctimer_freq & (rtctimer_freq - 1)) != 0) { |
134 | return -EINVAL; | 127 | snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", |
135 | } | 128 | rtctimer_freq); |
136 | for (order = 1; rtctimer_freq > order; order <<= 1) | ||
137 | ; | ||
138 | if (rtctimer_freq != order) { | ||
139 | snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq); | ||
140 | return -EINVAL; | 129 | return -EINVAL; |
141 | } | 130 | } |
142 | 131 | ||
@@ -145,6 +134,7 @@ static int __init rtctimer_init(void) | |||
145 | if (err < 0) | 134 | if (err < 0) |
146 | return err; | 135 | return err; |
147 | 136 | ||
137 | timer->module = THIS_MODULE; | ||
148 | strcpy(timer->name, "RTC timer"); | 138 | strcpy(timer->name, "RTC timer"); |
149 | timer->hw = rtc_hw; | 139 | timer->hw = rtc_hw; |
150 | timer->hw.resolution = NANO_SEC / rtctimer_freq; | 140 | timer->hw.resolution = NANO_SEC / rtctimer_freq; |
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c index 019d43a462d7..1d525b13ebb6 100644 --- a/sound/core/seq/seq_instr.c +++ b/sound/core/seq/seq_instr.c | |||
@@ -109,8 +109,7 @@ void snd_seq_instr_list_free(snd_seq_kinstr_list_t **list_ptr) | |||
109 | spin_lock_irqsave(&list->lock, flags); | 109 | spin_lock_irqsave(&list->lock, flags); |
110 | while (instr->use) { | 110 | while (instr->use) { |
111 | spin_unlock_irqrestore(&list->lock, flags); | 111 | spin_unlock_irqrestore(&list->lock, flags); |
112 | set_current_state(TASK_INTERRUPTIBLE); | 112 | schedule_timeout_interruptible(1); |
113 | schedule_timeout(1); | ||
114 | spin_lock_irqsave(&list->lock, flags); | 113 | spin_lock_irqsave(&list->lock, flags); |
115 | } | 114 | } |
116 | spin_unlock_irqrestore(&list->lock, flags); | 115 | spin_unlock_irqrestore(&list->lock, flags); |
@@ -199,10 +198,8 @@ int snd_seq_instr_list_free_cond(snd_seq_kinstr_list_t *list, | |||
199 | while (flist) { | 198 | while (flist) { |
200 | instr = flist; | 199 | instr = flist; |
201 | flist = instr->next; | 200 | flist = instr->next; |
202 | while (instr->use) { | 201 | while (instr->use) |
203 | set_current_state(TASK_INTERRUPTIBLE); | 202 | schedule_timeout_interruptible(1); |
204 | schedule_timeout(1); | ||
205 | } | ||
206 | if (snd_seq_instr_free(instr, atomic)<0) | 203 | if (snd_seq_instr_free(instr, atomic)<0) |
207 | snd_printk(KERN_WARNING "instrument free problem\n"); | 204 | snd_printk(KERN_WARNING "instrument free problem\n"); |
208 | instr = next; | 205 | instr = next; |
@@ -554,8 +551,7 @@ static int instr_free(snd_seq_kinstr_ops_t *ops, | |||
554 | instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE); | 551 | instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE); |
555 | while (instr->use) { | 552 | while (instr->use) { |
556 | spin_unlock_irqrestore(&list->lock, flags); | 553 | spin_unlock_irqrestore(&list->lock, flags); |
557 | set_current_state(TASK_INTERRUPTIBLE); | 554 | schedule_timeout_interruptible(1); |
558 | schedule_timeout(1); | ||
559 | spin_lock_irqsave(&list->lock, flags); | 555 | spin_lock_irqsave(&list->lock, flags); |
560 | } | 556 | } |
561 | spin_unlock_irqrestore(&list->lock, flags); | 557 | spin_unlock_irqrestore(&list->lock, flags); |
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c index b09cee058fa7..a837a94b2d2a 100644 --- a/sound/core/seq/seq_lock.c +++ b/sound/core/seq/seq_lock.c | |||
@@ -39,8 +39,7 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) | |||
39 | snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); | 39 | snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); |
40 | break; | 40 | break; |
41 | } | 41 | } |
42 | set_current_state(TASK_UNINTERRUPTIBLE); | 42 | schedule_timeout_uninterruptible(1); |
43 | schedule_timeout(1); | ||
44 | max_count--; | 43 | max_count--; |
45 | } | 44 | } |
46 | } | 45 | } |
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index d4d7d326c4b1..8416bcffa091 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c | |||
@@ -423,8 +423,7 @@ int snd_seq_pool_done(pool_t *pool) | |||
423 | snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter)); | 423 | snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter)); |
424 | break; | 424 | break; |
425 | } | 425 | } |
426 | set_current_state(TASK_UNINTERRUPTIBLE); | 426 | schedule_timeout_uninterruptible(1); |
427 | schedule_timeout(1); | ||
428 | max_count--; | 427 | max_count--; |
429 | } | 428 | } |
430 | 429 | ||
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index b4674ae3bc30..f89f40f44876 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -449,11 +449,9 @@ snd_seq_midisynth_unregister_port(snd_seq_device_t *dev) | |||
449 | client->ports_per_device[device] = 0; | 449 | client->ports_per_device[device] = 0; |
450 | msynth = client->ports[device]; | 450 | msynth = client->ports[device]; |
451 | client->ports[device] = NULL; | 451 | client->ports[device] = NULL; |
452 | snd_runtime_check(msynth != NULL || ports <= 0, goto __skip); | ||
453 | for (p = 0; p < ports; p++) | 452 | for (p = 0; p < ports; p++) |
454 | snd_seq_midisynth_delete(&msynth[p]); | 453 | snd_seq_midisynth_delete(&msynth[p]); |
455 | kfree(msynth); | 454 | kfree(msynth); |
456 | __skip: | ||
457 | client->num_ports--; | 455 | client->num_ports--; |
458 | if (client->num_ports <= 0) { | 456 | if (client->num_ports <= 0) { |
459 | snd_seq_delete_kernel_client(client->seq_client); | 457 | snd_seq_delete_kernel_client(client->seq_client); |
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index b57a3c07ff6f..65b64a7c456d 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c | |||
@@ -34,10 +34,15 @@ extern int seq_default_timer_device; | |||
34 | extern int seq_default_timer_subdevice; | 34 | extern int seq_default_timer_subdevice; |
35 | extern int seq_default_timer_resolution; | 35 | extern int seq_default_timer_resolution; |
36 | 36 | ||
37 | /* allowed sequencer timer frequencies, in Hz */ | ||
38 | #define MIN_FREQUENCY 10 | ||
39 | #define MAX_FREQUENCY 6250 | ||
40 | #define DEFAULT_FREQUENCY 1000 | ||
41 | |||
37 | #define SKEW_BASE 0x10000 /* 16bit shift */ | 42 | #define SKEW_BASE 0x10000 /* 16bit shift */ |
38 | 43 | ||
39 | static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, | 44 | static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, |
40 | int tempo, int ppq, int nticks) | 45 | int tempo, int ppq) |
41 | { | 46 | { |
42 | if (tempo < 1000000) | 47 | if (tempo < 1000000) |
43 | tick->resolution = (tempo * 1000) / ppq; | 48 | tick->resolution = (tempo * 1000) / ppq; |
@@ -51,7 +56,6 @@ static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, | |||
51 | } | 56 | } |
52 | if (tick->resolution <= 0) | 57 | if (tick->resolution <= 0) |
53 | tick->resolution = 1; | 58 | tick->resolution = 1; |
54 | tick->resolution *= nticks; | ||
55 | snd_seq_timer_update_tick(tick, 0); | 59 | snd_seq_timer_update_tick(tick, 0); |
56 | } | 60 | } |
57 | 61 | ||
@@ -100,7 +104,7 @@ void snd_seq_timer_defaults(seq_timer_t * tmr) | |||
100 | /* setup defaults */ | 104 | /* setup defaults */ |
101 | tmr->ppq = 96; /* 96 PPQ */ | 105 | tmr->ppq = 96; /* 96 PPQ */ |
102 | tmr->tempo = 500000; /* 120 BPM */ | 106 | tmr->tempo = 500000; /* 120 BPM */ |
103 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); | 107 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); |
104 | tmr->running = 0; | 108 | tmr->running = 0; |
105 | 109 | ||
106 | tmr->type = SNDRV_SEQ_TIMER_ALSA; | 110 | tmr->type = SNDRV_SEQ_TIMER_ALSA; |
@@ -183,7 +187,7 @@ int snd_seq_timer_set_tempo(seq_timer_t * tmr, int tempo) | |||
183 | spin_lock_irqsave(&tmr->lock, flags); | 187 | spin_lock_irqsave(&tmr->lock, flags); |
184 | if ((unsigned int)tempo != tmr->tempo) { | 188 | if ((unsigned int)tempo != tmr->tempo) { |
185 | tmr->tempo = tempo; | 189 | tmr->tempo = tempo; |
186 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); | 190 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); |
187 | } | 191 | } |
188 | spin_unlock_irqrestore(&tmr->lock, flags); | 192 | spin_unlock_irqrestore(&tmr->lock, flags); |
189 | return 0; | 193 | return 0; |
@@ -207,7 +211,7 @@ int snd_seq_timer_set_ppq(seq_timer_t * tmr, int ppq) | |||
207 | } | 211 | } |
208 | 212 | ||
209 | tmr->ppq = ppq; | 213 | tmr->ppq = ppq; |
210 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); | 214 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); |
211 | spin_unlock_irqrestore(&tmr->lock, flags); | 215 | spin_unlock_irqrestore(&tmr->lock, flags); |
212 | return 0; | 216 | return 0; |
213 | } | 217 | } |
@@ -326,17 +330,26 @@ int snd_seq_timer_stop(seq_timer_t * tmr) | |||
326 | static int initialize_timer(seq_timer_t *tmr) | 330 | static int initialize_timer(seq_timer_t *tmr) |
327 | { | 331 | { |
328 | snd_timer_t *t; | 332 | snd_timer_t *t; |
333 | unsigned long freq; | ||
334 | |||
329 | t = tmr->timeri->timer; | 335 | t = tmr->timeri->timer; |
330 | snd_assert(t, return -EINVAL); | 336 | snd_assert(t, return -EINVAL); |
331 | 337 | ||
338 | freq = tmr->preferred_resolution; | ||
339 | if (!freq) | ||
340 | freq = DEFAULT_FREQUENCY; | ||
341 | else if (freq < MIN_FREQUENCY) | ||
342 | freq = MIN_FREQUENCY; | ||
343 | else if (freq > MAX_FREQUENCY) | ||
344 | freq = MAX_FREQUENCY; | ||
345 | |||
332 | tmr->ticks = 1; | 346 | tmr->ticks = 1; |
333 | if (tmr->preferred_resolution && | 347 | if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { |
334 | ! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { | ||
335 | unsigned long r = t->hw.resolution; | 348 | unsigned long r = t->hw.resolution; |
336 | if (! r && t->hw.c_resolution) | 349 | if (! r && t->hw.c_resolution) |
337 | r = t->hw.c_resolution(t); | 350 | r = t->hw.c_resolution(t); |
338 | if (r) { | 351 | if (r) { |
339 | tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution)); | 352 | tmr->ticks = (unsigned int)(1000000000uL / (r * freq)); |
340 | if (! tmr->ticks) | 353 | if (! tmr->ticks) |
341 | tmr->ticks = 1; | 354 | tmr->ticks = 1; |
342 | } | 355 | } |
diff --git a/sound/core/sound.c b/sound/core/sound.c index b57519a3e3d9..1139dd8ca8eb 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -130,7 +130,7 @@ static int snd_open(struct inode *inode, struct file *file) | |||
130 | struct file_operations *old_fops; | 130 | struct file_operations *old_fops; |
131 | int err = 0; | 131 | int err = 0; |
132 | 132 | ||
133 | if (dev != SNDRV_MINOR_SEQUENCER && dev != SNDRV_MINOR_TIMER) { | 133 | if (dev != SNDRV_MINOR_GLOBAL) { |
134 | if (snd_cards[card] == NULL) { | 134 | if (snd_cards[card] == NULL) { |
135 | #ifdef CONFIG_KMOD | 135 | #ifdef CONFIG_KMOD |
136 | snd_request_card(card); | 136 | snd_request_card(card); |
@@ -287,7 +287,7 @@ static void snd_minor_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buf | |||
287 | for (card = 0; card < SNDRV_CARDS; card++) { | 287 | for (card = 0; card < SNDRV_CARDS; card++) { |
288 | list_for_each(list, &snd_minors_hash[card]) { | 288 | list_for_each(list, &snd_minors_hash[card]) { |
289 | mptr = list_entry(list, snd_minor_t, list); | 289 | mptr = list_entry(list, snd_minor_t, list); |
290 | if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_SEQUENCER) { | 290 | if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) { |
291 | if ((device = mptr->device) >= 0) | 291 | if ((device = mptr->device) >= 0) |
292 | snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment); | 292 | snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment); |
293 | else | 293 | else |
@@ -350,9 +350,7 @@ static int __init alsa_sound_init(void) | |||
350 | devfs_remove("snd"); | 350 | devfs_remove("snd"); |
351 | return -EIO; | 351 | return -EIO; |
352 | } | 352 | } |
353 | snd_memory_init(); | ||
354 | if (snd_info_init() < 0) { | 353 | if (snd_info_init() < 0) { |
355 | snd_memory_done(); | ||
356 | unregister_chrdev(major, "alsa"); | 354 | unregister_chrdev(major, "alsa"); |
357 | devfs_remove("snd"); | 355 | devfs_remove("snd"); |
358 | return -ENOMEM; | 356 | return -ENOMEM; |
@@ -381,7 +379,6 @@ static void __exit alsa_sound_exit(void) | |||
381 | #endif | 379 | #endif |
382 | snd_info_minor_unregister(); | 380 | snd_info_minor_unregister(); |
383 | snd_info_done(); | 381 | snd_info_done(); |
384 | snd_memory_done(); | ||
385 | if (unregister_chrdev(major, "alsa") != 0) | 382 | if (unregister_chrdev(major, "alsa") != 0) |
386 | snd_printk(KERN_ERR "unable to unregister major device number %d\n", major); | 383 | snd_printk(KERN_ERR "unable to unregister major device number %d\n", major); |
387 | devfs_remove("snd"); | 384 | devfs_remove("snd"); |
@@ -403,14 +400,6 @@ EXPORT_SYMBOL(snd_register_oss_device); | |||
403 | EXPORT_SYMBOL(snd_unregister_oss_device); | 400 | EXPORT_SYMBOL(snd_unregister_oss_device); |
404 | #endif | 401 | #endif |
405 | /* memory.c */ | 402 | /* memory.c */ |
406 | #ifdef CONFIG_SND_DEBUG_MEMORY | ||
407 | EXPORT_SYMBOL(snd_hidden_kmalloc); | ||
408 | EXPORT_SYMBOL(snd_hidden_kcalloc); | ||
409 | EXPORT_SYMBOL(snd_hidden_kfree); | ||
410 | EXPORT_SYMBOL(snd_hidden_vmalloc); | ||
411 | EXPORT_SYMBOL(snd_hidden_vfree); | ||
412 | EXPORT_SYMBOL(snd_hidden_kstrdup); | ||
413 | #endif | ||
414 | EXPORT_SYMBOL(copy_to_user_fromio); | 403 | EXPORT_SYMBOL(copy_to_user_fromio); |
415 | EXPORT_SYMBOL(copy_from_user_toio); | 404 | EXPORT_SYMBOL(copy_from_user_toio); |
416 | /* init.c */ | 405 | /* init.c */ |
@@ -487,17 +476,10 @@ EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); | |||
487 | EXPORT_SYMBOL(snd_ctl_elem_read); | 476 | EXPORT_SYMBOL(snd_ctl_elem_read); |
488 | EXPORT_SYMBOL(snd_ctl_elem_write); | 477 | EXPORT_SYMBOL(snd_ctl_elem_write); |
489 | /* misc.c */ | 478 | /* misc.c */ |
490 | EXPORT_SYMBOL(snd_task_name); | 479 | EXPORT_SYMBOL(release_and_free_resource); |
491 | #ifdef CONFIG_SND_VERBOSE_PRINTK | 480 | #ifdef CONFIG_SND_VERBOSE_PRINTK |
492 | EXPORT_SYMBOL(snd_verbose_printk); | 481 | EXPORT_SYMBOL(snd_verbose_printk); |
493 | #endif | 482 | #endif |
494 | #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) | 483 | #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) |
495 | EXPORT_SYMBOL(snd_verbose_printd); | 484 | EXPORT_SYMBOL(snd_verbose_printd); |
496 | #endif | 485 | #endif |
497 | /* wrappers */ | ||
498 | #ifdef CONFIG_SND_DEBUG_MEMORY | ||
499 | EXPORT_SYMBOL(snd_wrapper_kmalloc); | ||
500 | EXPORT_SYMBOL(snd_wrapper_kfree); | ||
501 | EXPORT_SYMBOL(snd_wrapper_vmalloc); | ||
502 | EXPORT_SYMBOL(snd_wrapper_vfree); | ||
503 | #endif | ||
diff --git a/sound/core/timer.c b/sound/core/timer.c index 22b104624084..1b90a38d10ff 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); | |||
55 | 55 | ||
56 | typedef struct { | 56 | typedef struct { |
57 | snd_timer_instance_t *timeri; | 57 | snd_timer_instance_t *timeri; |
58 | int tread; /* enhanced read with timestamps and events */ | 58 | int tread; /* enhanced read with timestamps and events */ |
59 | unsigned long ticks; | 59 | unsigned long ticks; |
60 | unsigned long overrun; | 60 | unsigned long overrun; |
61 | int qhead; | 61 | int qhead; |
@@ -95,7 +95,8 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left); | |||
95 | * create a timer instance with the given owner string. | 95 | * create a timer instance with the given owner string. |
96 | * when timer is not NULL, increments the module counter | 96 | * when timer is not NULL, increments the module counter |
97 | */ | 97 | */ |
98 | static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) | 98 | static snd_timer_instance_t *snd_timer_instance_new(char *owner, |
99 | snd_timer_t *timer) | ||
99 | { | 100 | { |
100 | snd_timer_instance_t *timeri; | 101 | snd_timer_instance_t *timeri; |
101 | timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); | 102 | timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); |
@@ -113,7 +114,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti | |||
113 | INIT_LIST_HEAD(&timeri->slave_active_head); | 114 | INIT_LIST_HEAD(&timeri->slave_active_head); |
114 | 115 | ||
115 | timeri->timer = timer; | 116 | timeri->timer = timer; |
116 | if (timer && timer->card && !try_module_get(timer->card->module)) { | 117 | if (timer && !try_module_get(timer->module)) { |
117 | kfree(timeri->owner); | 118 | kfree(timeri->owner); |
118 | kfree(timeri); | 119 | kfree(timeri); |
119 | return NULL; | 120 | return NULL; |
@@ -131,7 +132,7 @@ static snd_timer_t *snd_timer_find(snd_timer_id_t *tid) | |||
131 | struct list_head *p; | 132 | struct list_head *p; |
132 | 133 | ||
133 | list_for_each(p, &snd_timer_list) { | 134 | list_for_each(p, &snd_timer_list) { |
134 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 135 | timer = list_entry(p, snd_timer_t, device_list); |
135 | 136 | ||
136 | if (timer->tmr_class != tid->dev_class) | 137 | if (timer->tmr_class != tid->dev_class) |
137 | continue; | 138 | continue; |
@@ -186,13 +187,14 @@ static void snd_timer_check_slave(snd_timer_instance_t *slave) | |||
186 | 187 | ||
187 | /* FIXME: it's really dumb to look up all entries.. */ | 188 | /* FIXME: it's really dumb to look up all entries.. */ |
188 | list_for_each(p, &snd_timer_list) { | 189 | list_for_each(p, &snd_timer_list) { |
189 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 190 | timer = list_entry(p, snd_timer_t, device_list); |
190 | list_for_each(q, &timer->open_list_head) { | 191 | list_for_each(q, &timer->open_list_head) { |
191 | master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list); | 192 | master = list_entry(q, snd_timer_instance_t, open_list); |
192 | if (slave->slave_class == master->slave_class && | 193 | if (slave->slave_class == master->slave_class && |
193 | slave->slave_id == master->slave_id) { | 194 | slave->slave_id == master->slave_id) { |
194 | list_del(&slave->open_list); | 195 | list_del(&slave->open_list); |
195 | list_add_tail(&slave->open_list, &master->slave_list_head); | 196 | list_add_tail(&slave->open_list, |
197 | &master->slave_list_head); | ||
196 | spin_lock_irq(&slave_active_lock); | 198 | spin_lock_irq(&slave_active_lock); |
197 | slave->master = master; | 199 | slave->master = master; |
198 | slave->timer = master->timer; | 200 | slave->timer = master->timer; |
@@ -216,7 +218,7 @@ static void snd_timer_check_master(snd_timer_instance_t *master) | |||
216 | 218 | ||
217 | /* check all pending slaves */ | 219 | /* check all pending slaves */ |
218 | list_for_each_safe(p, n, &snd_timer_slave_list) { | 220 | list_for_each_safe(p, n, &snd_timer_slave_list) { |
219 | slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); | 221 | slave = list_entry(p, snd_timer_instance_t, open_list); |
220 | if (slave->slave_class == master->slave_class && | 222 | if (slave->slave_class == master->slave_class && |
221 | slave->slave_id == master->slave_id) { | 223 | slave->slave_id == master->slave_id) { |
222 | list_del(p); | 224 | list_del(p); |
@@ -225,7 +227,8 @@ static void snd_timer_check_master(snd_timer_instance_t *master) | |||
225 | slave->master = master; | 227 | slave->master = master; |
226 | slave->timer = master->timer; | 228 | slave->timer = master->timer; |
227 | if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) | 229 | if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) |
228 | list_add_tail(&slave->active_list, &master->slave_active_head); | 230 | list_add_tail(&slave->active_list, |
231 | &master->slave_active_head); | ||
229 | spin_unlock_irq(&slave_active_lock); | 232 | spin_unlock_irq(&slave_active_lock); |
230 | } | 233 | } |
231 | } | 234 | } |
@@ -241,7 +244,7 @@ int snd_timer_open(snd_timer_instance_t **ti, | |||
241 | { | 244 | { |
242 | snd_timer_t *timer; | 245 | snd_timer_t *timer; |
243 | snd_timer_instance_t *timeri = NULL; | 246 | snd_timer_instance_t *timeri = NULL; |
244 | 247 | ||
245 | if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { | 248 | if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { |
246 | /* open a slave instance */ | 249 | /* open a slave instance */ |
247 | if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || | 250 | if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || |
@@ -251,6 +254,10 @@ int snd_timer_open(snd_timer_instance_t **ti, | |||
251 | } | 254 | } |
252 | down(®ister_mutex); | 255 | down(®ister_mutex); |
253 | timeri = snd_timer_instance_new(owner, NULL); | 256 | timeri = snd_timer_instance_new(owner, NULL); |
257 | if (!timeri) { | ||
258 | up(®ister_mutex); | ||
259 | return -ENOMEM; | ||
260 | } | ||
254 | timeri->slave_class = tid->dev_sclass; | 261 | timeri->slave_class = tid->dev_sclass; |
255 | timeri->slave_id = tid->device; | 262 | timeri->slave_id = tid->device; |
256 | timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; | 263 | timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; |
@@ -272,33 +279,36 @@ int snd_timer_open(snd_timer_instance_t **ti, | |||
272 | timer = snd_timer_find(tid); | 279 | timer = snd_timer_find(tid); |
273 | } | 280 | } |
274 | #endif | 281 | #endif |
275 | if (timer) { | 282 | if (!timer) { |
276 | if (!list_empty(&timer->open_list_head)) { | ||
277 | timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list); | ||
278 | if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { | ||
279 | up(®ister_mutex); | ||
280 | return -EBUSY; | ||
281 | } | ||
282 | } | ||
283 | timeri = snd_timer_instance_new(owner, timer); | ||
284 | if (timeri) { | ||
285 | timeri->slave_class = tid->dev_sclass; | ||
286 | timeri->slave_id = slave_id; | ||
287 | if (list_empty(&timer->open_list_head) && timer->hw.open) | ||
288 | timer->hw.open(timer); | ||
289 | list_add_tail(&timeri->open_list, &timer->open_list_head); | ||
290 | snd_timer_check_master(timeri); | ||
291 | } | ||
292 | } else { | ||
293 | up(®ister_mutex); | 283 | up(®ister_mutex); |
294 | return -ENODEV; | 284 | return -ENODEV; |
295 | } | 285 | } |
286 | if (!list_empty(&timer->open_list_head)) { | ||
287 | timeri = list_entry(timer->open_list_head.next, | ||
288 | snd_timer_instance_t, open_list); | ||
289 | if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { | ||
290 | up(®ister_mutex); | ||
291 | return -EBUSY; | ||
292 | } | ||
293 | } | ||
294 | timeri = snd_timer_instance_new(owner, timer); | ||
295 | if (!timeri) { | ||
296 | up(®ister_mutex); | ||
297 | return -ENOMEM; | ||
298 | } | ||
299 | timeri->slave_class = tid->dev_sclass; | ||
300 | timeri->slave_id = slave_id; | ||
301 | if (list_empty(&timer->open_list_head) && timer->hw.open) | ||
302 | timer->hw.open(timer); | ||
303 | list_add_tail(&timeri->open_list, &timer->open_list_head); | ||
304 | snd_timer_check_master(timeri); | ||
296 | up(®ister_mutex); | 305 | up(®ister_mutex); |
297 | *ti = timeri; | 306 | *ti = timeri; |
298 | return 0; | 307 | return 0; |
299 | } | 308 | } |
300 | 309 | ||
301 | static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); | 310 | static int _snd_timer_stop(snd_timer_instance_t * timeri, |
311 | int keep_flag, enum sndrv_timer_event event); | ||
302 | 312 | ||
303 | /* | 313 | /* |
304 | * close a timer instance | 314 | * close a timer instance |
@@ -338,11 +348,12 @@ int snd_timer_close(snd_timer_instance_t * timeri) | |||
338 | spin_unlock_irq(&timer->lock); | 348 | spin_unlock_irq(&timer->lock); |
339 | down(®ister_mutex); | 349 | down(®ister_mutex); |
340 | list_del(&timeri->open_list); | 350 | list_del(&timeri->open_list); |
341 | if (timer && list_empty(&timer->open_list_head) && timer->hw.close) | 351 | if (timer && list_empty(&timer->open_list_head) && |
352 | timer->hw.close) | ||
342 | timer->hw.close(timer); | 353 | timer->hw.close(timer); |
343 | /* remove slave links */ | 354 | /* remove slave links */ |
344 | list_for_each_safe(p, n, &timeri->slave_list_head) { | 355 | list_for_each_safe(p, n, &timeri->slave_list_head) { |
345 | slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); | 356 | slave = list_entry(p, snd_timer_instance_t, open_list); |
346 | spin_lock_irq(&slave_active_lock); | 357 | spin_lock_irq(&slave_active_lock); |
347 | _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); | 358 | _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); |
348 | list_del(p); | 359 | list_del(p); |
@@ -357,8 +368,8 @@ int snd_timer_close(snd_timer_instance_t * timeri) | |||
357 | timeri->private_free(timeri); | 368 | timeri->private_free(timeri); |
358 | kfree(timeri->owner); | 369 | kfree(timeri->owner); |
359 | kfree(timeri); | 370 | kfree(timeri); |
360 | if (timer && timer->card) | 371 | if (timer) |
361 | module_put(timer->card->module); | 372 | module_put(timer->module); |
362 | return 0; | 373 | return 0; |
363 | } | 374 | } |
364 | 375 | ||
@@ -376,7 +387,8 @@ unsigned long snd_timer_resolution(snd_timer_instance_t * timeri) | |||
376 | return 0; | 387 | return 0; |
377 | } | 388 | } |
378 | 389 | ||
379 | static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) | 390 | static void snd_timer_notify1(snd_timer_instance_t *ti, |
391 | enum sndrv_timer_event event) | ||
380 | { | 392 | { |
381 | snd_timer_t *timer; | 393 | snd_timer_t *timer; |
382 | unsigned long flags; | 394 | unsigned long flags; |
@@ -385,9 +397,11 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e | |||
385 | struct list_head *n; | 397 | struct list_head *n; |
386 | struct timespec tstamp; | 398 | struct timespec tstamp; |
387 | 399 | ||
388 | snd_timestamp_now(&tstamp, 1); | 400 | getnstimeofday(&tstamp); |
389 | snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); | 401 | snd_assert(event >= SNDRV_TIMER_EVENT_START && |
390 | if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) | 402 | event <= SNDRV_TIMER_EVENT_PAUSE, return); |
403 | if (event == SNDRV_TIMER_EVENT_START || | ||
404 | event == SNDRV_TIMER_EVENT_CONTINUE) | ||
391 | resolution = snd_timer_resolution(ti); | 405 | resolution = snd_timer_resolution(ti); |
392 | if (ti->ccallback) | 406 | if (ti->ccallback) |
393 | ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); | 407 | ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); |
@@ -400,14 +414,15 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e | |||
400 | return; | 414 | return; |
401 | spin_lock_irqsave(&timer->lock, flags); | 415 | spin_lock_irqsave(&timer->lock, flags); |
402 | list_for_each(n, &ti->slave_active_head) { | 416 | list_for_each(n, &ti->slave_active_head) { |
403 | ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list); | 417 | ts = list_entry(n, snd_timer_instance_t, active_list); |
404 | if (ts->ccallback) | 418 | if (ts->ccallback) |
405 | ts->ccallback(ti, event + 100, &tstamp, resolution); | 419 | ts->ccallback(ti, event + 100, &tstamp, resolution); |
406 | } | 420 | } |
407 | spin_unlock_irqrestore(&timer->lock, flags); | 421 | spin_unlock_irqrestore(&timer->lock, flags); |
408 | } | 422 | } |
409 | 423 | ||
410 | static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) | 424 | static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, |
425 | unsigned long sticks) | ||
411 | { | 426 | { |
412 | list_del(&timeri->active_list); | 427 | list_del(&timeri->active_list); |
413 | list_add_tail(&timeri->active_list, &timer->active_list_head); | 428 | list_add_tail(&timeri->active_list, &timer->active_list_head); |
@@ -434,14 +449,15 @@ static int snd_timer_start_slave(snd_timer_instance_t *timeri) | |||
434 | spin_lock_irqsave(&slave_active_lock, flags); | 449 | spin_lock_irqsave(&slave_active_lock, flags); |
435 | timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; | 450 | timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; |
436 | if (timeri->master) | 451 | if (timeri->master) |
437 | list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); | 452 | list_add_tail(&timeri->active_list, |
453 | &timeri->master->slave_active_head); | ||
438 | spin_unlock_irqrestore(&slave_active_lock, flags); | 454 | spin_unlock_irqrestore(&slave_active_lock, flags); |
439 | return 1; /* delayed start */ | 455 | return 1; /* delayed start */ |
440 | } | 456 | } |
441 | 457 | ||
442 | /* | 458 | /* |
443 | * start the timer instance | 459 | * start the timer instance |
444 | */ | 460 | */ |
445 | int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) | 461 | int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) |
446 | { | 462 | { |
447 | snd_timer_t *timer; | 463 | snd_timer_t *timer; |
@@ -467,7 +483,8 @@ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) | |||
467 | return result; | 483 | return result; |
468 | } | 484 | } |
469 | 485 | ||
470 | static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) | 486 | static int _snd_timer_stop(snd_timer_instance_t * timeri, |
487 | int keep_flag, enum sndrv_timer_event event) | ||
471 | { | 488 | { |
472 | snd_timer_t *timer; | 489 | snd_timer_t *timer; |
473 | unsigned long flags; | 490 | unsigned long flags; |
@@ -501,7 +518,8 @@ static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sn | |||
501 | } | 518 | } |
502 | } | 519 | } |
503 | if (!keep_flag) | 520 | if (!keep_flag) |
504 | timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START); | 521 | timeri->flags &= |
522 | ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); | ||
505 | spin_unlock_irqrestore(&timer->lock, flags); | 523 | spin_unlock_irqrestore(&timer->lock, flags); |
506 | __end: | 524 | __end: |
507 | if (event != SNDRV_TIMER_EVENT_RESOLUTION) | 525 | if (event != SNDRV_TIMER_EVENT_RESOLUTION) |
@@ -578,7 +596,7 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left) | |||
578 | struct list_head *p; | 596 | struct list_head *p; |
579 | 597 | ||
580 | list_for_each(p, &timer->active_list_head) { | 598 | list_for_each(p, &timer->active_list_head) { |
581 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); | 599 | ti = list_entry(p, snd_timer_instance_t, active_list); |
582 | if (ti->flags & SNDRV_TIMER_IFLG_START) { | 600 | if (ti->flags & SNDRV_TIMER_IFLG_START) { |
583 | ti->flags &= ~SNDRV_TIMER_IFLG_START; | 601 | ti->flags &= ~SNDRV_TIMER_IFLG_START; |
584 | ti->flags |= SNDRV_TIMER_IFLG_RUNNING; | 602 | ti->flags |= SNDRV_TIMER_IFLG_RUNNING; |
@@ -615,11 +633,11 @@ static void snd_timer_tasklet(unsigned long arg) | |||
615 | /* now process all callbacks */ | 633 | /* now process all callbacks */ |
616 | while (!list_empty(&timer->sack_list_head)) { | 634 | while (!list_empty(&timer->sack_list_head)) { |
617 | p = timer->sack_list_head.next; /* get first item */ | 635 | p = timer->sack_list_head.next; /* get first item */ |
618 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); | 636 | ti = list_entry(p, snd_timer_instance_t, ack_list); |
619 | 637 | ||
620 | /* remove from ack_list and make empty */ | 638 | /* remove from ack_list and make empty */ |
621 | list_del_init(p); | 639 | list_del_init(p); |
622 | 640 | ||
623 | ticks = ti->pticks; | 641 | ticks = ti->pticks; |
624 | ti->pticks = 0; | 642 | ti->pticks = 0; |
625 | resolution = ti->resolution; | 643 | resolution = ti->resolution; |
@@ -644,7 +662,7 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
644 | { | 662 | { |
645 | snd_timer_instance_t *ti, *ts; | 663 | snd_timer_instance_t *ti, *ts; |
646 | unsigned long resolution, ticks; | 664 | unsigned long resolution, ticks; |
647 | struct list_head *p, *q, *n; | 665 | struct list_head *p, *q, *n, *ack_list_head; |
648 | int use_tasklet = 0; | 666 | int use_tasklet = 0; |
649 | 667 | ||
650 | if (timer == NULL) | 668 | if (timer == NULL) |
@@ -659,11 +677,12 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
659 | resolution = timer->hw.resolution; | 677 | resolution = timer->hw.resolution; |
660 | 678 | ||
661 | /* loop for all active instances | 679 | /* loop for all active instances |
662 | * here we cannot use list_for_each because the active_list of a processed | 680 | * Here we cannot use list_for_each because the active_list of a |
663 | * instance is relinked to done_list_head before callback is called. | 681 | * processed instance is relinked to done_list_head before the callback |
682 | * is called. | ||
664 | */ | 683 | */ |
665 | list_for_each_safe(p, n, &timer->active_list_head) { | 684 | list_for_each_safe(p, n, &timer->active_list_head) { |
666 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); | 685 | ti = list_entry(p, snd_timer_instance_t, active_list); |
667 | if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) | 686 | if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) |
668 | continue; | 687 | continue; |
669 | ti->pticks += ticks_left; | 688 | ti->pticks += ticks_left; |
@@ -681,26 +700,19 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
681 | if (--timer->running) | 700 | if (--timer->running) |
682 | list_del(p); | 701 | list_del(p); |
683 | } | 702 | } |
684 | if (list_empty(&ti->ack_list)) { | 703 | if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || |
685 | if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || | 704 | (ti->flags & SNDRV_TIMER_IFLG_FAST)) |
686 | (ti->flags & SNDRV_TIMER_IFLG_FAST)) { | 705 | ack_list_head = &timer->ack_list_head; |
687 | list_add_tail(&ti->ack_list, &timer->ack_list_head); | 706 | else |
688 | } else { | 707 | ack_list_head = &timer->sack_list_head; |
689 | list_add_tail(&ti->ack_list, &timer->sack_list_head); | 708 | if (list_empty(&ti->ack_list)) |
690 | } | 709 | list_add_tail(&ti->ack_list, ack_list_head); |
691 | } | ||
692 | list_for_each(q, &ti->slave_active_head) { | 710 | list_for_each(q, &ti->slave_active_head) { |
693 | ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list); | 711 | ts = list_entry(q, snd_timer_instance_t, active_list); |
694 | ts->pticks = ti->pticks; | 712 | ts->pticks = ti->pticks; |
695 | ts->resolution = resolution; | 713 | ts->resolution = resolution; |
696 | if (list_empty(&ts->ack_list)) { | 714 | if (list_empty(&ts->ack_list)) |
697 | if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || | 715 | list_add_tail(&ts->ack_list, ack_list_head); |
698 | (ti->flags & SNDRV_TIMER_IFLG_FAST)) { | ||
699 | list_add_tail(&ts->ack_list, &timer->ack_list_head); | ||
700 | } else { | ||
701 | list_add_tail(&ts->ack_list, &timer->sack_list_head); | ||
702 | } | ||
703 | } | ||
704 | } | 716 | } |
705 | } | 717 | } |
706 | if (timer->flags & SNDRV_TIMER_FLG_RESCHED) | 718 | if (timer->flags & SNDRV_TIMER_FLG_RESCHED) |
@@ -723,11 +735,11 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
723 | /* now process all fast callbacks */ | 735 | /* now process all fast callbacks */ |
724 | while (!list_empty(&timer->ack_list_head)) { | 736 | while (!list_empty(&timer->ack_list_head)) { |
725 | p = timer->ack_list_head.next; /* get first item */ | 737 | p = timer->ack_list_head.next; /* get first item */ |
726 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); | 738 | ti = list_entry(p, snd_timer_instance_t, ack_list); |
727 | 739 | ||
728 | /* remove from ack_list and make empty */ | 740 | /* remove from ack_list and make empty */ |
729 | list_del_init(p); | 741 | list_del_init(p); |
730 | 742 | ||
731 | ticks = ti->pticks; | 743 | ticks = ti->pticks; |
732 | ti->pticks = 0; | 744 | ti->pticks = 0; |
733 | 745 | ||
@@ -751,7 +763,8 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
751 | 763 | ||
752 | */ | 764 | */ |
753 | 765 | ||
754 | int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer) | 766 | int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, |
767 | snd_timer_t **rtimer) | ||
755 | { | 768 | { |
756 | snd_timer_t *timer; | 769 | snd_timer_t *timer; |
757 | int err; | 770 | int err; |
@@ -779,9 +792,12 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t * | |||
779 | INIT_LIST_HEAD(&timer->ack_list_head); | 792 | INIT_LIST_HEAD(&timer->ack_list_head); |
780 | INIT_LIST_HEAD(&timer->sack_list_head); | 793 | INIT_LIST_HEAD(&timer->sack_list_head); |
781 | spin_lock_init(&timer->lock); | 794 | spin_lock_init(&timer->lock); |
782 | tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); | 795 | tasklet_init(&timer->task_queue, snd_timer_tasklet, |
796 | (unsigned long)timer); | ||
783 | if (card != NULL) { | 797 | if (card != NULL) { |
784 | if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) { | 798 | timer->module = card->module; |
799 | err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); | ||
800 | if (err < 0) { | ||
785 | snd_timer_free(timer); | 801 | snd_timer_free(timer); |
786 | return err; | 802 | return err; |
787 | } | 803 | } |
@@ -811,14 +827,15 @@ static int snd_timer_dev_register(snd_device_t *dev) | |||
811 | snd_timer_t *timer1; | 827 | snd_timer_t *timer1; |
812 | struct list_head *p; | 828 | struct list_head *p; |
813 | 829 | ||
814 | snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); | 830 | snd_assert(timer != NULL && timer->hw.start != NULL && |
831 | timer->hw.stop != NULL, return -ENXIO); | ||
815 | if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && | 832 | if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && |
816 | !timer->hw.resolution && timer->hw.c_resolution == NULL) | 833 | !timer->hw.resolution && timer->hw.c_resolution == NULL) |
817 | return -EINVAL; | 834 | return -EINVAL; |
818 | 835 | ||
819 | down(®ister_mutex); | 836 | down(®ister_mutex); |
820 | list_for_each(p, &snd_timer_list) { | 837 | list_for_each(p, &snd_timer_list) { |
821 | timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 838 | timer1 = list_entry(p, snd_timer_t, device_list); |
822 | if (timer1->tmr_class > timer->tmr_class) | 839 | if (timer1->tmr_class > timer->tmr_class) |
823 | break; | 840 | break; |
824 | if (timer1->tmr_class < timer->tmr_class) | 841 | if (timer1->tmr_class < timer->tmr_class) |
@@ -857,7 +874,7 @@ static int snd_timer_unregister(snd_timer_t *timer) | |||
857 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); | 874 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); |
858 | list_for_each_safe(p, n, &timer->open_list_head) { | 875 | list_for_each_safe(p, n, &timer->open_list_head) { |
859 | list_del_init(p); | 876 | list_del_init(p); |
860 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); | 877 | ti = list_entry(p, snd_timer_instance_t, open_list); |
861 | ti->timer = NULL; | 878 | ti->timer = NULL; |
862 | } | 879 | } |
863 | } | 880 | } |
@@ -872,15 +889,18 @@ static int snd_timer_dev_unregister(snd_device_t *device) | |||
872 | return snd_timer_unregister(timer); | 889 | return snd_timer_unregister(timer); |
873 | } | 890 | } |
874 | 891 | ||
875 | void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) | 892 | void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, |
893 | struct timespec *tstamp) | ||
876 | { | 894 | { |
877 | unsigned long flags; | 895 | unsigned long flags; |
878 | unsigned long resolution = 0; | 896 | unsigned long resolution = 0; |
879 | snd_timer_instance_t *ti, *ts; | 897 | snd_timer_instance_t *ti, *ts; |
880 | struct list_head *p, *n; | 898 | struct list_head *p, *n; |
881 | 899 | ||
882 | snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return); | 900 | if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) |
883 | snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); | 901 | return; |
902 | snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && | ||
903 | event <= SNDRV_TIMER_EVENT_MRESUME, return); | ||
884 | spin_lock_irqsave(&timer->lock, flags); | 904 | spin_lock_irqsave(&timer->lock, flags); |
885 | if (event == SNDRV_TIMER_EVENT_MSTART || | 905 | if (event == SNDRV_TIMER_EVENT_MSTART || |
886 | event == SNDRV_TIMER_EVENT_MCONTINUE || | 906 | event == SNDRV_TIMER_EVENT_MCONTINUE || |
@@ -891,11 +911,11 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t | |||
891 | resolution = timer->hw.resolution; | 911 | resolution = timer->hw.resolution; |
892 | } | 912 | } |
893 | list_for_each(p, &timer->active_list_head) { | 913 | list_for_each(p, &timer->active_list_head) { |
894 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); | 914 | ti = list_entry(p, snd_timer_instance_t, active_list); |
895 | if (ti->ccallback) | 915 | if (ti->ccallback) |
896 | ti->ccallback(ti, event, tstamp, resolution); | 916 | ti->ccallback(ti, event, tstamp, resolution); |
897 | list_for_each(n, &ti->slave_active_head) { | 917 | list_for_each(n, &ti->slave_active_head) { |
898 | ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list); | 918 | ts = list_entry(n, snd_timer_instance_t, active_list); |
899 | if (ts->ccallback) | 919 | if (ts->ccallback) |
900 | ts->ccallback(ts, event, tstamp, resolution); | 920 | ts->ccallback(ts, event, tstamp, resolution); |
901 | } | 921 | } |
@@ -909,7 +929,7 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t | |||
909 | int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer) | 929 | int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer) |
910 | { | 930 | { |
911 | snd_timer_id_t tid; | 931 | snd_timer_id_t tid; |
912 | 932 | ||
913 | tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; | 933 | tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; |
914 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; | 934 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; |
915 | tid.card = -1; | 935 | tid.card = -1; |
@@ -937,7 +957,7 @@ int snd_timer_global_unregister(snd_timer_t *timer) | |||
937 | return snd_timer_unregister(timer); | 957 | return snd_timer_unregister(timer); |
938 | } | 958 | } |
939 | 959 | ||
940 | /* | 960 | /* |
941 | * System timer | 961 | * System timer |
942 | */ | 962 | */ |
943 | 963 | ||
@@ -1013,7 +1033,8 @@ static int snd_timer_register_system(void) | |||
1013 | struct snd_timer_system_private *priv; | 1033 | struct snd_timer_system_private *priv; |
1014 | int err; | 1034 | int err; |
1015 | 1035 | ||
1016 | if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0) | 1036 | err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer); |
1037 | if (err < 0) | ||
1017 | return err; | 1038 | return err; |
1018 | strcpy(timer->name, "system timer"); | 1039 | strcpy(timer->name, "system timer"); |
1019 | timer->hw = snd_timer_system; | 1040 | timer->hw = snd_timer_system; |
@@ -1044,33 +1065,41 @@ static void snd_timer_proc_read(snd_info_entry_t *entry, | |||
1044 | 1065 | ||
1045 | down(®ister_mutex); | 1066 | down(®ister_mutex); |
1046 | list_for_each(p, &snd_timer_list) { | 1067 | list_for_each(p, &snd_timer_list) { |
1047 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1068 | timer = list_entry(p, snd_timer_t, device_list); |
1048 | switch (timer->tmr_class) { | 1069 | switch (timer->tmr_class) { |
1049 | case SNDRV_TIMER_CLASS_GLOBAL: | 1070 | case SNDRV_TIMER_CLASS_GLOBAL: |
1050 | snd_iprintf(buffer, "G%i: ", timer->tmr_device); | 1071 | snd_iprintf(buffer, "G%i: ", timer->tmr_device); |
1051 | break; | 1072 | break; |
1052 | case SNDRV_TIMER_CLASS_CARD: | 1073 | case SNDRV_TIMER_CLASS_CARD: |
1053 | snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); | 1074 | snd_iprintf(buffer, "C%i-%i: ", |
1075 | timer->card->number, timer->tmr_device); | ||
1054 | break; | 1076 | break; |
1055 | case SNDRV_TIMER_CLASS_PCM: | 1077 | case SNDRV_TIMER_CLASS_PCM: |
1056 | snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); | 1078 | snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, |
1079 | timer->tmr_device, timer->tmr_subdevice); | ||
1057 | break; | 1080 | break; |
1058 | default: | 1081 | default: |
1059 | snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); | 1082 | snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, |
1083 | timer->card ? timer->card->number : -1, | ||
1084 | timer->tmr_device, timer->tmr_subdevice); | ||
1060 | } | 1085 | } |
1061 | snd_iprintf(buffer, "%s :", timer->name); | 1086 | snd_iprintf(buffer, "%s :", timer->name); |
1062 | if (timer->hw.resolution) | 1087 | if (timer->hw.resolution) |
1063 | snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); | 1088 | snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", |
1089 | timer->hw.resolution / 1000, | ||
1090 | timer->hw.resolution % 1000, | ||
1091 | timer->hw.ticks); | ||
1064 | if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) | 1092 | if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) |
1065 | snd_iprintf(buffer, " SLAVE"); | 1093 | snd_iprintf(buffer, " SLAVE"); |
1066 | snd_iprintf(buffer, "\n"); | 1094 | snd_iprintf(buffer, "\n"); |
1067 | spin_lock_irqsave(&timer->lock, flags); | 1095 | spin_lock_irqsave(&timer->lock, flags); |
1068 | list_for_each(q, &timer->open_list_head) { | 1096 | list_for_each(q, &timer->open_list_head) { |
1069 | ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list); | 1097 | ti = list_entry(q, snd_timer_instance_t, open_list); |
1070 | snd_iprintf(buffer, " Client %s : %s : lost interrupts %li\n", | 1098 | snd_iprintf(buffer, " Client %s : %s\n", |
1071 | ti->owner ? ti->owner : "unknown", | 1099 | ti->owner ? ti->owner : "unknown", |
1072 | ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped", | 1100 | ti->flags & (SNDRV_TIMER_IFLG_START | |
1073 | ti->lost); | 1101 | SNDRV_TIMER_IFLG_RUNNING) |
1102 | ? "running" : "stopped"); | ||
1074 | } | 1103 | } |
1075 | spin_unlock_irqrestore(&timer->lock, flags); | 1104 | spin_unlock_irqrestore(&timer->lock, flags); |
1076 | } | 1105 | } |
@@ -1088,7 +1117,7 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, | |||
1088 | snd_timer_user_t *tu = timeri->callback_data; | 1117 | snd_timer_user_t *tu = timeri->callback_data; |
1089 | snd_timer_read_t *r; | 1118 | snd_timer_read_t *r; |
1090 | int prev; | 1119 | int prev; |
1091 | 1120 | ||
1092 | spin_lock(&tu->qlock); | 1121 | spin_lock(&tu->qlock); |
1093 | if (tu->qused > 0) { | 1122 | if (tu->qused > 0) { |
1094 | prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; | 1123 | prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; |
@@ -1113,7 +1142,8 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, | |||
1113 | wake_up(&tu->qchange_sleep); | 1142 | wake_up(&tu->qchange_sleep); |
1114 | } | 1143 | } |
1115 | 1144 | ||
1116 | static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) | 1145 | static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, |
1146 | snd_timer_tread_t *tread) | ||
1117 | { | 1147 | { |
1118 | if (tu->qused >= tu->queue_size) { | 1148 | if (tu->qused >= tu->queue_size) { |
1119 | tu->overrun++; | 1149 | tu->overrun++; |
@@ -1132,7 +1162,8 @@ static void snd_timer_user_ccallback(snd_timer_instance_t *timeri, | |||
1132 | snd_timer_user_t *tu = timeri->callback_data; | 1162 | snd_timer_user_t *tu = timeri->callback_data; |
1133 | snd_timer_tread_t r1; | 1163 | snd_timer_tread_t r1; |
1134 | 1164 | ||
1135 | if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) | 1165 | if (event >= SNDRV_TIMER_EVENT_START && |
1166 | event <= SNDRV_TIMER_EVENT_PAUSE) | ||
1136 | tu->tstamp = *tstamp; | 1167 | tu->tstamp = *tstamp; |
1137 | if ((tu->filter & (1 << event)) == 0 || !tu->tread) | 1168 | if ((tu->filter & (1 << event)) == 0 || !tu->tread) |
1138 | return; | 1169 | return; |
@@ -1155,15 +1186,17 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, | |||
1155 | struct timespec tstamp; | 1186 | struct timespec tstamp; |
1156 | int prev, append = 0; | 1187 | int prev, append = 0; |
1157 | 1188 | ||
1158 | snd_timestamp_zero(&tstamp); | 1189 | memset(&tstamp, 0, sizeof(tstamp)); |
1159 | spin_lock(&tu->qlock); | 1190 | spin_lock(&tu->qlock); |
1160 | if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) { | 1191 | if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | |
1192 | (1 << SNDRV_TIMER_EVENT_TICK))) == 0) { | ||
1161 | spin_unlock(&tu->qlock); | 1193 | spin_unlock(&tu->qlock); |
1162 | return; | 1194 | return; |
1163 | } | 1195 | } |
1164 | if (tu->last_resolution != resolution || ticks > 0) | 1196 | if (tu->last_resolution != resolution || ticks > 0) |
1165 | snd_timestamp_now(&tstamp, 1); | 1197 | getnstimeofday(&tstamp); |
1166 | if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { | 1198 | if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && |
1199 | tu->last_resolution != resolution) { | ||
1167 | r1.event = SNDRV_TIMER_EVENT_RESOLUTION; | 1200 | r1.event = SNDRV_TIMER_EVENT_RESOLUTION; |
1168 | r1.tstamp = tstamp; | 1201 | r1.tstamp = tstamp; |
1169 | r1.val = resolution; | 1202 | r1.val = resolution; |
@@ -1201,7 +1234,7 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, | |||
1201 | static int snd_timer_user_open(struct inode *inode, struct file *file) | 1234 | static int snd_timer_user_open(struct inode *inode, struct file *file) |
1202 | { | 1235 | { |
1203 | snd_timer_user_t *tu; | 1236 | snd_timer_user_t *tu; |
1204 | 1237 | ||
1205 | tu = kzalloc(sizeof(*tu), GFP_KERNEL); | 1238 | tu = kzalloc(sizeof(*tu), GFP_KERNEL); |
1206 | if (tu == NULL) | 1239 | if (tu == NULL) |
1207 | return -ENOMEM; | 1240 | return -ENOMEM; |
@@ -1210,7 +1243,8 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) | |||
1210 | init_MUTEX(&tu->tread_sem); | 1243 | init_MUTEX(&tu->tread_sem); |
1211 | tu->ticks = 1; | 1244 | tu->ticks = 1; |
1212 | tu->queue_size = 128; | 1245 | tu->queue_size = 128; |
1213 | tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); | 1246 | tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), |
1247 | GFP_KERNEL); | ||
1214 | if (tu->queue == NULL) { | 1248 | if (tu->queue == NULL) { |
1215 | kfree(tu); | 1249 | kfree(tu); |
1216 | return -ENOMEM; | 1250 | return -ENOMEM; |
@@ -1259,7 +1293,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1259 | snd_timer_id_t id; | 1293 | snd_timer_id_t id; |
1260 | snd_timer_t *timer; | 1294 | snd_timer_t *timer; |
1261 | struct list_head *p; | 1295 | struct list_head *p; |
1262 | 1296 | ||
1263 | if (copy_from_user(&id, _tid, sizeof(id))) | 1297 | if (copy_from_user(&id, _tid, sizeof(id))) |
1264 | return -EFAULT; | 1298 | return -EFAULT; |
1265 | down(®ister_mutex); | 1299 | down(®ister_mutex); |
@@ -1267,7 +1301,8 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1267 | if (list_empty(&snd_timer_list)) | 1301 | if (list_empty(&snd_timer_list)) |
1268 | snd_timer_user_zero_id(&id); | 1302 | snd_timer_user_zero_id(&id); |
1269 | else { | 1303 | else { |
1270 | timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list); | 1304 | timer = list_entry(snd_timer_list.next, |
1305 | snd_timer_t, device_list); | ||
1271 | snd_timer_user_copy_id(&id, timer); | 1306 | snd_timer_user_copy_id(&id, timer); |
1272 | } | 1307 | } |
1273 | } else { | 1308 | } else { |
@@ -1275,7 +1310,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1275 | case SNDRV_TIMER_CLASS_GLOBAL: | 1310 | case SNDRV_TIMER_CLASS_GLOBAL: |
1276 | id.device = id.device < 0 ? 0 : id.device + 1; | 1311 | id.device = id.device < 0 ? 0 : id.device + 1; |
1277 | list_for_each(p, &snd_timer_list) { | 1312 | list_for_each(p, &snd_timer_list) { |
1278 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1313 | timer = list_entry(p, snd_timer_t, device_list); |
1279 | if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { | 1314 | if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { |
1280 | snd_timer_user_copy_id(&id, timer); | 1315 | snd_timer_user_copy_id(&id, timer); |
1281 | break; | 1316 | break; |
@@ -1299,12 +1334,16 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1299 | if (id.device < 0) { | 1334 | if (id.device < 0) { |
1300 | id.device = 0; | 1335 | id.device = 0; |
1301 | } else { | 1336 | } else { |
1302 | id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1; | 1337 | if (id.subdevice < 0) { |
1338 | id.subdevice = 0; | ||
1339 | } else { | ||
1340 | id.subdevice++; | ||
1341 | } | ||
1303 | } | 1342 | } |
1304 | } | 1343 | } |
1305 | } | 1344 | } |
1306 | list_for_each(p, &snd_timer_list) { | 1345 | list_for_each(p, &snd_timer_list) { |
1307 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1346 | timer = list_entry(p, snd_timer_t, device_list); |
1308 | if (timer->tmr_class > id.dev_class) { | 1347 | if (timer->tmr_class > id.dev_class) { |
1309 | snd_timer_user_copy_id(&id, timer); | 1348 | snd_timer_user_copy_id(&id, timer); |
1310 | break; | 1349 | break; |
@@ -1343,9 +1382,10 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1343 | if (copy_to_user(_tid, &id, sizeof(*_tid))) | 1382 | if (copy_to_user(_tid, &id, sizeof(*_tid))) |
1344 | return -EFAULT; | 1383 | return -EFAULT; |
1345 | return 0; | 1384 | return 0; |
1346 | } | 1385 | } |
1347 | 1386 | ||
1348 | static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) | 1387 | static int snd_timer_user_ginfo(struct file *file, |
1388 | snd_timer_ginfo_t __user *_ginfo) | ||
1349 | { | 1389 | { |
1350 | snd_timer_ginfo_t *ginfo; | 1390 | snd_timer_ginfo_t *ginfo; |
1351 | snd_timer_id_t tid; | 1391 | snd_timer_id_t tid; |
@@ -1389,7 +1429,8 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_gi | |||
1389 | return err; | 1429 | return err; |
1390 | } | 1430 | } |
1391 | 1431 | ||
1392 | static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) | 1432 | static int snd_timer_user_gparams(struct file *file, |
1433 | snd_timer_gparams_t __user *_gparams) | ||
1393 | { | 1434 | { |
1394 | snd_timer_gparams_t gparams; | 1435 | snd_timer_gparams_t gparams; |
1395 | snd_timer_t *t; | 1436 | snd_timer_t *t; |
@@ -1399,23 +1440,26 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user | |||
1399 | return -EFAULT; | 1440 | return -EFAULT; |
1400 | down(®ister_mutex); | 1441 | down(®ister_mutex); |
1401 | t = snd_timer_find(&gparams.tid); | 1442 | t = snd_timer_find(&gparams.tid); |
1402 | if (t != NULL) { | 1443 | if (!t) { |
1403 | if (list_empty(&t->open_list_head)) { | ||
1404 | if (t->hw.set_period) | ||
1405 | err = t->hw.set_period(t, gparams.period_num, gparams.period_den); | ||
1406 | else | ||
1407 | err = -ENOSYS; | ||
1408 | } else { | ||
1409 | err = -EBUSY; | ||
1410 | } | ||
1411 | } else { | ||
1412 | err = -ENODEV; | 1444 | err = -ENODEV; |
1445 | goto _error; | ||
1446 | } | ||
1447 | if (!list_empty(&t->open_list_head)) { | ||
1448 | err = -EBUSY; | ||
1449 | goto _error; | ||
1413 | } | 1450 | } |
1451 | if (!t->hw.set_period) { | ||
1452 | err = -ENOSYS; | ||
1453 | goto _error; | ||
1454 | } | ||
1455 | err = t->hw.set_period(t, gparams.period_num, gparams.period_den); | ||
1456 | _error: | ||
1414 | up(®ister_mutex); | 1457 | up(®ister_mutex); |
1415 | return err; | 1458 | return err; |
1416 | } | 1459 | } |
1417 | 1460 | ||
1418 | static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) | 1461 | static int snd_timer_user_gstatus(struct file *file, |
1462 | snd_timer_gstatus_t __user *_gstatus) | ||
1419 | { | 1463 | { |
1420 | snd_timer_gstatus_t gstatus; | 1464 | snd_timer_gstatus_t gstatus; |
1421 | snd_timer_id_t tid; | 1465 | snd_timer_id_t tid; |
@@ -1435,7 +1479,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user | |||
1435 | else | 1479 | else |
1436 | gstatus.resolution = t->hw.resolution; | 1480 | gstatus.resolution = t->hw.resolution; |
1437 | if (t->hw.precise_resolution) { | 1481 | if (t->hw.precise_resolution) { |
1438 | t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); | 1482 | t->hw.precise_resolution(t, &gstatus.resolution_num, |
1483 | &gstatus.resolution_den); | ||
1439 | } else { | 1484 | } else { |
1440 | gstatus.resolution_num = gstatus.resolution; | 1485 | gstatus.resolution_num = gstatus.resolution; |
1441 | gstatus.resolution_den = 1000000000uL; | 1486 | gstatus.resolution_den = 1000000000uL; |
@@ -1449,13 +1494,14 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user | |||
1449 | return err; | 1494 | return err; |
1450 | } | 1495 | } |
1451 | 1496 | ||
1452 | static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) | 1497 | static int snd_timer_user_tselect(struct file *file, |
1498 | snd_timer_select_t __user *_tselect) | ||
1453 | { | 1499 | { |
1454 | snd_timer_user_t *tu; | 1500 | snd_timer_user_t *tu; |
1455 | snd_timer_select_t tselect; | 1501 | snd_timer_select_t tselect; |
1456 | char str[32]; | 1502 | char str[32]; |
1457 | int err = 0; | 1503 | int err = 0; |
1458 | 1504 | ||
1459 | tu = file->private_data; | 1505 | tu = file->private_data; |
1460 | down(&tu->tread_sem); | 1506 | down(&tu->tread_sem); |
1461 | if (tu->timeri) { | 1507 | if (tu->timeri) { |
@@ -1469,7 +1515,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * | |||
1469 | sprintf(str, "application %i", current->pid); | 1515 | sprintf(str, "application %i", current->pid); |
1470 | if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) | 1516 | if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) |
1471 | tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; | 1517 | tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; |
1472 | if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) | 1518 | err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid); |
1519 | if (err < 0) | ||
1473 | goto __err; | 1520 | goto __err; |
1474 | 1521 | ||
1475 | kfree(tu->queue); | 1522 | kfree(tu->queue); |
@@ -1477,21 +1524,24 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * | |||
1477 | kfree(tu->tqueue); | 1524 | kfree(tu->tqueue); |
1478 | tu->tqueue = NULL; | 1525 | tu->tqueue = NULL; |
1479 | if (tu->tread) { | 1526 | if (tu->tread) { |
1480 | tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); | 1527 | tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), |
1528 | GFP_KERNEL); | ||
1481 | if (tu->tqueue == NULL) | 1529 | if (tu->tqueue == NULL) |
1482 | err = -ENOMEM; | 1530 | err = -ENOMEM; |
1483 | } else { | 1531 | } else { |
1484 | tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); | 1532 | tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), |
1533 | GFP_KERNEL); | ||
1485 | if (tu->queue == NULL) | 1534 | if (tu->queue == NULL) |
1486 | err = -ENOMEM; | 1535 | err = -ENOMEM; |
1487 | } | 1536 | } |
1488 | 1537 | ||
1489 | if (err < 0) { | 1538 | if (err < 0) { |
1490 | snd_timer_close(tu->timeri); | 1539 | snd_timer_close(tu->timeri); |
1491 | tu->timeri = NULL; | 1540 | tu->timeri = NULL; |
1492 | } else { | 1541 | } else { |
1493 | tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; | 1542 | tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; |
1494 | tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; | 1543 | tu->timeri->callback = tu->tread |
1544 | ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; | ||
1495 | tu->timeri->ccallback = snd_timer_user_ccallback; | 1545 | tu->timeri->ccallback = snd_timer_user_ccallback; |
1496 | tu->timeri->callback_data = (void *)tu; | 1546 | tu->timeri->callback_data = (void *)tu; |
1497 | } | 1547 | } |
@@ -1501,7 +1551,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * | |||
1501 | return err; | 1551 | return err; |
1502 | } | 1552 | } |
1503 | 1553 | ||
1504 | static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) | 1554 | static int snd_timer_user_info(struct file *file, |
1555 | snd_timer_info_t __user *_info) | ||
1505 | { | 1556 | { |
1506 | snd_timer_user_t *tu; | 1557 | snd_timer_user_t *tu; |
1507 | snd_timer_info_t *info; | 1558 | snd_timer_info_t *info; |
@@ -1528,7 +1579,8 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info | |||
1528 | return err; | 1579 | return err; |
1529 | } | 1580 | } |
1530 | 1581 | ||
1531 | static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) | 1582 | static int snd_timer_user_params(struct file *file, |
1583 | snd_timer_params_t __user *_params) | ||
1532 | { | 1584 | { |
1533 | snd_timer_user_t *tu; | 1585 | snd_timer_user_t *tu; |
1534 | snd_timer_params_t params; | 1586 | snd_timer_params_t params; |
@@ -1536,7 +1588,7 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1536 | snd_timer_read_t *tr; | 1588 | snd_timer_read_t *tr; |
1537 | snd_timer_tread_t *ttr; | 1589 | snd_timer_tread_t *ttr; |
1538 | int err; | 1590 | int err; |
1539 | 1591 | ||
1540 | tu = file->private_data; | 1592 | tu = file->private_data; |
1541 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1593 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1542 | t = tu->timeri->timer; | 1594 | t = tu->timeri->timer; |
@@ -1547,7 +1599,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1547 | err = -EINVAL; | 1599 | err = -EINVAL; |
1548 | goto _end; | 1600 | goto _end; |
1549 | } | 1601 | } |
1550 | if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { | 1602 | if (params.queue_size > 0 && |
1603 | (params.queue_size < 32 || params.queue_size > 1024)) { | ||
1551 | err = -EINVAL; | 1604 | err = -EINVAL; |
1552 | goto _end; | 1605 | goto _end; |
1553 | } | 1606 | } |
@@ -1580,16 +1633,19 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1580 | if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) | 1633 | if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) |
1581 | tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; | 1634 | tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; |
1582 | spin_unlock_irq(&t->lock); | 1635 | spin_unlock_irq(&t->lock); |
1583 | if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { | 1636 | if (params.queue_size > 0 && |
1637 | (unsigned int)tu->queue_size != params.queue_size) { | ||
1584 | if (tu->tread) { | 1638 | if (tu->tread) { |
1585 | ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); | 1639 | ttr = kmalloc(params.queue_size * sizeof(*ttr), |
1640 | GFP_KERNEL); | ||
1586 | if (ttr) { | 1641 | if (ttr) { |
1587 | kfree(tu->tqueue); | 1642 | kfree(tu->tqueue); |
1588 | tu->queue_size = params.queue_size; | 1643 | tu->queue_size = params.queue_size; |
1589 | tu->tqueue = ttr; | 1644 | tu->tqueue = ttr; |
1590 | } | 1645 | } |
1591 | } else { | 1646 | } else { |
1592 | tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); | 1647 | tr = kmalloc(params.queue_size * sizeof(*tr), |
1648 | GFP_KERNEL); | ||
1593 | if (tr) { | 1649 | if (tr) { |
1594 | kfree(tu->queue); | 1650 | kfree(tu->queue); |
1595 | tu->queue_size = params.queue_size; | 1651 | tu->queue_size = params.queue_size; |
@@ -1613,7 +1669,6 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1613 | tu->qused++; | 1669 | tu->qused++; |
1614 | tu->qtail++; | 1670 | tu->qtail++; |
1615 | } | 1671 | } |
1616 | |||
1617 | } | 1672 | } |
1618 | tu->filter = params.filter; | 1673 | tu->filter = params.filter; |
1619 | tu->ticks = params.ticks; | 1674 | tu->ticks = params.ticks; |
@@ -1624,11 +1679,12 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1624 | return err; | 1679 | return err; |
1625 | } | 1680 | } |
1626 | 1681 | ||
1627 | static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) | 1682 | static int snd_timer_user_status(struct file *file, |
1683 | snd_timer_status_t __user *_status) | ||
1628 | { | 1684 | { |
1629 | snd_timer_user_t *tu; | 1685 | snd_timer_user_t *tu; |
1630 | snd_timer_status_t status; | 1686 | snd_timer_status_t status; |
1631 | 1687 | ||
1632 | tu = file->private_data; | 1688 | tu = file->private_data; |
1633 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1689 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1634 | memset(&status, 0, sizeof(status)); | 1690 | memset(&status, 0, sizeof(status)); |
@@ -1648,7 +1704,7 @@ static int snd_timer_user_start(struct file *file) | |||
1648 | { | 1704 | { |
1649 | int err; | 1705 | int err; |
1650 | snd_timer_user_t *tu; | 1706 | snd_timer_user_t *tu; |
1651 | 1707 | ||
1652 | tu = file->private_data; | 1708 | tu = file->private_data; |
1653 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1709 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1654 | snd_timer_stop(tu->timeri); | 1710 | snd_timer_stop(tu->timeri); |
@@ -1661,7 +1717,7 @@ static int snd_timer_user_stop(struct file *file) | |||
1661 | { | 1717 | { |
1662 | int err; | 1718 | int err; |
1663 | snd_timer_user_t *tu; | 1719 | snd_timer_user_t *tu; |
1664 | 1720 | ||
1665 | tu = file->private_data; | 1721 | tu = file->private_data; |
1666 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1722 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1667 | return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; | 1723 | return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; |
@@ -1671,7 +1727,7 @@ static int snd_timer_user_continue(struct file *file) | |||
1671 | { | 1727 | { |
1672 | int err; | 1728 | int err; |
1673 | snd_timer_user_t *tu; | 1729 | snd_timer_user_t *tu; |
1674 | 1730 | ||
1675 | tu = file->private_data; | 1731 | tu = file->private_data; |
1676 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1732 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1677 | tu->timeri->lost = 0; | 1733 | tu->timeri->lost = 0; |
@@ -1682,7 +1738,7 @@ static int snd_timer_user_pause(struct file *file) | |||
1682 | { | 1738 | { |
1683 | int err; | 1739 | int err; |
1684 | snd_timer_user_t *tu; | 1740 | snd_timer_user_t *tu; |
1685 | 1741 | ||
1686 | tu = file->private_data; | 1742 | tu = file->private_data; |
1687 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1743 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1688 | return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; | 1744 | return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; |
@@ -1695,12 +1751,13 @@ enum { | |||
1695 | SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), | 1751 | SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), |
1696 | }; | 1752 | }; |
1697 | 1753 | ||
1698 | static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1754 | static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, |
1755 | unsigned long arg) | ||
1699 | { | 1756 | { |
1700 | snd_timer_user_t *tu; | 1757 | snd_timer_user_t *tu; |
1701 | void __user *argp = (void __user *)arg; | 1758 | void __user *argp = (void __user *)arg; |
1702 | int __user *p = argp; | 1759 | int __user *p = argp; |
1703 | 1760 | ||
1704 | tu = file->private_data; | 1761 | tu = file->private_data; |
1705 | switch (cmd) { | 1762 | switch (cmd) { |
1706 | case SNDRV_TIMER_IOCTL_PVERSION: | 1763 | case SNDRV_TIMER_IOCTL_PVERSION: |
@@ -1710,7 +1767,7 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l | |||
1710 | case SNDRV_TIMER_IOCTL_TREAD: | 1767 | case SNDRV_TIMER_IOCTL_TREAD: |
1711 | { | 1768 | { |
1712 | int xarg; | 1769 | int xarg; |
1713 | 1770 | ||
1714 | down(&tu->tread_sem); | 1771 | down(&tu->tread_sem); |
1715 | if (tu->timeri) { /* too late */ | 1772 | if (tu->timeri) { /* too late */ |
1716 | up(&tu->tread_sem); | 1773 | up(&tu->tread_sem); |
@@ -1758,7 +1815,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) | |||
1758 | { | 1815 | { |
1759 | snd_timer_user_t *tu; | 1816 | snd_timer_user_t *tu; |
1760 | int err; | 1817 | int err; |
1761 | 1818 | ||
1762 | tu = file->private_data; | 1819 | tu = file->private_data; |
1763 | err = fasync_helper(fd, file, on, &tu->fasync); | 1820 | err = fasync_helper(fd, file, on, &tu->fasync); |
1764 | if (err < 0) | 1821 | if (err < 0) |
@@ -1766,12 +1823,13 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) | |||
1766 | return 0; | 1823 | return 0; |
1767 | } | 1824 | } |
1768 | 1825 | ||
1769 | static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) | 1826 | static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, |
1827 | size_t count, loff_t *offset) | ||
1770 | { | 1828 | { |
1771 | snd_timer_user_t *tu; | 1829 | snd_timer_user_t *tu; |
1772 | long result = 0, unit; | 1830 | long result = 0, unit; |
1773 | int err = 0; | 1831 | int err = 0; |
1774 | 1832 | ||
1775 | tu = file->private_data; | 1833 | tu = file->private_data; |
1776 | unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t); | 1834 | unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t); |
1777 | spin_lock_irq(&tu->qlock); | 1835 | spin_lock_irq(&tu->qlock); |
@@ -1805,12 +1863,14 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_ | |||
1805 | goto _error; | 1863 | goto _error; |
1806 | 1864 | ||
1807 | if (tu->tread) { | 1865 | if (tu->tread) { |
1808 | if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { | 1866 | if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], |
1867 | sizeof(snd_timer_tread_t))) { | ||
1809 | err = -EFAULT; | 1868 | err = -EFAULT; |
1810 | goto _error; | 1869 | goto _error; |
1811 | } | 1870 | } |
1812 | } else { | 1871 | } else { |
1813 | if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { | 1872 | if (copy_to_user(buffer, &tu->queue[tu->qhead++], |
1873 | sizeof(snd_timer_read_t))) { | ||
1814 | err = -EFAULT; | 1874 | err = -EFAULT; |
1815 | goto _error; | 1875 | goto _error; |
1816 | } | 1876 | } |
@@ -1837,7 +1897,7 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait) | |||
1837 | tu = file->private_data; | 1897 | tu = file->private_data; |
1838 | 1898 | ||
1839 | poll_wait(file, &tu->qchange_sleep, wait); | 1899 | poll_wait(file, &tu->qchange_sleep, wait); |
1840 | 1900 | ||
1841 | mask = 0; | 1901 | mask = 0; |
1842 | if (tu->qused) | 1902 | if (tu->qused) |
1843 | mask |= POLLIN | POLLRDNORM; | 1903 | mask |= POLLIN | POLLRDNORM; |
@@ -1881,9 +1941,11 @@ static int __init alsa_timer_init(void) | |||
1881 | snd_info_entry_t *entry; | 1941 | snd_info_entry_t *entry; |
1882 | 1942 | ||
1883 | #ifdef SNDRV_OSS_INFO_DEV_TIMERS | 1943 | #ifdef SNDRV_OSS_INFO_DEV_TIMERS |
1884 | snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); | 1944 | snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, |
1945 | "system timer"); | ||
1885 | #endif | 1946 | #endif |
1886 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) { | 1947 | entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); |
1948 | if (entry != NULL) { | ||
1887 | entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; | 1949 | entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; |
1888 | entry->c.text.read = snd_timer_proc_read; | 1950 | entry->c.text.read = snd_timer_proc_read; |
1889 | if (snd_info_register(entry) < 0) { | 1951 | if (snd_info_register(entry) < 0) { |
@@ -1893,10 +1955,12 @@ static int __init alsa_timer_init(void) | |||
1893 | } | 1955 | } |
1894 | snd_timer_proc_entry = entry; | 1956 | snd_timer_proc_entry = entry; |
1895 | if ((err = snd_timer_register_system()) < 0) | 1957 | if ((err = snd_timer_register_system()) < 0) |
1896 | snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); | 1958 | snd_printk(KERN_ERR "unable to register system timer (%i)\n", |
1959 | err); | ||
1897 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, | 1960 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, |
1898 | NULL, 0, &snd_timer_reg, "timer"))<0) | 1961 | NULL, 0, &snd_timer_reg, "timer"))<0) |
1899 | snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); | 1962 | snd_printk(KERN_ERR "unable to register timer device (%i)\n", |
1963 | err); | ||
1900 | return 0; | 1964 | return 0; |
1901 | } | 1965 | } |
1902 | 1966 | ||
@@ -1907,7 +1971,7 @@ static void __exit alsa_timer_exit(void) | |||
1907 | snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0); | 1971 | snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0); |
1908 | /* unregister the system timer */ | 1972 | /* unregister the system timer */ |
1909 | list_for_each_safe(p, n, &snd_timer_list) { | 1973 | list_for_each_safe(p, n, &snd_timer_list) { |
1910 | snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1974 | snd_timer_t *timer = list_entry(p, snd_timer_t, device_list); |
1911 | snd_timer_unregister(timer); | 1975 | snd_timer_unregister(timer); |
1912 | } | 1976 | } |
1913 | if (snd_timer_proc_entry) { | 1977 | if (snd_timer_proc_entry) { |
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c deleted file mode 100644 index 296b716f1376..000000000000 --- a/sound/core/wrappers.c +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | * Various wrappers | ||
3 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | ||
4 | * | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/config.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/vmalloc.h> | ||
27 | #include <linux/fs.h> | ||
28 | |||
29 | #ifdef CONFIG_SND_DEBUG_MEMORY | ||
30 | void *snd_wrapper_kmalloc(size_t size, gfp_t flags) | ||
31 | { | ||
32 | return kmalloc(size, flags); | ||
33 | } | ||
34 | |||
35 | void snd_wrapper_kfree(const void *obj) | ||
36 | { | ||
37 | kfree(obj); | ||
38 | } | ||
39 | |||
40 | void *snd_wrapper_vmalloc(unsigned long size) | ||
41 | { | ||
42 | return vmalloc(size); | ||
43 | } | ||
44 | |||
45 | void snd_wrapper_vfree(void *obj) | ||
46 | { | ||
47 | vfree(obj); | ||
48 | } | ||
49 | #endif | ||
50 | |||