aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c52
-rw-r--r--sound/core/control_compat.c3
-rw-r--r--sound/core/device.c1
-rw-r--r--sound/core/hwdep.c1
-rw-r--r--sound/core/info.c1
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/init.c39
-rw-r--r--sound/core/isadma.c1
-rw-r--r--sound/core/memalloc.c1
-rw-r--r--sound/core/memory.c2
-rw-r--r--sound/core/misc.c1
-rw-r--r--sound/core/oss/copy.c1
-rw-r--r--sound/core/oss/io.c1
-rw-r--r--sound/core/oss/linear.c1
-rw-r--r--sound/core/oss/mixer_oss.c1
-rw-r--r--sound/core/oss/mulaw.c1
-rw-r--r--sound/core/oss/pcm_oss.c4
-rw-r--r--sound/core/oss/pcm_plugin.c1
-rw-r--r--sound/core/oss/rate.c1
-rw-r--r--sound/core/oss/route.c1
-rw-r--r--sound/core/pcm.c15
-rw-r--r--sound/core/pcm_compat.c1
-rw-r--r--sound/core/pcm_lib.c339
-rw-r--r--sound/core/pcm_memory.c1
-rw-r--r--sound/core/pcm_misc.c3
-rw-r--r--sound/core/pcm_native.c141
-rw-r--r--sound/core/pcm_timer.c1
-rw-r--r--sound/core/rawmidi.c41
-rw-r--r--sound/core/rtctimer.c1
-rw-r--r--sound/core/seq/Makefile8
-rw-r--r--sound/core/seq/instr/Makefile23
-rw-r--r--sound/core/seq/instr/ainstr_fm.c155
-rw-r--r--sound/core/seq/instr/ainstr_gf1.c359
-rw-r--r--sound/core/seq/instr/ainstr_iw.c623
-rw-r--r--sound/core/seq/instr/ainstr_simple.c215
-rw-r--r--sound/core/seq/oss/seq_oss.c1
-rw-r--r--sound/core/seq/oss/seq_oss_device.h1
-rw-r--r--sound/core/seq/seq.c1
-rw-r--r--sound/core/seq/seq_clientmgr.c6
-rw-r--r--sound/core/seq/seq_clientmgr.h2
-rw-r--r--sound/core/seq/seq_device.c1
-rw-r--r--sound/core/seq/seq_dummy.c1
-rw-r--r--sound/core/seq/seq_fifo.c1
-rw-r--r--sound/core/seq/seq_info.c1
-rw-r--r--sound/core/seq/seq_instr.c655
-rw-r--r--sound/core/seq/seq_lock.c1
-rw-r--r--sound/core/seq/seq_memory.c1
-rw-r--r--sound/core/seq/seq_midi.c1
-rw-r--r--sound/core/seq/seq_midi_emul.c8
-rw-r--r--sound/core/seq/seq_midi_event.c1
-rw-r--r--sound/core/seq/seq_ports.c1
-rw-r--r--sound/core/seq/seq_prioq.c1
-rw-r--r--sound/core/seq/seq_queue.c1
-rw-r--r--sound/core/seq/seq_system.c1
-rw-r--r--sound/core/seq/seq_timer.c8
-rw-r--r--sound/core/seq/seq_timer.h7
-rw-r--r--sound/core/seq/seq_virmidi.c1
-rw-r--r--sound/core/sound.c1
-rw-r--r--sound/core/sound_oss.c2
-rw-r--r--sound/core/timer.c17
60 files changed, 246 insertions, 2519 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index df0774c76f6f..01a1a5af47bb 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/threads.h> 22#include <linux/threads.h>
24#include <linux/interrupt.h> 23#include <linux/interrupt.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
@@ -232,8 +231,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
232 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 231 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
233 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 232 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
234 SNDRV_CTL_ELEM_ACCESS_INACTIVE| 233 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
235 SNDRV_CTL_ELEM_ACCESS_DINDIRECT|
236 SNDRV_CTL_ELEM_ACCESS_INDIRECT|
237 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE| 234 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
238 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)); 235 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
239 kctl.info = ncontrol->info; 236 kctl.info = ncontrol->info;
@@ -692,7 +689,7 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
692 struct snd_kcontrol *kctl; 689 struct snd_kcontrol *kctl;
693 struct snd_kcontrol_volatile *vd; 690 struct snd_kcontrol_volatile *vd;
694 unsigned int index_offset; 691 unsigned int index_offset;
695 int result, indirect; 692 int result;
696 693
697 down_read(&card->controls_rwsem); 694 down_read(&card->controls_rwsem);
698 kctl = snd_ctl_find_id(card, &control->id); 695 kctl = snd_ctl_find_id(card, &control->id);
@@ -701,17 +698,12 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
701 } else { 698 } else {
702 index_offset = snd_ctl_get_ioff(kctl, &control->id); 699 index_offset = snd_ctl_get_ioff(kctl, &control->id);
703 vd = &kctl->vd[index_offset]; 700 vd = &kctl->vd[index_offset];
704 indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0; 701 if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
705 if (control->indirect != indirect) { 702 kctl->get != NULL) {
706 result = -EACCES; 703 snd_ctl_build_ioff(&control->id, kctl, index_offset);
707 } else { 704 result = kctl->get(kctl, control);
708 if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) { 705 } else
709 snd_ctl_build_ioff(&control->id, kctl, index_offset); 706 result = -EPERM;
710 result = kctl->get(kctl, control);
711 } else {
712 result = -EPERM;
713 }
714 }
715 } 707 }
716 up_read(&card->controls_rwsem); 708 up_read(&card->controls_rwsem);
717 return result; 709 return result;
@@ -748,7 +740,7 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
748 struct snd_kcontrol *kctl; 740 struct snd_kcontrol *kctl;
749 struct snd_kcontrol_volatile *vd; 741 struct snd_kcontrol_volatile *vd;
750 unsigned int index_offset; 742 unsigned int index_offset;
751 int result, indirect; 743 int result;
752 744
753 down_read(&card->controls_rwsem); 745 down_read(&card->controls_rwsem);
754 kctl = snd_ctl_find_id(card, &control->id); 746 kctl = snd_ctl_find_id(card, &control->id);
@@ -757,23 +749,19 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
757 } else { 749 } else {
758 index_offset = snd_ctl_get_ioff(kctl, &control->id); 750 index_offset = snd_ctl_get_ioff(kctl, &control->id);
759 vd = &kctl->vd[index_offset]; 751 vd = &kctl->vd[index_offset];
760 indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0; 752 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
761 if (control->indirect != indirect) { 753 kctl->put == NULL ||
762 result = -EACCES; 754 (file && vd->owner && vd->owner != file)) {
755 result = -EPERM;
763 } else { 756 } else {
764 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || 757 snd_ctl_build_ioff(&control->id, kctl, index_offset);
765 kctl->put == NULL || 758 result = kctl->put(kctl, control);
766 (file && vd->owner != NULL && vd->owner != file)) { 759 }
767 result = -EPERM; 760 if (result > 0) {
768 } else { 761 up_read(&card->controls_rwsem);
769 snd_ctl_build_ioff(&control->id, kctl, index_offset); 762 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
770 result = kctl->put(kctl, control); 763 &control->id);
771 } 764 return 0;
772 if (result > 0) {
773 up_read(&card->controls_rwsem);
774 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id);
775 return 0;
776 }
777 } 765 }
778 } 766 }
779 up_read(&card->controls_rwsem); 767 up_read(&card->controls_rwsem);
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 9311ca397bbc..6101259ad860 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -219,7 +219,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
219 struct snd_ctl_elem_value32 __user *data32, 219 struct snd_ctl_elem_value32 __user *data32,
220 int *typep, int *countp) 220 int *typep, int *countp)
221{ 221{
222 int i, type, count, size; 222 int i, type, size;
223 int uninitialized_var(count);
223 unsigned int indirect; 224 unsigned int indirect;
224 225
225 if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) 226 if (copy_from_user(&data->id, &data32->id, sizeof(data->id)))
diff --git a/sound/core/device.c b/sound/core/device.c
index ea1a0621eefb..202dac0e4d89 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index bfd9d182b8a3..6d6589f93899 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/major.h> 22#include <linux/major.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
diff --git a/sound/core/info.c b/sound/core/info.c
index 1ffd29bb4cd0..9977ec2eace3 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index 435c9399f7a9..e35789a92752 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <linux/string.h> 24#include <linux/string.h>
@@ -66,8 +65,6 @@ int snd_oss_info_register(int dev, int num, char *string)
66 65
67EXPORT_SYMBOL(snd_oss_info_register); 66EXPORT_SYMBOL(snd_oss_info_register);
68 67
69extern void snd_card_info_read_oss(struct snd_info_buffer *buffer);
70
71static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) 68static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev)
72{ 69{
73 int idx, ok = -1; 70 int idx, ok = -1;
diff --git a/sound/core/init.c b/sound/core/init.c
index 2cb7099eb1e1..e3338d6071ef 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/sched.h> 23#include <linux/sched.h>
25#include <linux/file.h> 24#include <linux/file.h>
@@ -43,6 +42,40 @@ EXPORT_SYMBOL(snd_cards);
43 42
44static DEFINE_MUTEX(snd_card_mutex); 43static DEFINE_MUTEX(snd_card_mutex);
45 44
45static char *slots[SNDRV_CARDS];
46module_param_array(slots, charp, NULL, 0444);
47MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
48
49/* return non-zero if the given index is already reserved for another
50 * module via slots option
51 */
52static int module_slot_mismatch(struct module *module, int idx)
53{
54#ifdef MODULE
55 char *s1, *s2;
56 if (!module || !module->name || !slots[idx])
57 return 0;
58 s1 = slots[idx];
59 s2 = module->name;
60 /* compare module name strings
61 * hyphens are handled as equivalent with underscore
62 */
63 for (;;) {
64 char c1 = *s1++;
65 char c2 = *s2++;
66 if (c1 == '-')
67 c1 = '_';
68 if (c2 == '-')
69 c2 = '_';
70 if (c1 != c2)
71 return 1;
72 if (!c1)
73 break;
74 }
75#endif
76 return 0;
77}
78
46#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 79#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
47int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); 80int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
48EXPORT_SYMBOL(snd_mixer_oss_notify_callback); 81EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
@@ -115,6 +148,8 @@ struct snd_card *snd_card_new(int idx, const char *xid,
115 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 148 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
116 /* idx == -1 == 0xffff means: take any free slot */ 149 /* idx == -1 == 0xffff means: take any free slot */
117 if (~snd_cards_lock & idx & 1<<idx2) { 150 if (~snd_cards_lock & idx & 1<<idx2) {
151 if (module_slot_mismatch(module, idx2))
152 continue;
118 idx = idx2; 153 idx = idx2;
119 if (idx >= snd_ecards_limit) 154 if (idx >= snd_ecards_limit)
120 snd_ecards_limit = idx + 1; 155 snd_ecards_limit = idx + 1;
@@ -304,8 +339,8 @@ int snd_card_disconnect(struct snd_card *card)
304 list_add(&mfile->shutdown_list, &shutdown_files); 339 list_add(&mfile->shutdown_list, &shutdown_files);
305 spin_unlock(&shutdown_lock); 340 spin_unlock(&shutdown_lock);
306 341
307 fops_get(&snd_shutdown_f_ops);
308 mfile->file->f_op = &snd_shutdown_f_ops; 342 mfile->file->f_op = &snd_shutdown_f_ops;
343 fops_get(mfile->file->f_op);
309 344
310 mfile = mfile->next; 345 mfile = mfile->next;
311 } 346 }
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index eb173cef4f05..79f0f16af339 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -26,7 +26,6 @@
26 26
27#undef HAVE_REALLY_SLOW_DMA_CONTROLLER 27#undef HAVE_REALLY_SLOW_DMA_CONTROLLER
28 28
29#include <sound/driver.h>
30#include <sound/core.h> 29#include <sound/core.h>
31#include <asm/dma.h> 30#include <asm/dma.h>
32 31
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 9b4992eab479..920e5780c228 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -568,6 +568,7 @@ static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer,
568 if (pci_set_dma_mask(pci, mask) < 0 || 568 if (pci_set_dma_mask(pci, mask) < 0 ||
569 pci_set_consistent_dma_mask(pci, mask) < 0) { 569 pci_set_consistent_dma_mask(pci, mask) < 0) {
570 printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device); 570 printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device);
571 pci_dev_put(pci);
571 return count; 572 return count;
572 } 573 }
573 } 574 }
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 25b0f056563e..1161158582a6 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -20,9 +20,9 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/module.h>
24#include <asm/io.h> 23#include <asm/io.h>
25#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <sound/core.h>
26 26
27/** 27/**
28 * 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 6cabab8cc537..102d1c36cf26 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <linux/ioport.h> 24#include <linux/ioport.h>
diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c
index d6a04c2d5a75..9ded30d0e97d 100644
--- a/sound/core/oss/copy.c
+++ b/sound/core/oss/copy.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c
index 3ece39fc48db..f874f6ca3657 100644
--- a/sound/core/oss/io.c
+++ b/sound/core/oss/io.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index 06f96a3e86f6..da3dbd41669e 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <sound/core.h> 24#include <sound/core.h>
26#include <sound/pcm.h> 25#include <sound/pcm.h>
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index c5a5ab9cae8c..75daed298a15 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/time.h> 24#include <linux/time.h>
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
index 848db82529ed..77f96194a0ed 100644
--- a/sound/core/oss/mulaw.c
+++ b/sound/core/oss/mulaw.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <linux/time.h> 24#include <linux/time.h>
26#include <sound/core.h> 25#include <sound/core.h>
27#include <sound/pcm.h> 26#include <sound/pcm.h>
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d0c4ceb9f0b4..4c601b192ddf 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -26,7 +26,6 @@
26#define OSS_DEBUG 26#define OSS_DEBUG
27#endif 27#endif
28 28
29#include <sound/driver.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/time.h> 31#include <linux/time.h>
@@ -985,10 +984,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
985 sw_params->stop_threshold = runtime->buffer_size; 984 sw_params->stop_threshold = runtime->buffer_size;
986 sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; 985 sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
987 sw_params->period_step = 1; 986 sw_params->period_step = 1;
988 sw_params->sleep_min = 0;
989 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 987 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
990 1 : runtime->period_size; 988 1 : runtime->period_size;
991 sw_params->xfer_align = 1;
992 if (atomic_read(&substream->mmap_count) || 989 if (atomic_read(&substream->mmap_count) ||
993 substream->oss.setup.nosilence) { 990 substream->oss.setup.nosilence) {
994 sw_params->silence_threshold = 0; 991 sw_params->silence_threshold = 0;
@@ -1624,6 +1621,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1624 snd_pcm_format_set_silence(runtime->format, 1621 snd_pcm_format_set_silence(runtime->format,
1625 runtime->oss.buffer, 1622 runtime->oss.buffer,
1626 size1); 1623 size1);
1624 size1 /= runtime->channels; /* frames */
1627 fs = snd_enter_user(); 1625 fs = snd_enter_user();
1628 snd_pcm_lib_write(substream, (void __user *)runtime->oss.buffer, size1); 1626 snd_pcm_lib_write(substream, (void __user *)runtime->oss.buffer, size1);
1629 snd_leave_user(fs); 1627 snd_leave_user(fs);
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 14095a927a1b..bec94138205e 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -24,7 +24,6 @@
24#define PLUGIN_DEBUG 24#define PLUGIN_DEBUG
25#endif 25#endif
26 26
27#include <sound/driver.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <linux/time.h> 28#include <linux/time.h>
30#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c
index 9eb267913c38..14dfb3175d84 100644
--- a/sound/core/oss/rate.c
+++ b/sound/core/oss/rate.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index de3ffdeaf7e3..da7ab7a3e82c 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <sound/core.h> 24#include <sound/core.h>
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index cf9b9493d41d..9dd9bc73fe1d 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/time.h> 24#include <linux/time.h>
@@ -228,7 +227,7 @@ static char *snd_pcm_subformat_names[] = {
228 227
229static char *snd_pcm_tstamp_mode_names[] = { 228static char *snd_pcm_tstamp_mode_names[] = {
230 TSTAMP(NONE), 229 TSTAMP(NONE),
231 TSTAMP(MMAP), 230 TSTAMP(ENABLE),
232}; 231};
233 232
234static const char *snd_pcm_stream_name(int stream) 233static const char *snd_pcm_stream_name(int stream)
@@ -359,7 +358,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
359 snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den); 358 snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den);
360 snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size); 359 snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);
361 snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size); 360 snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);
362 snd_iprintf(buffer, "tick_time: %u\n", runtime->tick_time);
363#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 361#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
364 if (substream->oss.oss) { 362 if (substream->oss.oss) {
365 snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format)); 363 snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));
@@ -387,9 +385,7 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
387 } 385 }
388 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); 386 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
389 snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); 387 snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
390 snd_iprintf(buffer, "sleep_min: %u\n", runtime->sleep_min);
391 snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min); 388 snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);
392 snd_iprintf(buffer, "xfer_align: %lu\n", runtime->xfer_align);
393 snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold); 389 snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);
394 snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold); 390 snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);
395 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); 391 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
@@ -765,12 +761,6 @@ static int snd_pcm_dev_free(struct snd_device *device)
765 return snd_pcm_free(pcm); 761 return snd_pcm_free(pcm);
766} 762}
767 763
768static void snd_pcm_tick_timer_func(unsigned long data)
769{
770 struct snd_pcm_substream *substream = (struct snd_pcm_substream *) data;
771 snd_pcm_tick_elapsed(substream);
772}
773
774int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, 764int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
775 struct file *file, 765 struct file *file,
776 struct snd_pcm_substream **rsubstream) 766 struct snd_pcm_substream **rsubstream)
@@ -877,9 +867,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
877 memset((void*)runtime->control, 0, size); 867 memset((void*)runtime->control, 0, size);
878 868
879 init_waitqueue_head(&runtime->sleep); 869 init_waitqueue_head(&runtime->sleep);
880 init_timer(&runtime->tick_timer);
881 runtime->tick_timer.function = snd_pcm_tick_timer_func;
882 runtime->tick_timer.data = (unsigned long) substream;
883 870
884 runtime->status->state = SNDRV_PCM_STATE_OPEN; 871 runtime->status->state = SNDRV_PCM_STATE_OPEN;
885 872
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 2b539799d23b..49aa693fba8a 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -484,6 +484,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
484 case SNDRV_PCM_IOCTL_PVERSION: 484 case SNDRV_PCM_IOCTL_PVERSION:
485 case SNDRV_PCM_IOCTL_INFO: 485 case SNDRV_PCM_IOCTL_INFO:
486 case SNDRV_PCM_IOCTL_TSTAMP: 486 case SNDRV_PCM_IOCTL_TSTAMP:
487 case SNDRV_PCM_IOCTL_TTSTAMP:
487 case SNDRV_PCM_IOCTL_HWSYNC: 488 case SNDRV_PCM_IOCTL_HWSYNC:
488 case SNDRV_PCM_IOCTL_PREPARE: 489 case SNDRV_PCM_IOCTL_PREPARE:
489 case SNDRV_PCM_IOCTL_RESET: 490 case SNDRV_PCM_IOCTL_RESET:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 806f1fba5446..1533f0379e9d 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/time.h> 24#include <linux/time.h>
26#include <sound/core.h> 25#include <sound/core.h>
@@ -145,11 +144,11 @@ static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substre
145{ 144{
146 snd_pcm_uframes_t pos; 145 snd_pcm_uframes_t pos;
147 146
147 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
148 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
148 pos = substream->ops->pointer(substream); 149 pos = substream->ops->pointer(substream);
149 if (pos == SNDRV_PCM_POS_XRUN) 150 if (pos == SNDRV_PCM_POS_XRUN)
150 return pos; /* XRUN */ 151 return pos; /* XRUN */
151 if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
152 getnstimeofday((struct timespec *)&runtime->status->tstamp);
153#ifdef CONFIG_SND_DEBUG 152#ifdef CONFIG_SND_DEBUG
154 if (pos >= runtime->buffer_size) { 153 if (pos >= runtime->buffer_size) {
155 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); 154 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);
@@ -1139,7 +1138,7 @@ EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
1139 1138
1140static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 1139static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1141{ 1140{
1142 static int pow2_sizes[] = { 1141 static unsigned int pow2_sizes[] = {
1143 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7, 1142 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7,
1144 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1143 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15,
1145 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23, 1144 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23,
@@ -1451,108 +1450,13 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1451 1450
1452EXPORT_SYMBOL(snd_pcm_lib_ioctl); 1451EXPORT_SYMBOL(snd_pcm_lib_ioctl);
1453 1452
1454/*
1455 * Conditions
1456 */
1457
1458static void snd_pcm_system_tick_set(struct snd_pcm_substream *substream,
1459 unsigned long ticks)
1460{
1461 struct snd_pcm_runtime *runtime = substream->runtime;
1462 if (ticks == 0)
1463 del_timer(&runtime->tick_timer);
1464 else {
1465 ticks += (1000000 / HZ) - 1;
1466 ticks /= (1000000 / HZ);
1467 mod_timer(&runtime->tick_timer, jiffies + ticks);
1468 }
1469}
1470
1471/* Temporary alias */
1472void snd_pcm_tick_set(struct snd_pcm_substream *substream, unsigned long ticks)
1473{
1474 snd_pcm_system_tick_set(substream, ticks);
1475}
1476
1477void snd_pcm_tick_prepare(struct snd_pcm_substream *substream)
1478{
1479 struct snd_pcm_runtime *runtime = substream->runtime;
1480 snd_pcm_uframes_t frames = ULONG_MAX;
1481 snd_pcm_uframes_t avail, dist;
1482 unsigned int ticks;
1483 u_int64_t n;
1484 u_int32_t r;
1485 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1486 if (runtime->silence_size >= runtime->boundary) {
1487 frames = 1;
1488 } else if (runtime->silence_size > 0 &&
1489 runtime->silence_filled < runtime->buffer_size) {
1490 snd_pcm_sframes_t noise_dist;
1491 noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
1492 if (noise_dist > (snd_pcm_sframes_t)runtime->silence_threshold)
1493 frames = noise_dist - runtime->silence_threshold;
1494 }
1495 avail = snd_pcm_playback_avail(runtime);
1496 } else {
1497 avail = snd_pcm_capture_avail(runtime);
1498 }
1499 if (avail < runtime->control->avail_min) {
1500 snd_pcm_sframes_t n = runtime->control->avail_min - avail;
1501 if (n > 0 && frames > (snd_pcm_uframes_t)n)
1502 frames = n;
1503 }
1504 if (avail < runtime->buffer_size) {
1505 snd_pcm_sframes_t n = runtime->buffer_size - avail;
1506 if (n > 0 && frames > (snd_pcm_uframes_t)n)
1507 frames = n;
1508 }
1509 if (frames == ULONG_MAX) {
1510 snd_pcm_tick_set(substream, 0);
1511 return;
1512 }
1513 dist = runtime->status->hw_ptr - runtime->hw_ptr_base;
1514 /* Distance to next interrupt */
1515 dist = runtime->period_size - dist % runtime->period_size;
1516 if (dist <= frames) {
1517 snd_pcm_tick_set(substream, 0);
1518 return;
1519 }
1520 /* the base time is us */
1521 n = frames;
1522 n *= 1000000;
1523 div64_32(&n, runtime->tick_time * runtime->rate, &r);
1524 ticks = n + (r > 0 ? 1 : 0);
1525 if (ticks < runtime->sleep_min)
1526 ticks = runtime->sleep_min;
1527 snd_pcm_tick_set(substream, (unsigned long) ticks);
1528}
1529
1530void snd_pcm_tick_elapsed(struct snd_pcm_substream *substream)
1531{
1532 struct snd_pcm_runtime *runtime;
1533 unsigned long flags;
1534
1535 snd_assert(substream != NULL, return);
1536 runtime = substream->runtime;
1537 snd_assert(runtime != NULL, return);
1538
1539 snd_pcm_stream_lock_irqsave(substream, flags);
1540 if (!snd_pcm_running(substream) ||
1541 snd_pcm_update_hw_ptr(substream) < 0)
1542 goto _end;
1543 if (runtime->sleep_min)
1544 snd_pcm_tick_prepare(substream);
1545 _end:
1546 snd_pcm_stream_unlock_irqrestore(substream, flags);
1547}
1548
1549/** 1453/**
1550 * snd_pcm_period_elapsed - update the pcm status for the next period 1454 * snd_pcm_period_elapsed - update the pcm status for the next period
1551 * @substream: the pcm substream instance 1455 * @substream: the pcm substream instance
1552 * 1456 *
1553 * This function is called from the interrupt handler when the 1457 * This function is called from the interrupt handler when the
1554 * PCM has processed the period size. It will update the current 1458 * PCM has processed the period size. It will update the current
1555 * pointer, set up the tick, wake up sleepers, etc. 1459 * pointer, wake up sleepers, etc.
1556 * 1460 *
1557 * Even if more than one periods have elapsed since the last call, you 1461 * Even if more than one periods have elapsed since the last call, you
1558 * have to call this only once. 1462 * have to call this only once.
@@ -1576,8 +1480,6 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1576 1480
1577 if (substream->timer_running) 1481 if (substream->timer_running)
1578 snd_timer_interrupt(substream->timer, 1); 1482 snd_timer_interrupt(substream->timer, 1);
1579 if (runtime->sleep_min)
1580 snd_pcm_tick_prepare(substream);
1581 _end: 1483 _end:
1582 snd_pcm_stream_unlock_irqrestore(substream, flags); 1484 snd_pcm_stream_unlock_irqrestore(substream, flags);
1583 if (runtime->transfer_ack_end) 1485 if (runtime->transfer_ack_end)
@@ -1587,6 +1489,71 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1587 1489
1588EXPORT_SYMBOL(snd_pcm_period_elapsed); 1490EXPORT_SYMBOL(snd_pcm_period_elapsed);
1589 1491
1492/*
1493 * Wait until avail_min data becomes available
1494 * Returns a negative error code if any error occurs during operation.
1495 * The available space is stored on availp. When err = 0 and avail = 0
1496 * on the capture stream, it indicates the stream is in DRAINING state.
1497 */
1498static int wait_for_avail_min(struct snd_pcm_substream *substream,
1499 snd_pcm_uframes_t *availp)
1500{
1501 struct snd_pcm_runtime *runtime = substream->runtime;
1502 int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1503 wait_queue_t wait;
1504 int err = 0;
1505 snd_pcm_uframes_t avail = 0;
1506 long tout;
1507
1508 init_waitqueue_entry(&wait, current);
1509 add_wait_queue(&runtime->sleep, &wait);
1510 for (;;) {
1511 if (signal_pending(current)) {
1512 err = -ERESTARTSYS;
1513 break;
1514 }
1515 set_current_state(TASK_INTERRUPTIBLE);
1516 snd_pcm_stream_unlock_irq(substream);
1517 tout = schedule_timeout(msecs_to_jiffies(10000));
1518 snd_pcm_stream_lock_irq(substream);
1519 switch (runtime->status->state) {
1520 case SNDRV_PCM_STATE_SUSPENDED:
1521 err = -ESTRPIPE;
1522 goto _endloop;
1523 case SNDRV_PCM_STATE_XRUN:
1524 err = -EPIPE;
1525 goto _endloop;
1526 case SNDRV_PCM_STATE_DRAINING:
1527 if (is_playback)
1528 err = -EPIPE;
1529 else
1530 avail = 0; /* indicate draining */
1531 goto _endloop;
1532 case SNDRV_PCM_STATE_OPEN:
1533 case SNDRV_PCM_STATE_SETUP:
1534 case SNDRV_PCM_STATE_DISCONNECTED:
1535 err = -EBADFD;
1536 goto _endloop;
1537 }
1538 if (!tout) {
1539 snd_printd("%s write error (DMA or IRQ trouble?)\n",
1540 is_playback ? "playback" : "capture");
1541 err = -EIO;
1542 break;
1543 }
1544 if (is_playback)
1545 avail = snd_pcm_playback_avail(runtime);
1546 else
1547 avail = snd_pcm_capture_avail(runtime);
1548 if (avail >= runtime->control->avail_min)
1549 break;
1550 }
1551 _endloop:
1552 remove_wait_queue(&runtime->sleep, &wait);
1553 *availp = avail;
1554 return err;
1555}
1556
1590static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, 1557static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
1591 unsigned int hwoff, 1558 unsigned int hwoff,
1592 unsigned long data, unsigned int off, 1559 unsigned long data, unsigned int off,
@@ -1624,8 +1591,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1624 1591
1625 if (size == 0) 1592 if (size == 0)
1626 return 0; 1593 return 0;
1627 if (size > runtime->xfer_align)
1628 size -= size % runtime->xfer_align;
1629 1594
1630 snd_pcm_stream_lock_irq(substream); 1595 snd_pcm_stream_lock_irq(substream);
1631 switch (runtime->status->state) { 1596 switch (runtime->status->state) {
@@ -1648,84 +1613,18 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1648 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1613 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1649 snd_pcm_uframes_t avail; 1614 snd_pcm_uframes_t avail;
1650 snd_pcm_uframes_t cont; 1615 snd_pcm_uframes_t cont;
1651 if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) 1616 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
1652 snd_pcm_update_hw_ptr(substream); 1617 snd_pcm_update_hw_ptr(substream);
1653 avail = snd_pcm_playback_avail(runtime); 1618 avail = snd_pcm_playback_avail(runtime);
1654 if (((avail < runtime->control->avail_min && size > avail) || 1619 if (!avail) {
1655 (size >= runtime->xfer_align && avail < runtime->xfer_align))) {
1656 wait_queue_t wait;
1657 enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state;
1658 long tout;
1659
1660 if (nonblock) { 1620 if (nonblock) {
1661 err = -EAGAIN; 1621 err = -EAGAIN;
1662 goto _end_unlock; 1622 goto _end_unlock;
1663 } 1623 }
1664 1624 err = wait_for_avail_min(substream, &avail);
1665 init_waitqueue_entry(&wait, current); 1625 if (err < 0)
1666 add_wait_queue(&runtime->sleep, &wait);
1667 while (1) {
1668 if (signal_pending(current)) {
1669 state = SIGNALED;
1670 break;
1671 }
1672 set_current_state(TASK_INTERRUPTIBLE);
1673 snd_pcm_stream_unlock_irq(substream);
1674 tout = schedule_timeout(10 * HZ);
1675 snd_pcm_stream_lock_irq(substream);
1676 if (tout == 0) {
1677 if (runtime->status->state != SNDRV_PCM_STATE_PREPARED &&
1678 runtime->status->state != SNDRV_PCM_STATE_PAUSED) {
1679 state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
1680 break;
1681 }
1682 }
1683 switch (runtime->status->state) {
1684 case SNDRV_PCM_STATE_XRUN:
1685 case SNDRV_PCM_STATE_DRAINING:
1686 state = ERROR;
1687 goto _end_loop;
1688 case SNDRV_PCM_STATE_SUSPENDED:
1689 state = SUSPENDED;
1690 goto _end_loop;
1691 case SNDRV_PCM_STATE_SETUP:
1692 state = DROPPED;
1693 goto _end_loop;
1694 default:
1695 break;
1696 }
1697 avail = snd_pcm_playback_avail(runtime);
1698 if (avail >= runtime->control->avail_min) {
1699 state = READY;
1700 break;
1701 }
1702 }
1703 _end_loop:
1704 remove_wait_queue(&runtime->sleep, &wait);
1705
1706 switch (state) {
1707 case ERROR:
1708 err = -EPIPE;
1709 goto _end_unlock;
1710 case SUSPENDED:
1711 err = -ESTRPIPE;
1712 goto _end_unlock;
1713 case SIGNALED:
1714 err = -ERESTARTSYS;
1715 goto _end_unlock;
1716 case EXPIRED:
1717 snd_printd("playback write error (DMA or IRQ trouble?)\n");
1718 err = -EIO;
1719 goto _end_unlock;
1720 case DROPPED:
1721 err = -EBADFD;
1722 goto _end_unlock; 1626 goto _end_unlock;
1723 default:
1724 break;
1725 }
1726 } 1627 }
1727 if (avail > runtime->xfer_align)
1728 avail -= avail % runtime->xfer_align;
1729 frames = size > avail ? avail : size; 1628 frames = size > avail ? avail : size;
1730 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; 1629 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
1731 if (frames > cont) 1630 if (frames > cont)
@@ -1763,9 +1662,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1763 if (err < 0) 1662 if (err < 0)
1764 goto _end_unlock; 1663 goto _end_unlock;
1765 } 1664 }
1766 if (runtime->sleep_min &&
1767 runtime->status->state == SNDRV_PCM_STATE_RUNNING)
1768 snd_pcm_tick_prepare(substream);
1769 } 1665 }
1770 _end_unlock: 1666 _end_unlock:
1771 snd_pcm_stream_unlock_irq(substream); 1667 snd_pcm_stream_unlock_irq(substream);
@@ -1893,8 +1789,6 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1893 1789
1894 if (size == 0) 1790 if (size == 0)
1895 return 0; 1791 return 0;
1896 if (size > runtime->xfer_align)
1897 size -= size % runtime->xfer_align;
1898 1792
1899 snd_pcm_stream_lock_irq(substream); 1793 snd_pcm_stream_lock_irq(substream);
1900 switch (runtime->status->state) { 1794 switch (runtime->status->state) {
@@ -1924,91 +1818,25 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1924 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1818 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1925 snd_pcm_uframes_t avail; 1819 snd_pcm_uframes_t avail;
1926 snd_pcm_uframes_t cont; 1820 snd_pcm_uframes_t cont;
1927 if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) 1821 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
1928 snd_pcm_update_hw_ptr(substream); 1822 snd_pcm_update_hw_ptr(substream);
1929 __draining:
1930 avail = snd_pcm_capture_avail(runtime); 1823 avail = snd_pcm_capture_avail(runtime);
1931 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 1824 if (!avail) {
1932 if (avail < runtime->xfer_align) { 1825 if (runtime->status->state ==
1933 err = -EPIPE; 1826 SNDRV_PCM_STATE_DRAINING) {
1827 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
1934 goto _end_unlock; 1828 goto _end_unlock;
1935 } 1829 }
1936 } else if ((avail < runtime->control->avail_min && size > avail) ||
1937 (size >= runtime->xfer_align && avail < runtime->xfer_align)) {
1938 wait_queue_t wait;
1939 enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state;
1940 long tout;
1941
1942 if (nonblock) { 1830 if (nonblock) {
1943 err = -EAGAIN; 1831 err = -EAGAIN;
1944 goto _end_unlock; 1832 goto _end_unlock;
1945 } 1833 }
1946 1834 err = wait_for_avail_min(substream, &avail);
1947 init_waitqueue_entry(&wait, current); 1835 if (err < 0)
1948 add_wait_queue(&runtime->sleep, &wait);
1949 while (1) {
1950 if (signal_pending(current)) {
1951 state = SIGNALED;
1952 break;
1953 }
1954 set_current_state(TASK_INTERRUPTIBLE);
1955 snd_pcm_stream_unlock_irq(substream);
1956 tout = schedule_timeout(10 * HZ);
1957 snd_pcm_stream_lock_irq(substream);
1958 if (tout == 0) {
1959 if (runtime->status->state != SNDRV_PCM_STATE_PREPARED &&
1960 runtime->status->state != SNDRV_PCM_STATE_PAUSED) {
1961 state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
1962 break;
1963 }
1964 }
1965 switch (runtime->status->state) {
1966 case SNDRV_PCM_STATE_XRUN:
1967 state = ERROR;
1968 goto _end_loop;
1969 case SNDRV_PCM_STATE_SUSPENDED:
1970 state = SUSPENDED;
1971 goto _end_loop;
1972 case SNDRV_PCM_STATE_DRAINING:
1973 goto __draining;
1974 case SNDRV_PCM_STATE_SETUP:
1975 state = DROPPED;
1976 goto _end_loop;
1977 default:
1978 break;
1979 }
1980 avail = snd_pcm_capture_avail(runtime);
1981 if (avail >= runtime->control->avail_min) {
1982 state = READY;
1983 break;
1984 }
1985 }
1986 _end_loop:
1987 remove_wait_queue(&runtime->sleep, &wait);
1988
1989 switch (state) {
1990 case ERROR:
1991 err = -EPIPE;
1992 goto _end_unlock;
1993 case SUSPENDED:
1994 err = -ESTRPIPE;
1995 goto _end_unlock;
1996 case SIGNALED:
1997 err = -ERESTARTSYS;
1998 goto _end_unlock;
1999 case EXPIRED:
2000 snd_printd("capture read error (DMA or IRQ trouble?)\n");
2001 err = -EIO;
2002 goto _end_unlock;
2003 case DROPPED:
2004 err = -EBADFD;
2005 goto _end_unlock; 1836 goto _end_unlock;
2006 default: 1837 if (!avail)
2007 break; 1838 continue; /* draining */
2008 }
2009 } 1839 }
2010 if (avail > runtime->xfer_align)
2011 avail -= avail % runtime->xfer_align;
2012 frames = size > avail ? avail : size; 1840 frames = size > avail ? avail : size;
2013 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; 1841 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
2014 if (frames > cont) 1842 if (frames > cont)
@@ -2040,9 +1868,6 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2040 offset += frames; 1868 offset += frames;
2041 size -= frames; 1869 size -= frames;
2042 xfer += frames; 1870 xfer += frames;
2043 if (runtime->sleep_min &&
2044 runtime->status->state == SNDRV_PCM_STATE_RUNNING)
2045 snd_pcm_tick_prepare(substream);
2046 } 1871 }
2047 _end_unlock: 1872 _end_unlock:
2048 snd_pcm_stream_unlock_irq(substream); 1873 snd_pcm_stream_unlock_irq(substream);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index a13e38cfd2c6..ff07b4a9992e 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <linux/time.h> 23#include <linux/time.h>
25#include <linux/init.h> 24#include <linux/init.h>
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index dd9aa51d8c82..89b7f549bebd 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -75,7 +74,7 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
75 }, 74 },
76 [SNDRV_PCM_FORMAT_U24_BE] = { 75 [SNDRV_PCM_FORMAT_U24_BE] = {
77 .width = 24, .phys = 32, .le = 0, .signd = 0, 76 .width = 24, .phys = 32, .le = 0, .signd = 0,
78 .silence = { 0x80, 0x00, 0x00 }, 77 .silence = { 0x00, 0x80, 0x00, 0x00 },
79 }, 78 },
80 [SNDRV_PCM_FORMAT_S32_LE] = { 79 [SNDRV_PCM_FORMAT_S32_LE] = {
81 .width = 32, .phys = 32, .le = 1, .signd = 1, 80 .width = 32, .phys = 32, .le = 1, .signd = 1,
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index fb3dde4db045..62449117ee14 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/mm.h> 22#include <linux/mm.h>
24#include <linux/file.h> 23#include <linux/file.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
@@ -413,7 +412,6 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
413 runtime->period_size = params_period_size(params); 412 runtime->period_size = params_period_size(params);
414 runtime->periods = params_periods(params); 413 runtime->periods = params_periods(params);
415 runtime->buffer_size = params_buffer_size(params); 414 runtime->buffer_size = params_buffer_size(params);
416 runtime->tick_time = params_tick_time(params);
417 runtime->info = params->info; 415 runtime->info = params->info;
418 runtime->rate_num = params->rate_num; 416 runtime->rate_num = params->rate_num;
419 runtime->rate_den = params->rate_den; 417 runtime->rate_den = params->rate_den;
@@ -433,9 +431,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
433 /* Default sw params */ 431 /* Default sw params */
434 runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; 432 runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
435 runtime->period_step = 1; 433 runtime->period_step = 1;
436 runtime->sleep_min = 0;
437 runtime->control->avail_min = runtime->period_size; 434 runtime->control->avail_min = runtime->period_size;
438 runtime->xfer_align = runtime->period_size;
439 runtime->start_threshold = 1; 435 runtime->start_threshold = 1;
440 runtime->stop_threshold = runtime->buffer_size; 436 runtime->stop_threshold = runtime->buffer_size;
441 runtime->silence_threshold = 0; 437 runtime->silence_threshold = 0;
@@ -532,9 +528,6 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
532 return -EINVAL; 528 return -EINVAL;
533 if (params->avail_min == 0) 529 if (params->avail_min == 0)
534 return -EINVAL; 530 return -EINVAL;
535 if (params->xfer_align == 0 ||
536 params->xfer_align % runtime->min_align != 0)
537 return -EINVAL;
538 if (params->silence_size >= runtime->boundary) { 531 if (params->silence_size >= runtime->boundary) {
539 if (params->silence_threshold != 0) 532 if (params->silence_threshold != 0)
540 return -EINVAL; 533 return -EINVAL;
@@ -546,20 +539,14 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
546 } 539 }
547 snd_pcm_stream_lock_irq(substream); 540 snd_pcm_stream_lock_irq(substream);
548 runtime->tstamp_mode = params->tstamp_mode; 541 runtime->tstamp_mode = params->tstamp_mode;
549 runtime->sleep_min = params->sleep_min;
550 runtime->period_step = params->period_step; 542 runtime->period_step = params->period_step;
551 runtime->control->avail_min = params->avail_min; 543 runtime->control->avail_min = params->avail_min;
552 runtime->start_threshold = params->start_threshold; 544 runtime->start_threshold = params->start_threshold;
553 runtime->stop_threshold = params->stop_threshold; 545 runtime->stop_threshold = params->stop_threshold;
554 runtime->silence_threshold = params->silence_threshold; 546 runtime->silence_threshold = params->silence_threshold;
555 runtime->silence_size = params->silence_size; 547 runtime->silence_size = params->silence_size;
556 runtime->xfer_align = params->xfer_align;
557 params->boundary = runtime->boundary; 548 params->boundary = runtime->boundary;
558 if (snd_pcm_running(substream)) { 549 if (snd_pcm_running(substream)) {
559 if (runtime->sleep_min)
560 snd_pcm_tick_prepare(substream);
561 else
562 snd_pcm_tick_set(substream, 0);
563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 550 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
564 runtime->silence_size > 0) 551 runtime->silence_size > 0)
565 snd_pcm_playback_silence(substream, ULONG_MAX); 552 snd_pcm_playback_silence(substream, ULONG_MAX);
@@ -595,12 +582,13 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
595 status->trigger_tstamp = runtime->trigger_tstamp; 582 status->trigger_tstamp = runtime->trigger_tstamp;
596 if (snd_pcm_running(substream)) { 583 if (snd_pcm_running(substream)) {
597 snd_pcm_update_hw_ptr(substream); 584 snd_pcm_update_hw_ptr(substream);
598 if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) 585 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
599 status->tstamp = runtime->status->tstamp; 586 status->tstamp = runtime->status->tstamp;
600 else 587 goto _tstamp_end;
601 getnstimeofday(&status->tstamp); 588 }
602 } else 589 }
603 getnstimeofday(&status->tstamp); 590 snd_pcm_gettime(runtime, &status->tstamp);
591 _tstamp_end:
604 status->appl_ptr = runtime->control->appl_ptr; 592 status->appl_ptr = runtime->control->appl_ptr;
605 status->hw_ptr = runtime->status->hw_ptr; 593 status->hw_ptr = runtime->status->hw_ptr;
606 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 594 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -688,7 +676,7 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
688 if (runtime->trigger_master == NULL) 676 if (runtime->trigger_master == NULL)
689 return; 677 return;
690 if (runtime->trigger_master == substream) { 678 if (runtime->trigger_master == substream) {
691 getnstimeofday(&runtime->trigger_tstamp); 679 snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
692 } else { 680 } else {
693 snd_pcm_trigger_tstamp(runtime->trigger_master); 681 snd_pcm_trigger_tstamp(runtime->trigger_master);
694 runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp; 682 runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -875,8 +863,6 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
875 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 863 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
876 runtime->silence_size > 0) 864 runtime->silence_size > 0)
877 snd_pcm_playback_silence(substream, ULONG_MAX); 865 snd_pcm_playback_silence(substream, ULONG_MAX);
878 if (runtime->sleep_min)
879 snd_pcm_tick_prepare(substream);
880 if (substream->timer) 866 if (substream->timer)
881 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART, 867 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
882 &runtime->trigger_tstamp); 868 &runtime->trigger_tstamp);
@@ -930,7 +916,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
930 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, 916 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
931 &runtime->trigger_tstamp); 917 &runtime->trigger_tstamp);
932 runtime->status->state = state; 918 runtime->status->state = state;
933 snd_pcm_tick_set(substream, 0);
934 } 919 }
935 wake_up(&runtime->sleep); 920 wake_up(&runtime->sleep);
936} 921}
@@ -1014,12 +999,9 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1014 snd_timer_notify(substream->timer, 999 snd_timer_notify(substream->timer,
1015 SNDRV_TIMER_EVENT_MPAUSE, 1000 SNDRV_TIMER_EVENT_MPAUSE,
1016 &runtime->trigger_tstamp); 1001 &runtime->trigger_tstamp);
1017 snd_pcm_tick_set(substream, 0);
1018 wake_up(&runtime->sleep); 1002 wake_up(&runtime->sleep);
1019 } else { 1003 } else {
1020 runtime->status->state = SNDRV_PCM_STATE_RUNNING; 1004 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1021 if (runtime->sleep_min)
1022 snd_pcm_tick_prepare(substream);
1023 if (substream->timer) 1005 if (substream->timer)
1024 snd_timer_notify(substream->timer, 1006 snd_timer_notify(substream->timer,
1025 SNDRV_TIMER_EVENT_MCONTINUE, 1007 SNDRV_TIMER_EVENT_MCONTINUE,
@@ -1074,7 +1056,6 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1074 &runtime->trigger_tstamp); 1056 &runtime->trigger_tstamp);
1075 runtime->status->suspended_state = runtime->status->state; 1057 runtime->status->suspended_state = runtime->status->state;
1076 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; 1058 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1077 snd_pcm_tick_set(substream, 0);
1078 wake_up(&runtime->sleep); 1059 wake_up(&runtime->sleep);
1079} 1060}
1080 1061
@@ -1177,8 +1158,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
1177 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME, 1158 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
1178 &runtime->trigger_tstamp); 1159 &runtime->trigger_tstamp);
1179 runtime->status->state = runtime->status->suspended_state; 1160 runtime->status->state = runtime->status->suspended_state;
1180 if (runtime->sleep_min)
1181 snd_pcm_tick_prepare(substream);
1182} 1161}
1183 1162
1184static struct action_ops snd_pcm_action_resume = { 1163static struct action_ops snd_pcm_action_resume = {
@@ -1395,10 +1374,10 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
1395 } else { 1374 } else {
1396 /* stop running stream */ 1375 /* stop running stream */
1397 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) { 1376 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
1398 int state = snd_pcm_capture_avail(runtime) > 0 ? 1377 int new_state = snd_pcm_capture_avail(runtime) > 0 ?
1399 SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP; 1378 SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
1400 snd_pcm_do_stop(substream, state); 1379 snd_pcm_do_stop(substream, new_state);
1401 snd_pcm_post_stop(substream, state); 1380 snd_pcm_post_stop(substream, new_state);
1402 } 1381 }
1403 } 1382 }
1404 return 0; 1383 return 0;
@@ -2007,8 +1986,6 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
2007 } 1986 }
2008 1987
2009 /* FIXME: this belong to lowlevel */ 1988 /* FIXME: this belong to lowlevel */
2010 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_TICK_TIME,
2011 1000000 / HZ, 1000000 / HZ);
2012 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); 1989 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2013 1990
2014 return 0; 1991 return 0;
@@ -2244,15 +2221,10 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
2244 } 2221 }
2245 if (frames > (snd_pcm_uframes_t)hw_avail) 2222 if (frames > (snd_pcm_uframes_t)hw_avail)
2246 frames = hw_avail; 2223 frames = hw_avail;
2247 else
2248 frames -= frames % runtime->xfer_align;
2249 appl_ptr = runtime->control->appl_ptr - frames; 2224 appl_ptr = runtime->control->appl_ptr - frames;
2250 if (appl_ptr < 0) 2225 if (appl_ptr < 0)
2251 appl_ptr += runtime->boundary; 2226 appl_ptr += runtime->boundary;
2252 runtime->control->appl_ptr = appl_ptr; 2227 runtime->control->appl_ptr = appl_ptr;
2253 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
2254 runtime->sleep_min)
2255 snd_pcm_tick_prepare(substream);
2256 ret = frames; 2228 ret = frames;
2257 __end: 2229 __end:
2258 snd_pcm_stream_unlock_irq(substream); 2230 snd_pcm_stream_unlock_irq(substream);
@@ -2294,15 +2266,10 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
2294 } 2266 }
2295 if (frames > (snd_pcm_uframes_t)hw_avail) 2267 if (frames > (snd_pcm_uframes_t)hw_avail)
2296 frames = hw_avail; 2268 frames = hw_avail;
2297 else
2298 frames -= frames % runtime->xfer_align;
2299 appl_ptr = runtime->control->appl_ptr - frames; 2269 appl_ptr = runtime->control->appl_ptr - frames;
2300 if (appl_ptr < 0) 2270 if (appl_ptr < 0)
2301 appl_ptr += runtime->boundary; 2271 appl_ptr += runtime->boundary;
2302 runtime->control->appl_ptr = appl_ptr; 2272 runtime->control->appl_ptr = appl_ptr;
2303 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
2304 runtime->sleep_min)
2305 snd_pcm_tick_prepare(substream);
2306 ret = frames; 2273 ret = frames;
2307 __end: 2274 __end:
2308 snd_pcm_stream_unlock_irq(substream); 2275 snd_pcm_stream_unlock_irq(substream);
@@ -2345,15 +2312,10 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
2345 } 2312 }
2346 if (frames > (snd_pcm_uframes_t)avail) 2313 if (frames > (snd_pcm_uframes_t)avail)
2347 frames = avail; 2314 frames = avail;
2348 else
2349 frames -= frames % runtime->xfer_align;
2350 appl_ptr = runtime->control->appl_ptr + frames; 2315 appl_ptr = runtime->control->appl_ptr + frames;
2351 if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) 2316 if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
2352 appl_ptr -= runtime->boundary; 2317 appl_ptr -= runtime->boundary;
2353 runtime->control->appl_ptr = appl_ptr; 2318 runtime->control->appl_ptr = appl_ptr;
2354 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
2355 runtime->sleep_min)
2356 snd_pcm_tick_prepare(substream);
2357 ret = frames; 2319 ret = frames;
2358 __end: 2320 __end:
2359 snd_pcm_stream_unlock_irq(substream); 2321 snd_pcm_stream_unlock_irq(substream);
@@ -2396,15 +2358,10 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
2396 } 2358 }
2397 if (frames > (snd_pcm_uframes_t)avail) 2359 if (frames > (snd_pcm_uframes_t)avail)
2398 frames = avail; 2360 frames = avail;
2399 else
2400 frames -= frames % runtime->xfer_align;
2401 appl_ptr = runtime->control->appl_ptr + frames; 2361 appl_ptr = runtime->control->appl_ptr + frames;
2402 if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) 2362 if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
2403 appl_ptr -= runtime->boundary; 2363 appl_ptr -= runtime->boundary;
2404 runtime->control->appl_ptr = appl_ptr; 2364 runtime->control->appl_ptr = appl_ptr;
2405 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
2406 runtime->sleep_min)
2407 snd_pcm_tick_prepare(substream);
2408 ret = frames; 2365 ret = frames;
2409 __end: 2366 __end:
2410 snd_pcm_stream_unlock_irq(substream); 2367 snd_pcm_stream_unlock_irq(substream);
@@ -2519,6 +2476,21 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2519 return -EFAULT; 2476 return -EFAULT;
2520 return 0; 2477 return 0;
2521} 2478}
2479
2480static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
2481{
2482 struct snd_pcm_runtime *runtime = substream->runtime;
2483 int arg;
2484
2485 if (get_user(arg, _arg))
2486 return -EFAULT;
2487 if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
2488 return -EINVAL;
2489 runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
2490 if (arg == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC)
2491 runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
2492 return 0;
2493}
2522 2494
2523static int snd_pcm_common_ioctl1(struct file *file, 2495static int snd_pcm_common_ioctl1(struct file *file,
2524 struct snd_pcm_substream *substream, 2496 struct snd_pcm_substream *substream,
@@ -2531,8 +2503,10 @@ static int snd_pcm_common_ioctl1(struct file *file,
2531 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; 2503 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
2532 case SNDRV_PCM_IOCTL_INFO: 2504 case SNDRV_PCM_IOCTL_INFO:
2533 return snd_pcm_info_user(substream, arg); 2505 return snd_pcm_info_user(substream, arg);
2534 case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */ 2506 case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
2535 return 0; 2507 return 0;
2508 case SNDRV_PCM_IOCTL_TTSTAMP:
2509 return snd_pcm_tstamp(substream, arg);
2536 case SNDRV_PCM_IOCTL_HW_REFINE: 2510 case SNDRV_PCM_IOCTL_HW_REFINE:
2537 return snd_pcm_hw_refine_user(substream, arg); 2511 return snd_pcm_hw_refine_user(substream, arg);
2538 case SNDRV_PCM_IOCTL_HW_PARAMS: 2512 case SNDRV_PCM_IOCTL_HW_PARAMS:
@@ -3018,26 +2992,23 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
3018/* 2992/*
3019 * mmap status record 2993 * mmap status record
3020 */ 2994 */
3021static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, 2995static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
3022 unsigned long address, int *type) 2996 struct vm_fault *vmf)
3023{ 2997{
3024 struct snd_pcm_substream *substream = area->vm_private_data; 2998 struct snd_pcm_substream *substream = area->vm_private_data;
3025 struct snd_pcm_runtime *runtime; 2999 struct snd_pcm_runtime *runtime;
3026 struct page * page;
3027 3000
3028 if (substream == NULL) 3001 if (substream == NULL)
3029 return NOPAGE_SIGBUS; 3002 return VM_FAULT_SIGBUS;
3030 runtime = substream->runtime; 3003 runtime = substream->runtime;
3031 page = virt_to_page(runtime->status); 3004 vmf->page = virt_to_page(runtime->status);
3032 get_page(page); 3005 get_page(vmf->page);
3033 if (type) 3006 return 0;
3034 *type = VM_FAULT_MINOR;
3035 return page;
3036} 3007}
3037 3008
3038static struct vm_operations_struct snd_pcm_vm_ops_status = 3009static struct vm_operations_struct snd_pcm_vm_ops_status =
3039{ 3010{
3040 .nopage = snd_pcm_mmap_status_nopage, 3011 .fault = snd_pcm_mmap_status_fault,
3041}; 3012};
3042 3013
3043static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, 3014static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
@@ -3061,26 +3032,23 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
3061/* 3032/*
3062 * mmap control record 3033 * mmap control record
3063 */ 3034 */
3064static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, 3035static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
3065 unsigned long address, int *type) 3036 struct vm_fault *vmf)
3066{ 3037{
3067 struct snd_pcm_substream *substream = area->vm_private_data; 3038 struct snd_pcm_substream *substream = area->vm_private_data;
3068 struct snd_pcm_runtime *runtime; 3039 struct snd_pcm_runtime *runtime;
3069 struct page * page;
3070 3040
3071 if (substream == NULL) 3041 if (substream == NULL)
3072 return NOPAGE_SIGBUS; 3042 return VM_FAULT_SIGBUS;
3073 runtime = substream->runtime; 3043 runtime = substream->runtime;
3074 page = virt_to_page(runtime->control); 3044 vmf->page = virt_to_page(runtime->control);
3075 get_page(page); 3045 get_page(vmf->page);
3076 if (type) 3046 return 0;
3077 *type = VM_FAULT_MINOR;
3078 return page;
3079} 3047}
3080 3048
3081static struct vm_operations_struct snd_pcm_vm_ops_control = 3049static struct vm_operations_struct snd_pcm_vm_ops_control =
3082{ 3050{
3083 .nopage = snd_pcm_mmap_control_nopage, 3051 .fault = snd_pcm_mmap_control_fault,
3084}; 3052};
3085 3053
3086static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, 3054static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
@@ -3117,10 +3085,10 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3117#endif /* coherent mmap */ 3085#endif /* coherent mmap */
3118 3086
3119/* 3087/*
3120 * nopage callback for mmapping a RAM page 3088 * fault callback for mmapping a RAM page
3121 */ 3089 */
3122static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, 3090static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3123 unsigned long address, int *type) 3091 struct vm_fault *vmf)
3124{ 3092{
3125 struct snd_pcm_substream *substream = area->vm_private_data; 3093 struct snd_pcm_substream *substream = area->vm_private_data;
3126 struct snd_pcm_runtime *runtime; 3094 struct snd_pcm_runtime *runtime;
@@ -3130,33 +3098,30 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
3130 size_t dma_bytes; 3098 size_t dma_bytes;
3131 3099
3132 if (substream == NULL) 3100 if (substream == NULL)
3133 return NOPAGE_SIGBUS; 3101 return VM_FAULT_SIGBUS;
3134 runtime = substream->runtime; 3102 runtime = substream->runtime;
3135 offset = area->vm_pgoff << PAGE_SHIFT; 3103 offset = vmf->pgoff << PAGE_SHIFT;
3136 offset += address - area->vm_start;
3137 snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS);
3138 dma_bytes = PAGE_ALIGN(runtime->dma_bytes); 3104 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3139 if (offset > dma_bytes - PAGE_SIZE) 3105 if (offset > dma_bytes - PAGE_SIZE)
3140 return NOPAGE_SIGBUS; 3106 return VM_FAULT_SIGBUS;
3141 if (substream->ops->page) { 3107 if (substream->ops->page) {
3142 page = substream->ops->page(substream, offset); 3108 page = substream->ops->page(substream, offset);
3143 if (! page) 3109 if (!page)
3144 return NOPAGE_OOM; /* XXX: is this really due to OOM? */ 3110 return VM_FAULT_SIGBUS;
3145 } else { 3111 } else {
3146 vaddr = runtime->dma_area + offset; 3112 vaddr = runtime->dma_area + offset;
3147 page = virt_to_page(vaddr); 3113 page = virt_to_page(vaddr);
3148 } 3114 }
3149 get_page(page); 3115 get_page(page);
3150 if (type) 3116 vmf->page = page;
3151 *type = VM_FAULT_MINOR; 3117 return 0;
3152 return page;
3153} 3118}
3154 3119
3155static struct vm_operations_struct snd_pcm_vm_ops_data = 3120static struct vm_operations_struct snd_pcm_vm_ops_data =
3156{ 3121{
3157 .open = snd_pcm_mmap_data_open, 3122 .open = snd_pcm_mmap_data_open,
3158 .close = snd_pcm_mmap_data_close, 3123 .close = snd_pcm_mmap_data_close,
3159 .nopage = snd_pcm_mmap_data_nopage, 3124 .fault = snd_pcm_mmap_data_fault,
3160}; 3125};
3161 3126
3162/* 3127/*
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index 23aa9a27e215..033a024d153a 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index b8e700b94e59..f7ea7287c59c 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <sound/core.h> 22#include <sound/core.h>
24#include <linux/major.h> 23#include <linux/major.h>
25#include <linux/init.h> 24#include <linux/init.h>
@@ -912,7 +911,8 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
912} 911}
913 912
914static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, 913static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
915 unsigned char *buf, long count, int kernel) 914 unsigned char __user *userbuf,
915 unsigned char *kernelbuf, long count)
916{ 916{
917 unsigned long flags; 917 unsigned long flags;
918 long result = 0, count1; 918 long result = 0, count1;
@@ -925,11 +925,11 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
925 spin_lock_irqsave(&runtime->lock, flags); 925 spin_lock_irqsave(&runtime->lock, flags);
926 if (count1 > (int)runtime->avail) 926 if (count1 > (int)runtime->avail)
927 count1 = runtime->avail; 927 count1 = runtime->avail;
928 if (kernel) { 928 if (kernelbuf)
929 memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1); 929 memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
930 } else { 930 if (userbuf) {
931 spin_unlock_irqrestore(&runtime->lock, flags); 931 spin_unlock_irqrestore(&runtime->lock, flags);
932 if (copy_to_user((char __user *)buf + result, 932 if (copy_to_user(userbuf + result,
933 runtime->buffer + runtime->appl_ptr, count1)) { 933 runtime->buffer + runtime->appl_ptr, count1)) {
934 return result > 0 ? result : -EFAULT; 934 return result > 0 ? result : -EFAULT;
935 } 935 }
@@ -949,7 +949,7 @@ long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
949 unsigned char *buf, long count) 949 unsigned char *buf, long count)
950{ 950{
951 snd_rawmidi_input_trigger(substream, 1); 951 snd_rawmidi_input_trigger(substream, 1);
952 return snd_rawmidi_kernel_read1(substream, buf, count, 1); 952 return snd_rawmidi_kernel_read1(substream, NULL/*userbuf*/, buf, count);
953} 953}
954 954
955static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, 955static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count,
@@ -990,8 +990,9 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
990 } 990 }
991 spin_unlock_irq(&runtime->lock); 991 spin_unlock_irq(&runtime->lock);
992 count1 = snd_rawmidi_kernel_read1(substream, 992 count1 = snd_rawmidi_kernel_read1(substream,
993 (unsigned char __force *)buf, 993 (unsigned char __user *)buf,
994 count, 0); 994 NULL/*kernelbuf*/,
995 count);
995 if (count1 < 0) 996 if (count1 < 0)
996 return result > 0 ? result : count1; 997 return result > 0 ? result : count1;
997 result += count1; 998 result += count1;
@@ -1132,13 +1133,15 @@ int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
1132} 1133}
1133 1134
1134static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, 1135static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1135 const unsigned char *buf, long count, int kernel) 1136 const unsigned char __user *userbuf,
1137 const unsigned char *kernelbuf,
1138 long count)
1136{ 1139{
1137 unsigned long flags; 1140 unsigned long flags;
1138 long count1, result; 1141 long count1, result;
1139 struct snd_rawmidi_runtime *runtime = substream->runtime; 1142 struct snd_rawmidi_runtime *runtime = substream->runtime;
1140 1143
1141 snd_assert(buf != NULL, return -EINVAL); 1144 snd_assert(kernelbuf != NULL || userbuf != NULL, return -EINVAL);
1142 snd_assert(runtime->buffer != NULL, return -EINVAL); 1145 snd_assert(runtime->buffer != NULL, return -EINVAL);
1143 1146
1144 result = 0; 1147 result = 0;
@@ -1155,12 +1158,13 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1155 count1 = count; 1158 count1 = count;
1156 if (count1 > (long)runtime->avail) 1159 if (count1 > (long)runtime->avail)
1157 count1 = runtime->avail; 1160 count1 = runtime->avail;
1158 if (kernel) { 1161 if (kernelbuf)
1159 memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); 1162 memcpy(runtime->buffer + runtime->appl_ptr,
1160 } else { 1163 kernelbuf + result, count1);
1164 else if (userbuf) {
1161 spin_unlock_irqrestore(&runtime->lock, flags); 1165 spin_unlock_irqrestore(&runtime->lock, flags);
1162 if (copy_from_user(runtime->buffer + runtime->appl_ptr, 1166 if (copy_from_user(runtime->buffer + runtime->appl_ptr,
1163 (char __user *)buf, count1)) { 1167 userbuf + result, count1)) {
1164 spin_lock_irqsave(&runtime->lock, flags); 1168 spin_lock_irqsave(&runtime->lock, flags);
1165 result = result > 0 ? result : -EFAULT; 1169 result = result > 0 ? result : -EFAULT;
1166 goto __end; 1170 goto __end;
@@ -1171,7 +1175,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1171 runtime->appl_ptr %= runtime->buffer_size; 1175 runtime->appl_ptr %= runtime->buffer_size;
1172 runtime->avail -= count1; 1176 runtime->avail -= count1;
1173 result += count1; 1177 result += count1;
1174 buf += count1;
1175 count -= count1; 1178 count -= count1;
1176 } 1179 }
1177 __end: 1180 __end:
@@ -1185,7 +1188,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1185long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, 1188long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
1186 const unsigned char *buf, long count) 1189 const unsigned char *buf, long count)
1187{ 1190{
1188 return snd_rawmidi_kernel_write1(substream, buf, count, 1); 1191 return snd_rawmidi_kernel_write1(substream, NULL, buf, count);
1189} 1192}
1190 1193
1191static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, 1194static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
@@ -1225,9 +1228,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1225 spin_lock_irq(&runtime->lock); 1228 spin_lock_irq(&runtime->lock);
1226 } 1229 }
1227 spin_unlock_irq(&runtime->lock); 1230 spin_unlock_irq(&runtime->lock);
1228 count1 = snd_rawmidi_kernel_write1(substream, 1231 count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count);
1229 (unsigned char __force *)buf,
1230 count, 0);
1231 if (count1 < 0) 1232 if (count1 < 0)
1232 return result > 0 ? result : count1; 1233 return result > 0 ? result : count1;
1233 result += count1; 1234 result += count1;
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 7cd5e8f5d4ce..97b30fb4c361 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/interrupt.h> 24#include <linux/interrupt.h>
26#include <linux/moduleparam.h> 25#include <linux/moduleparam.h>
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile
index ceef14afee30..069593717fba 100644
--- a/sound/core/seq/Makefile
+++ b/sound/core/seq/Makefile
@@ -3,7 +3,6 @@
3# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> 3# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
4# 4#
5 5
6obj-$(CONFIG_SND) += instr/
7ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) 6ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
8 obj-$(CONFIG_SND_SEQUENCER) += oss/ 7 obj-$(CONFIG_SND_SEQUENCER) += oss/
9endif 8endif
@@ -15,7 +14,6 @@ snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \
15snd-seq-midi-objs := seq_midi.o 14snd-seq-midi-objs := seq_midi.o
16snd-seq-midi-emul-objs := seq_midi_emul.o 15snd-seq-midi-emul-objs := seq_midi_emul.o
17snd-seq-midi-event-objs := seq_midi_event.o 16snd-seq-midi-event-objs := seq_midi_event.o
18snd-seq-instr-objs := seq_instr.o
19snd-seq-dummy-objs := seq_dummy.o 17snd-seq-dummy-objs := seq_dummy.o
20snd-seq-virmidi-objs := seq_virmidi.o 18snd-seq-virmidi-objs := seq_virmidi.o
21 19
@@ -36,9 +34,7 @@ obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o
36# Toplevel Module Dependency 34# Toplevel Module Dependency
37obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o 35obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
38obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o 36obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o
39obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o 37obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o
40obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o 38obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o
41obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-midi-emul.o snd-seq-instr.o
42obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o 39obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o
43obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o 40obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o
44obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-seq-midi-emul.o snd-seq-instr.o
diff --git a/sound/core/seq/instr/Makefile b/sound/core/seq/instr/Makefile
deleted file mode 100644
index 608960364813..000000000000
--- a/sound/core/seq/instr/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
1#
2# Makefile for ALSA
3# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
4#
5
6snd-ainstr-fm-objs := ainstr_fm.o
7snd-ainstr-simple-objs := ainstr_simple.o
8snd-ainstr-gf1-objs := ainstr_gf1.o
9snd-ainstr-iw-objs := ainstr_iw.o
10
11#
12# this function returns:
13# "m" - CONFIG_SND_SEQUENCER is m
14# <empty string> - CONFIG_SND_SEQUENCER is undefined
15# otherwise parameter #1 value
16#
17sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
18
19# Toplevel Module Dependency
20obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-ainstr-fm.o
21obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-ainstr-fm.o
22obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-iw.o
23obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-ainstr-simple.o
diff --git a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c
deleted file mode 100644
index f80fab8f2ed1..000000000000
--- a/sound/core/seq/instr/ainstr_fm.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * FM (OPL2/3) Instrument routines
3 * Copyright (c) 2000 Uros Bizjak <uros@kss-loka.si>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <sound/core.h>
24#include <sound/ainstr_fm.h>
25#include <sound/initval.h>
26#include <asm/uaccess.h>
27
28MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
29MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support.");
30MODULE_LICENSE("GPL");
31
32static int snd_seq_fm_put(void *private_data, struct snd_seq_kinstr *instr,
33 char __user *instr_data, long len, int atomic, int cmd)
34{
35 struct fm_instrument *ip;
36 struct fm_xinstrument ix;
37 int idx;
38
39 if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
40 return -EINVAL;
41 /* copy instrument data */
42 if (len < (long)sizeof(ix))
43 return -EINVAL;
44 if (copy_from_user(&ix, instr_data, sizeof(ix)))
45 return -EFAULT;
46 if (ix.stype != FM_STRU_INSTR)
47 return -EINVAL;
48 ip = (struct fm_instrument *)KINSTR_DATA(instr);
49 ip->share_id[0] = le32_to_cpu(ix.share_id[0]);
50 ip->share_id[1] = le32_to_cpu(ix.share_id[1]);
51 ip->share_id[2] = le32_to_cpu(ix.share_id[2]);
52 ip->share_id[3] = le32_to_cpu(ix.share_id[3]);
53 ip->type = ix.type;
54 for (idx = 0; idx < 4; idx++) {
55 ip->op[idx].am_vib = ix.op[idx].am_vib;
56 ip->op[idx].ksl_level = ix.op[idx].ksl_level;
57 ip->op[idx].attack_decay = ix.op[idx].attack_decay;
58 ip->op[idx].sustain_release = ix.op[idx].sustain_release;
59 ip->op[idx].wave_select = ix.op[idx].wave_select;
60 }
61 for (idx = 0; idx < 2; idx++) {
62 ip->feedback_connection[idx] = ix.feedback_connection[idx];
63 }
64 ip->echo_delay = ix.echo_delay;
65 ip->echo_atten = ix.echo_atten;
66 ip->chorus_spread = ix.chorus_spread;
67 ip->trnsps = ix.trnsps;
68 ip->fix_dur = ix.fix_dur;
69 ip->modes = ix.modes;
70 ip->fix_key = ix.fix_key;
71 return 0;
72}
73
74static int snd_seq_fm_get(void *private_data, struct snd_seq_kinstr *instr,
75 char __user *instr_data, long len, int atomic,
76 int cmd)
77{
78 struct fm_instrument *ip;
79 struct fm_xinstrument ix;
80 int idx;
81
82 if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
83 return -EINVAL;
84 if (len < (long)sizeof(ix))
85 return -ENOMEM;
86 memset(&ix, 0, sizeof(ix));
87 ip = (struct fm_instrument *)KINSTR_DATA(instr);
88 ix.stype = FM_STRU_INSTR;
89 ix.share_id[0] = cpu_to_le32(ip->share_id[0]);
90 ix.share_id[1] = cpu_to_le32(ip->share_id[1]);
91 ix.share_id[2] = cpu_to_le32(ip->share_id[2]);
92 ix.share_id[3] = cpu_to_le32(ip->share_id[3]);
93 ix.type = ip->type;
94 for (idx = 0; idx < 4; idx++) {
95 ix.op[idx].am_vib = ip->op[idx].am_vib;
96 ix.op[idx].ksl_level = ip->op[idx].ksl_level;
97 ix.op[idx].attack_decay = ip->op[idx].attack_decay;
98 ix.op[idx].sustain_release = ip->op[idx].sustain_release;
99 ix.op[idx].wave_select = ip->op[idx].wave_select;
100 }
101 for (idx = 0; idx < 2; idx++) {
102 ix.feedback_connection[idx] = ip->feedback_connection[idx];
103 }
104 if (copy_to_user(instr_data, &ix, sizeof(ix)))
105 return -EFAULT;
106 ix.echo_delay = ip->echo_delay;
107 ix.echo_atten = ip->echo_atten;
108 ix.chorus_spread = ip->chorus_spread;
109 ix.trnsps = ip->trnsps;
110 ix.fix_dur = ip->fix_dur;
111 ix.modes = ip->modes;
112 ix.fix_key = ip->fix_key;
113 return 0;
114}
115
116static int snd_seq_fm_get_size(void *private_data, struct snd_seq_kinstr *instr,
117 long *size)
118{
119 *size = sizeof(struct fm_xinstrument);
120 return 0;
121}
122
123int snd_seq_fm_init(struct snd_seq_kinstr_ops *ops,
124 struct snd_seq_kinstr_ops *next)
125{
126 memset(ops, 0, sizeof(*ops));
127 // ops->private_data = private_data;
128 ops->add_len = sizeof(struct fm_instrument);
129 ops->instr_type = SNDRV_SEQ_INSTR_ID_OPL2_3;
130 ops->put = snd_seq_fm_put;
131 ops->get = snd_seq_fm_get;
132 ops->get_size = snd_seq_fm_get_size;
133 // ops->remove = snd_seq_fm_remove;
134 // ops->notify = snd_seq_fm_notify;
135 ops->next = next;
136 return 0;
137}
138
139/*
140 * Init part
141 */
142
143static int __init alsa_ainstr_fm_init(void)
144{
145 return 0;
146}
147
148static void __exit alsa_ainstr_fm_exit(void)
149{
150}
151
152module_init(alsa_ainstr_fm_init)
153module_exit(alsa_ainstr_fm_exit)
154
155EXPORT_SYMBOL(snd_seq_fm_init);
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
deleted file mode 100644
index 49400262b1eb..000000000000
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ /dev/null
@@ -1,359 +0,0 @@
1/*
2 * GF1 (GUS) Patch - Instrument routines
3 * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/ainstr_gf1.h>
26#include <sound/initval.h>
27#include <asm/uaccess.h>
28
29MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
30MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support.");
31MODULE_LICENSE("GPL");
32
33static unsigned int snd_seq_gf1_size(unsigned int size, unsigned int format)
34{
35 unsigned int result = size;
36
37 if (format & GF1_WAVE_16BIT)
38 result <<= 1;
39 if (format & GF1_WAVE_STEREO)
40 result <<= 1;
41 return format;
42}
43
44static int snd_seq_gf1_copy_wave_from_stream(struct snd_gf1_ops *ops,
45 struct gf1_instrument *ip,
46 char __user **data,
47 long *len,
48 int atomic)
49{
50 struct gf1_wave *wp, *prev;
51 struct gf1_xwave xp;
52 int err;
53 gfp_t gfp_mask;
54 unsigned int real_size;
55
56 gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
57 if (*len < (long)sizeof(xp))
58 return -EINVAL;
59 if (copy_from_user(&xp, *data, sizeof(xp)))
60 return -EFAULT;
61 *data += sizeof(xp);
62 *len -= sizeof(xp);
63 wp = kzalloc(sizeof(*wp), gfp_mask);
64 if (wp == NULL)
65 return -ENOMEM;
66 wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
67 wp->share_id[1] = le32_to_cpu(xp.share_id[1]);
68 wp->share_id[2] = le32_to_cpu(xp.share_id[2]);
69 wp->share_id[3] = le32_to_cpu(xp.share_id[3]);
70 wp->format = le32_to_cpu(xp.format);
71 wp->size = le32_to_cpu(xp.size);
72 wp->start = le32_to_cpu(xp.start);
73 wp->loop_start = le32_to_cpu(xp.loop_start);
74 wp->loop_end = le32_to_cpu(xp.loop_end);
75 wp->loop_repeat = le16_to_cpu(xp.loop_repeat);
76 wp->flags = xp.flags;
77 wp->sample_rate = le32_to_cpu(xp.sample_rate);
78 wp->low_frequency = le32_to_cpu(xp.low_frequency);
79 wp->high_frequency = le32_to_cpu(xp.high_frequency);
80 wp->root_frequency = le32_to_cpu(xp.root_frequency);
81 wp->tune = le16_to_cpu(xp.tune);
82 wp->balance = xp.balance;
83 memcpy(wp->envelope_rate, xp.envelope_rate, 6);
84 memcpy(wp->envelope_offset, xp.envelope_offset, 6);
85 wp->tremolo_sweep = xp.tremolo_sweep;
86 wp->tremolo_rate = xp.tremolo_rate;
87 wp->tremolo_depth = xp.tremolo_depth;
88 wp->vibrato_sweep = xp.vibrato_sweep;
89 wp->vibrato_rate = xp.vibrato_rate;
90 wp->vibrato_depth = xp.vibrato_depth;
91 wp->scale_frequency = le16_to_cpu(xp.scale_frequency);
92 wp->scale_factor = le16_to_cpu(xp.scale_factor);
93 real_size = snd_seq_gf1_size(wp->size, wp->format);
94 if ((long)real_size > *len) {
95 kfree(wp);
96 return -ENOMEM;
97 }
98 if (ops->put_sample) {
99 err = ops->put_sample(ops->private_data, wp,
100 *data, real_size, atomic);
101 if (err < 0) {
102 kfree(wp);
103 return err;
104 }
105 }
106 *data += real_size;
107 *len -= real_size;
108 prev = ip->wave;
109 if (prev) {
110 while (prev->next) prev = prev->next;
111 prev->next = wp;
112 } else {
113 ip->wave = wp;
114 }
115 return 0;
116}
117
118static void snd_seq_gf1_wave_free(struct snd_gf1_ops *ops,
119 struct gf1_wave *wave,
120 int atomic)
121{
122 if (ops->remove_sample)
123 ops->remove_sample(ops->private_data, wave, atomic);
124 kfree(wave);
125}
126
127static void snd_seq_gf1_instr_free(struct snd_gf1_ops *ops,
128 struct gf1_instrument *ip,
129 int atomic)
130{
131 struct gf1_wave *wave;
132
133 while ((wave = ip->wave) != NULL) {
134 ip->wave = wave->next;
135 snd_seq_gf1_wave_free(ops, wave, atomic);
136 }
137}
138
139static int snd_seq_gf1_put(void *private_data, struct snd_seq_kinstr *instr,
140 char __user *instr_data, long len, int atomic,
141 int cmd)
142{
143 struct snd_gf1_ops *ops = private_data;
144 struct gf1_instrument *ip;
145 struct gf1_xinstrument ix;
146 int err;
147 gfp_t gfp_mask;
148
149 if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
150 return -EINVAL;
151 gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
152 /* copy instrument data */
153 if (len < (long)sizeof(ix))
154 return -EINVAL;
155 if (copy_from_user(&ix, instr_data, sizeof(ix)))
156 return -EFAULT;
157 if (ix.stype != GF1_STRU_INSTR)
158 return -EINVAL;
159 instr_data += sizeof(ix);
160 len -= sizeof(ix);
161 ip = (struct gf1_instrument *)KINSTR_DATA(instr);
162 ip->exclusion = le16_to_cpu(ix.exclusion);
163 ip->exclusion_group = le16_to_cpu(ix.exclusion_group);
164 ip->effect1 = ix.effect1;
165 ip->effect1_depth = ix.effect1_depth;
166 ip->effect2 = ix.effect2;
167 ip->effect2_depth = ix.effect2_depth;
168 /* copy layers */
169 while (len > (long)sizeof(__u32)) {
170 __u32 stype;
171
172 if (copy_from_user(&stype, instr_data, sizeof(stype)))
173 return -EFAULT;
174 if (stype != GF1_STRU_WAVE) {
175 snd_seq_gf1_instr_free(ops, ip, atomic);
176 return -EINVAL;
177 }
178 err = snd_seq_gf1_copy_wave_from_stream(ops,
179 ip,
180 &instr_data,
181 &len,
182 atomic);
183 if (err < 0) {
184 snd_seq_gf1_instr_free(ops, ip, atomic);
185 return err;
186 }
187 }
188 return 0;
189}
190
191static int snd_seq_gf1_copy_wave_to_stream(struct snd_gf1_ops *ops,
192 struct gf1_instrument *ip,
193 char __user **data,
194 long *len,
195 int atomic)
196{
197 struct gf1_wave *wp;
198 struct gf1_xwave xp;
199 int err;
200 unsigned int real_size;
201
202 for (wp = ip->wave; wp; wp = wp->next) {
203 if (*len < (long)sizeof(xp))
204 return -ENOMEM;
205 memset(&xp, 0, sizeof(xp));
206 xp.stype = GF1_STRU_WAVE;
207 xp.share_id[0] = cpu_to_le32(wp->share_id[0]);
208 xp.share_id[1] = cpu_to_le32(wp->share_id[1]);
209 xp.share_id[2] = cpu_to_le32(wp->share_id[2]);
210 xp.share_id[3] = cpu_to_le32(wp->share_id[3]);
211 xp.format = cpu_to_le32(wp->format);
212 xp.size = cpu_to_le32(wp->size);
213 xp.start = cpu_to_le32(wp->start);
214 xp.loop_start = cpu_to_le32(wp->loop_start);
215 xp.loop_end = cpu_to_le32(wp->loop_end);
216 xp.loop_repeat = cpu_to_le32(wp->loop_repeat);
217 xp.flags = wp->flags;
218 xp.sample_rate = cpu_to_le32(wp->sample_rate);
219 xp.low_frequency = cpu_to_le32(wp->low_frequency);
220 xp.high_frequency = cpu_to_le32(wp->high_frequency);
221 xp.root_frequency = cpu_to_le32(wp->root_frequency);
222 xp.tune = cpu_to_le16(wp->tune);
223 xp.balance = wp->balance;
224 memcpy(xp.envelope_rate, wp->envelope_rate, 6);
225 memcpy(xp.envelope_offset, wp->envelope_offset, 6);
226 xp.tremolo_sweep = wp->tremolo_sweep;
227 xp.tremolo_rate = wp->tremolo_rate;
228 xp.tremolo_depth = wp->tremolo_depth;
229 xp.vibrato_sweep = wp->vibrato_sweep;
230 xp.vibrato_rate = wp->vibrato_rate;
231 xp.vibrato_depth = wp->vibrato_depth;
232 xp.scale_frequency = cpu_to_le16(wp->scale_frequency);
233 xp.scale_factor = cpu_to_le16(wp->scale_factor);
234 if (copy_to_user(*data, &xp, sizeof(xp)))
235 return -EFAULT;
236 *data += sizeof(xp);
237 *len -= sizeof(xp);
238 real_size = snd_seq_gf1_size(wp->size, wp->format);
239 if (*len < (long)real_size)
240 return -ENOMEM;
241 if (ops->get_sample) {
242 err = ops->get_sample(ops->private_data, wp,
243 *data, real_size, atomic);
244 if (err < 0)
245 return err;
246 }
247 *data += wp->size;
248 *len -= wp->size;
249 }
250 return 0;
251}
252
253static int snd_seq_gf1_get(void *private_data, struct snd_seq_kinstr *instr,
254 char __user *instr_data, long len, int atomic,
255 int cmd)
256{
257 struct snd_gf1_ops *ops = private_data;
258 struct gf1_instrument *ip;
259 struct gf1_xinstrument ix;
260
261 if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
262 return -EINVAL;
263 if (len < (long)sizeof(ix))
264 return -ENOMEM;
265 memset(&ix, 0, sizeof(ix));
266 ip = (struct gf1_instrument *)KINSTR_DATA(instr);
267 ix.stype = GF1_STRU_INSTR;
268 ix.exclusion = cpu_to_le16(ip->exclusion);
269 ix.exclusion_group = cpu_to_le16(ip->exclusion_group);
270 ix.effect1 = cpu_to_le16(ip->effect1);
271 ix.effect1_depth = cpu_to_le16(ip->effect1_depth);
272 ix.effect2 = ip->effect2;
273 ix.effect2_depth = ip->effect2_depth;
274 if (copy_to_user(instr_data, &ix, sizeof(ix)))
275 return -EFAULT;
276 instr_data += sizeof(ix);
277 len -= sizeof(ix);
278 return snd_seq_gf1_copy_wave_to_stream(ops,
279 ip,
280 &instr_data,
281 &len,
282 atomic);
283}
284
285static int snd_seq_gf1_get_size(void *private_data, struct snd_seq_kinstr *instr,
286 long *size)
287{
288 long result;
289 struct gf1_instrument *ip;
290 struct gf1_wave *wp;
291
292 *size = 0;
293 ip = (struct gf1_instrument *)KINSTR_DATA(instr);
294 result = sizeof(struct gf1_xinstrument);
295 for (wp = ip->wave; wp; wp = wp->next) {
296 result += sizeof(struct gf1_xwave);
297 result += wp->size;
298 }
299 *size = result;
300 return 0;
301}
302
303static int snd_seq_gf1_remove(void *private_data,
304 struct snd_seq_kinstr *instr,
305 int atomic)
306{
307 struct snd_gf1_ops *ops = private_data;
308 struct gf1_instrument *ip;
309
310 ip = (struct gf1_instrument *)KINSTR_DATA(instr);
311 snd_seq_gf1_instr_free(ops, ip, atomic);
312 return 0;
313}
314
315static void snd_seq_gf1_notify(void *private_data,
316 struct snd_seq_kinstr *instr,
317 int what)
318{
319 struct snd_gf1_ops *ops = private_data;
320
321 if (ops->notify)
322 ops->notify(ops->private_data, instr, what);
323}
324
325int snd_seq_gf1_init(struct snd_gf1_ops *ops,
326 void *private_data,
327 struct snd_seq_kinstr_ops *next)
328{
329 memset(ops, 0, sizeof(*ops));
330 ops->private_data = private_data;
331 ops->kops.private_data = ops;
332 ops->kops.add_len = sizeof(struct gf1_instrument);
333 ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_GUS_PATCH;
334 ops->kops.put = snd_seq_gf1_put;
335 ops->kops.get = snd_seq_gf1_get;
336 ops->kops.get_size = snd_seq_gf1_get_size;
337 ops->kops.remove = snd_seq_gf1_remove;
338 ops->kops.notify = snd_seq_gf1_notify;
339 ops->kops.next = next;
340 return 0;
341}
342
343/*
344 * Init part
345 */
346
347static int __init alsa_ainstr_gf1_init(void)
348{
349 return 0;
350}
351
352static void __exit alsa_ainstr_gf1_exit(void)
353{
354}
355
356module_init(alsa_ainstr_gf1_init)
357module_exit(alsa_ainstr_gf1_exit)
358
359EXPORT_SYMBOL(snd_seq_gf1_init);
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
deleted file mode 100644
index 6c40eb73fa9f..000000000000
--- a/sound/core/seq/instr/ainstr_iw.c
+++ /dev/null
@@ -1,623 +0,0 @@
1/*
2 * IWFFFF - AMD InterWave (tm) - Instrument routines
3 * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/ainstr_iw.h>
26#include <sound/initval.h>
27#include <asm/uaccess.h>
28
29MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
30MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support.");
31MODULE_LICENSE("GPL");
32
33static unsigned int snd_seq_iwffff_size(unsigned int size, unsigned int format)
34{
35 unsigned int result = size;
36
37 if (format & IWFFFF_WAVE_16BIT)
38 result <<= 1;
39 if (format & IWFFFF_WAVE_STEREO)
40 result <<= 1;
41 return result;
42}
43
44static void snd_seq_iwffff_copy_lfo_from_stream(struct iwffff_lfo *fp,
45 struct iwffff_xlfo *fx)
46{
47 fp->freq = le16_to_cpu(fx->freq);
48 fp->depth = le16_to_cpu(fx->depth);
49 fp->sweep = le16_to_cpu(fx->sweep);
50 fp->shape = fx->shape;
51 fp->delay = fx->delay;
52}
53
54static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype,
55 struct iwffff_layer *lp,
56 struct iwffff_env *ep,
57 struct iwffff_xenv *ex,
58 char __user **data,
59 long *len,
60 gfp_t gfp_mask)
61{
62 __u32 stype;
63 struct iwffff_env_record *rp, *rp_last;
64 struct iwffff_xenv_record rx;
65 struct iwffff_env_point *pp;
66 struct iwffff_xenv_point px;
67 int points_size, idx;
68
69 ep->flags = ex->flags;
70 ep->mode = ex->mode;
71 ep->index = ex->index;
72 rp_last = NULL;
73 while (1) {
74 if (*len < (long)sizeof(__u32))
75 return -EINVAL;
76 if (copy_from_user(&stype, *data, sizeof(stype)))
77 return -EFAULT;
78 if (stype == IWFFFF_STRU_WAVE)
79 return 0;
80 if (req_stype != stype) {
81 if (stype == IWFFFF_STRU_ENV_RECP ||
82 stype == IWFFFF_STRU_ENV_RECV)
83 return 0;
84 }
85 if (*len < (long)sizeof(rx))
86 return -EINVAL;
87 if (copy_from_user(&rx, *data, sizeof(rx)))
88 return -EFAULT;
89 *data += sizeof(rx);
90 *len -= sizeof(rx);
91 points_size = (le16_to_cpu(rx.nattack) + le16_to_cpu(rx.nrelease)) * 2 * sizeof(__u16);
92 if (points_size > *len)
93 return -EINVAL;
94 rp = kzalloc(sizeof(*rp) + points_size, gfp_mask);
95 if (rp == NULL)
96 return -ENOMEM;
97 rp->nattack = le16_to_cpu(rx.nattack);
98 rp->nrelease = le16_to_cpu(rx.nrelease);
99 rp->sustain_offset = le16_to_cpu(rx.sustain_offset);
100 rp->sustain_rate = le16_to_cpu(rx.sustain_rate);
101 rp->release_rate = le16_to_cpu(rx.release_rate);
102 rp->hirange = rx.hirange;
103 pp = (struct iwffff_env_point *)(rp + 1);
104 for (idx = 0; idx < rp->nattack + rp->nrelease; idx++) {
105 if (copy_from_user(&px, *data, sizeof(px)))
106 return -EFAULT;
107 *data += sizeof(px);
108 *len -= sizeof(px);
109 pp->offset = le16_to_cpu(px.offset);
110 pp->rate = le16_to_cpu(px.rate);
111 }
112 if (ep->record == NULL) {
113 ep->record = rp;
114 } else {
115 rp_last = rp;
116 }
117 rp_last = rp;
118 }
119 return 0;
120}
121
122static int snd_seq_iwffff_copy_wave_from_stream(struct snd_iwffff_ops *ops,
123 struct iwffff_layer *lp,
124 char __user **data,
125 long *len,
126 int atomic)
127{
128 struct iwffff_wave *wp, *prev;
129 struct iwffff_xwave xp;
130 int err;
131 gfp_t gfp_mask;
132 unsigned int real_size;
133
134 gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
135 if (*len < (long)sizeof(xp))
136 return -EINVAL;
137 if (copy_from_user(&xp, *data, sizeof(xp)))
138 return -EFAULT;
139 *data += sizeof(xp);
140 *len -= sizeof(xp);
141 wp = kzalloc(sizeof(*wp), gfp_mask);
142 if (wp == NULL)
143 return -ENOMEM;
144 wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
145 wp->share_id[1] = le32_to_cpu(xp.share_id[1]);
146 wp->share_id[2] = le32_to_cpu(xp.share_id[2]);
147 wp->share_id[3] = le32_to_cpu(xp.share_id[3]);
148 wp->format = le32_to_cpu(xp.format);
149 wp->address.memory = le32_to_cpu(xp.offset);
150 wp->size = le32_to_cpu(xp.size);
151 wp->start = le32_to_cpu(xp.start);
152 wp->loop_start = le32_to_cpu(xp.loop_start);
153 wp->loop_end = le32_to_cpu(xp.loop_end);
154 wp->loop_repeat = le16_to_cpu(xp.loop_repeat);
155 wp->sample_ratio = le32_to_cpu(xp.sample_ratio);
156 wp->attenuation = xp.attenuation;
157 wp->low_note = xp.low_note;
158 wp->high_note = xp.high_note;
159 real_size = snd_seq_iwffff_size(wp->size, wp->format);
160 if (!(wp->format & IWFFFF_WAVE_ROM)) {
161 if ((long)real_size > *len) {
162 kfree(wp);
163 return -ENOMEM;
164 }
165 }
166 if (ops->put_sample) {
167 err = ops->put_sample(ops->private_data, wp,
168 *data, real_size, atomic);
169 if (err < 0) {
170 kfree(wp);
171 return err;
172 }
173 }
174 if (!(wp->format & IWFFFF_WAVE_ROM)) {
175 *data += real_size;
176 *len -= real_size;
177 }
178 prev = lp->wave;
179 if (prev) {
180 while (prev->next) prev = prev->next;
181 prev->next = wp;
182 } else {
183 lp->wave = wp;
184 }
185 return 0;
186}
187
188static void snd_seq_iwffff_env_free(struct snd_iwffff_ops *ops,
189 struct iwffff_env *env,
190 int atomic)
191{
192 struct iwffff_env_record *rec;
193
194 while ((rec = env->record) != NULL) {
195 env->record = rec->next;
196 kfree(rec);
197 }
198}
199
200static void snd_seq_iwffff_wave_free(struct snd_iwffff_ops *ops,
201 struct iwffff_wave *wave,
202 int atomic)
203{
204 if (ops->remove_sample)
205 ops->remove_sample(ops->private_data, wave, atomic);
206 kfree(wave);
207}
208
209static void snd_seq_iwffff_instr_free(struct snd_iwffff_ops *ops,
210 struct iwffff_instrument *ip,
211 int atomic)
212{
213 struct iwffff_layer *layer;
214 struct iwffff_wave *wave;
215
216 while ((layer = ip->layer) != NULL) {
217 ip->layer = layer->next;
218 snd_seq_iwffff_env_free(ops, &layer->penv, atomic);
219 snd_seq_iwffff_env_free(ops, &layer->venv, atomic);
220 while ((wave = layer->wave) != NULL) {
221 layer->wave = wave->next;
222 snd_seq_iwffff_wave_free(ops, wave, atomic);
223 }
224 kfree(layer);
225 }
226}
227
228static int snd_seq_iwffff_put(void *private_data, struct snd_seq_kinstr *instr,
229 char __user *instr_data, long len, int atomic,
230 int cmd)
231{
232 struct snd_iwffff_ops *ops = private_data;
233 struct iwffff_instrument *ip;
234 struct iwffff_xinstrument ix;
235 struct iwffff_layer *lp, *prev_lp;
236 struct iwffff_xlayer lx;
237 int err;
238 gfp_t gfp_mask;
239
240 if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
241 return -EINVAL;
242 gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
243 /* copy instrument data */
244 if (len < (long)sizeof(ix))
245 return -EINVAL;
246 if (copy_from_user(&ix, instr_data, sizeof(ix)))
247 return -EFAULT;
248 if (ix.stype != IWFFFF_STRU_INSTR)
249 return -EINVAL;
250 instr_data += sizeof(ix);
251 len -= sizeof(ix);
252 ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
253 ip->exclusion = le16_to_cpu(ix.exclusion);
254 ip->layer_type = le16_to_cpu(ix.layer_type);
255 ip->exclusion_group = le16_to_cpu(ix.exclusion_group);
256 ip->effect1 = ix.effect1;
257 ip->effect1_depth = ix.effect1_depth;
258 ip->effect2 = ix.effect2;
259 ip->effect2_depth = ix.effect2_depth;
260 /* copy layers */
261 prev_lp = NULL;
262 while (len > 0) {
263 if (len < (long)sizeof(struct iwffff_xlayer)) {
264 snd_seq_iwffff_instr_free(ops, ip, atomic);
265 return -EINVAL;
266 }
267 if (copy_from_user(&lx, instr_data, sizeof(lx)))
268 return -EFAULT;
269 instr_data += sizeof(lx);
270 len -= sizeof(lx);
271 if (lx.stype != IWFFFF_STRU_LAYER) {
272 snd_seq_iwffff_instr_free(ops, ip, atomic);
273 return -EINVAL;
274 }
275 lp = kzalloc(sizeof(*lp), gfp_mask);
276 if (lp == NULL) {
277 snd_seq_iwffff_instr_free(ops, ip, atomic);
278 return -ENOMEM;
279 }
280 if (prev_lp) {
281 prev_lp->next = lp;
282 } else {
283 ip->layer = lp;
284 }
285 prev_lp = lp;
286 lp->flags = lx.flags;
287 lp->velocity_mode = lx.velocity_mode;
288 lp->layer_event = lx.layer_event;
289 lp->low_range = lx.low_range;
290 lp->high_range = lx.high_range;
291 lp->pan = lx.pan;
292 lp->pan_freq_scale = lx.pan_freq_scale;
293 lp->attenuation = lx.attenuation;
294 snd_seq_iwffff_copy_lfo_from_stream(&lp->tremolo, &lx.tremolo);
295 snd_seq_iwffff_copy_lfo_from_stream(&lp->vibrato, &lx.vibrato);
296 lp->freq_scale = le16_to_cpu(lx.freq_scale);
297 lp->freq_center = lx.freq_center;
298 err = snd_seq_iwffff_copy_env_from_stream(IWFFFF_STRU_ENV_RECP,
299 lp,
300 &lp->penv, &lx.penv,
301 &instr_data, &len,
302 gfp_mask);
303 if (err < 0) {
304 snd_seq_iwffff_instr_free(ops, ip, atomic);
305 return err;
306 }
307 err = snd_seq_iwffff_copy_env_from_stream(IWFFFF_STRU_ENV_RECV,
308 lp,
309 &lp->venv, &lx.venv,
310 &instr_data, &len,
311 gfp_mask);
312 if (err < 0) {
313 snd_seq_iwffff_instr_free(ops, ip, atomic);
314 return err;
315 }
316 while (len > (long)sizeof(__u32)) {
317 __u32 stype;
318
319 if (copy_from_user(&stype, instr_data, sizeof(stype)))
320 return -EFAULT;
321 if (stype != IWFFFF_STRU_WAVE)
322 break;
323 err = snd_seq_iwffff_copy_wave_from_stream(ops,
324 lp,
325 &instr_data,
326 &len,
327 atomic);
328 if (err < 0) {
329 snd_seq_iwffff_instr_free(ops, ip, atomic);
330 return err;
331 }
332 }
333 }
334 return 0;
335}
336
337static void snd_seq_iwffff_copy_lfo_to_stream(struct iwffff_xlfo *fx,
338 struct iwffff_lfo *fp)
339{
340 fx->freq = cpu_to_le16(fp->freq);
341 fx->depth = cpu_to_le16(fp->depth);
342 fx->sweep = cpu_to_le16(fp->sweep);
343 fp->shape = fx->shape;
344 fp->delay = fx->delay;
345}
346
347static int snd_seq_iwffff_copy_env_to_stream(__u32 req_stype,
348 struct iwffff_layer *lp,
349 struct iwffff_xenv *ex,
350 struct iwffff_env *ep,
351 char __user **data,
352 long *len)
353{
354 struct iwffff_env_record *rp;
355 struct iwffff_xenv_record rx;
356 struct iwffff_env_point *pp;
357 struct iwffff_xenv_point px;
358 int points_size, idx;
359
360 ex->flags = ep->flags;
361 ex->mode = ep->mode;
362 ex->index = ep->index;
363 for (rp = ep->record; rp; rp = rp->next) {
364 if (*len < (long)sizeof(rx))
365 return -ENOMEM;
366 memset(&rx, 0, sizeof(rx));
367 rx.stype = req_stype;
368 rx.nattack = cpu_to_le16(rp->nattack);
369 rx.nrelease = cpu_to_le16(rp->nrelease);
370 rx.sustain_offset = cpu_to_le16(rp->sustain_offset);
371 rx.sustain_rate = cpu_to_le16(rp->sustain_rate);
372 rx.release_rate = cpu_to_le16(rp->release_rate);
373 rx.hirange = cpu_to_le16(rp->hirange);
374 if (copy_to_user(*data, &rx, sizeof(rx)))
375 return -EFAULT;
376 *data += sizeof(rx);
377 *len -= sizeof(rx);
378 points_size = (rp->nattack + rp->nrelease) * 2 * sizeof(__u16);
379 if (*len < points_size)
380 return -ENOMEM;
381 pp = (struct iwffff_env_point *)(rp + 1);
382 for (idx = 0; idx < rp->nattack + rp->nrelease; idx++) {
383 px.offset = cpu_to_le16(pp->offset);
384 px.rate = cpu_to_le16(pp->rate);
385 if (copy_to_user(*data, &px, sizeof(px)))
386 return -EFAULT;
387 *data += sizeof(px);
388 *len -= sizeof(px);
389 }
390 }
391 return 0;
392}
393
394static int snd_seq_iwffff_copy_wave_to_stream(struct snd_iwffff_ops *ops,
395 struct iwffff_layer *lp,
396 char __user **data,
397 long *len,
398 int atomic)
399{
400 struct iwffff_wave *wp;
401 struct iwffff_xwave xp;
402 int err;
403 unsigned int real_size;
404
405 for (wp = lp->wave; wp; wp = wp->next) {
406 if (*len < (long)sizeof(xp))
407 return -ENOMEM;
408 memset(&xp, 0, sizeof(xp));
409 xp.stype = IWFFFF_STRU_WAVE;
410 xp.share_id[0] = cpu_to_le32(wp->share_id[0]);
411 xp.share_id[1] = cpu_to_le32(wp->share_id[1]);
412 xp.share_id[2] = cpu_to_le32(wp->share_id[2]);
413 xp.share_id[3] = cpu_to_le32(wp->share_id[3]);
414 xp.format = cpu_to_le32(wp->format);
415 if (wp->format & IWFFFF_WAVE_ROM)
416 xp.offset = cpu_to_le32(wp->address.memory);
417 xp.size = cpu_to_le32(wp->size);
418 xp.start = cpu_to_le32(wp->start);
419 xp.loop_start = cpu_to_le32(wp->loop_start);
420 xp.loop_end = cpu_to_le32(wp->loop_end);
421 xp.loop_repeat = cpu_to_le32(wp->loop_repeat);
422 xp.sample_ratio = cpu_to_le32(wp->sample_ratio);
423 xp.attenuation = wp->attenuation;
424 xp.low_note = wp->low_note;
425 xp.high_note = wp->high_note;
426 if (copy_to_user(*data, &xp, sizeof(xp)))
427 return -EFAULT;
428 *data += sizeof(xp);
429 *len -= sizeof(xp);
430 real_size = snd_seq_iwffff_size(wp->size, wp->format);
431 if (!(wp->format & IWFFFF_WAVE_ROM)) {
432 if (*len < (long)real_size)
433 return -ENOMEM;
434 }
435 if (ops->get_sample) {
436 err = ops->get_sample(ops->private_data, wp,
437 *data, real_size, atomic);
438 if (err < 0)
439 return err;
440 }
441 if (!(wp->format & IWFFFF_WAVE_ROM)) {
442 *data += real_size;
443 *len -= real_size;
444 }
445 }
446 return 0;
447}
448
449static int snd_seq_iwffff_get(void *private_data, struct snd_seq_kinstr *instr,
450 char __user *instr_data, long len, int atomic, int cmd)
451{
452 struct snd_iwffff_ops *ops = private_data;
453 struct iwffff_instrument *ip;
454 struct iwffff_xinstrument ix;
455 struct iwffff_layer *lp;
456 struct iwffff_xlayer lx;
457 char __user *layer_instr_data;
458 int err;
459
460 if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
461 return -EINVAL;
462 if (len < (long)sizeof(ix))
463 return -ENOMEM;
464 memset(&ix, 0, sizeof(ix));
465 ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
466 ix.stype = IWFFFF_STRU_INSTR;
467 ix.exclusion = cpu_to_le16(ip->exclusion);
468 ix.layer_type = cpu_to_le16(ip->layer_type);
469 ix.exclusion_group = cpu_to_le16(ip->exclusion_group);
470 ix.effect1 = cpu_to_le16(ip->effect1);
471 ix.effect1_depth = cpu_to_le16(ip->effect1_depth);
472 ix.effect2 = ip->effect2;
473 ix.effect2_depth = ip->effect2_depth;
474 if (copy_to_user(instr_data, &ix, sizeof(ix)))
475 return -EFAULT;
476 instr_data += sizeof(ix);
477 len -= sizeof(ix);
478 for (lp = ip->layer; lp; lp = lp->next) {
479 if (len < (long)sizeof(lx))
480 return -ENOMEM;
481 memset(&lx, 0, sizeof(lx));
482 lx.stype = IWFFFF_STRU_LAYER;
483 lx.flags = lp->flags;
484 lx.velocity_mode = lp->velocity_mode;
485 lx.layer_event = lp->layer_event;
486 lx.low_range = lp->low_range;
487 lx.high_range = lp->high_range;
488 lx.pan = lp->pan;
489 lx.pan_freq_scale = lp->pan_freq_scale;
490 lx.attenuation = lp->attenuation;
491 snd_seq_iwffff_copy_lfo_to_stream(&lx.tremolo, &lp->tremolo);
492 snd_seq_iwffff_copy_lfo_to_stream(&lx.vibrato, &lp->vibrato);
493 layer_instr_data = instr_data;
494 instr_data += sizeof(lx);
495 len -= sizeof(lx);
496 err = snd_seq_iwffff_copy_env_to_stream(IWFFFF_STRU_ENV_RECP,
497 lp,
498 &lx.penv, &lp->penv,
499 &instr_data, &len);
500 if (err < 0)
501 return err;
502 err = snd_seq_iwffff_copy_env_to_stream(IWFFFF_STRU_ENV_RECV,
503 lp,
504 &lx.venv, &lp->venv,
505 &instr_data, &len);
506 if (err < 0)
507 return err;
508 /* layer structure updating is now finished */
509 if (copy_to_user(layer_instr_data, &lx, sizeof(lx)))
510 return -EFAULT;
511 err = snd_seq_iwffff_copy_wave_to_stream(ops,
512 lp,
513 &instr_data,
514 &len,
515 atomic);
516 if (err < 0)
517 return err;
518 }
519 return 0;
520}
521
522static long snd_seq_iwffff_env_size_in_stream(struct iwffff_env *ep)
523{
524 long result = 0;
525 struct iwffff_env_record *rp;
526
527 for (rp = ep->record; rp; rp = rp->next) {
528 result += sizeof(struct iwffff_xenv_record);
529 result += (rp->nattack + rp->nrelease) * 2 * sizeof(__u16);
530 }
531 return 0;
532}
533
534static long snd_seq_iwffff_wave_size_in_stream(struct iwffff_layer *lp)
535{
536 long result = 0;
537 struct iwffff_wave *wp;
538
539 for (wp = lp->wave; wp; wp = wp->next) {
540 result += sizeof(struct iwffff_xwave);
541 if (!(wp->format & IWFFFF_WAVE_ROM))
542 result += wp->size;
543 }
544 return result;
545}
546
547static int snd_seq_iwffff_get_size(void *private_data, struct snd_seq_kinstr *instr,
548 long *size)
549{
550 long result;
551 struct iwffff_instrument *ip;
552 struct iwffff_layer *lp;
553
554 *size = 0;
555 ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
556 result = sizeof(struct iwffff_xinstrument);
557 for (lp = ip->layer; lp; lp = lp->next) {
558 result += sizeof(struct iwffff_xlayer);
559 result += snd_seq_iwffff_env_size_in_stream(&lp->penv);
560 result += snd_seq_iwffff_env_size_in_stream(&lp->venv);
561 result += snd_seq_iwffff_wave_size_in_stream(lp);
562 }
563 *size = result;
564 return 0;
565}
566
567static int snd_seq_iwffff_remove(void *private_data,
568 struct snd_seq_kinstr *instr,
569 int atomic)
570{
571 struct snd_iwffff_ops *ops = private_data;
572 struct iwffff_instrument *ip;
573
574 ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
575 snd_seq_iwffff_instr_free(ops, ip, atomic);
576 return 0;
577}
578
579static void snd_seq_iwffff_notify(void *private_data,
580 struct snd_seq_kinstr *instr,
581 int what)
582{
583 struct snd_iwffff_ops *ops = private_data;
584
585 if (ops->notify)
586 ops->notify(ops->private_data, instr, what);
587}
588
589int snd_seq_iwffff_init(struct snd_iwffff_ops *ops,
590 void *private_data,
591 struct snd_seq_kinstr_ops *next)
592{
593 memset(ops, 0, sizeof(*ops));
594 ops->private_data = private_data;
595 ops->kops.private_data = ops;
596 ops->kops.add_len = sizeof(struct iwffff_instrument);
597 ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_INTERWAVE;
598 ops->kops.put = snd_seq_iwffff_put;
599 ops->kops.get = snd_seq_iwffff_get;
600 ops->kops.get_size = snd_seq_iwffff_get_size;
601 ops->kops.remove = snd_seq_iwffff_remove;
602 ops->kops.notify = snd_seq_iwffff_notify;
603 ops->kops.next = next;
604 return 0;
605}
606
607/*
608 * Init part
609 */
610
611static int __init alsa_ainstr_iw_init(void)
612{
613 return 0;
614}
615
616static void __exit alsa_ainstr_iw_exit(void)
617{
618}
619
620module_init(alsa_ainstr_iw_init)
621module_exit(alsa_ainstr_iw_exit)
622
623EXPORT_SYMBOL(snd_seq_iwffff_init);
diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
deleted file mode 100644
index 78f68bee24fe..000000000000
--- a/sound/core/seq/instr/ainstr_simple.c
+++ /dev/null
@@ -1,215 +0,0 @@
1/*
2 * Simple (MOD player) - Instrument routines
3 * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/ainstr_simple.h>
26#include <sound/initval.h>
27#include <asm/uaccess.h>
28
29MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
30MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support.");
31MODULE_LICENSE("GPL");
32
33static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format)
34{
35 unsigned int result = size;
36
37 if (format & SIMPLE_WAVE_16BIT)
38 result <<= 1;
39 if (format & SIMPLE_WAVE_STEREO)
40 result <<= 1;
41 return result;
42}
43
44static void snd_seq_simple_instr_free(struct snd_simple_ops *ops,
45 struct simple_instrument *ip,
46 int atomic)
47{
48 if (ops->remove_sample)
49 ops->remove_sample(ops->private_data, ip, atomic);
50}
51
52static int snd_seq_simple_put(void *private_data, struct snd_seq_kinstr *instr,
53 char __user *instr_data, long len,
54 int atomic, int cmd)
55{
56 struct snd_simple_ops *ops = private_data;
57 struct simple_instrument *ip;
58 struct simple_xinstrument ix;
59 int err;
60 gfp_t gfp_mask;
61 unsigned int real_size;
62
63 if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
64 return -EINVAL;
65 gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
66 /* copy instrument data */
67 if (len < (long)sizeof(ix))
68 return -EINVAL;
69 if (copy_from_user(&ix, instr_data, sizeof(ix)))
70 return -EFAULT;
71 if (ix.stype != SIMPLE_STRU_INSTR)
72 return -EINVAL;
73 instr_data += sizeof(ix);
74 len -= sizeof(ix);
75 ip = (struct simple_instrument *)KINSTR_DATA(instr);
76 ip->share_id[0] = le32_to_cpu(ix.share_id[0]);
77 ip->share_id[1] = le32_to_cpu(ix.share_id[1]);
78 ip->share_id[2] = le32_to_cpu(ix.share_id[2]);
79 ip->share_id[3] = le32_to_cpu(ix.share_id[3]);
80 ip->format = le32_to_cpu(ix.format);
81 ip->size = le32_to_cpu(ix.size);
82 ip->start = le32_to_cpu(ix.start);
83 ip->loop_start = le32_to_cpu(ix.loop_start);
84 ip->loop_end = le32_to_cpu(ix.loop_end);
85 ip->loop_repeat = le16_to_cpu(ix.loop_repeat);
86 ip->effect1 = ix.effect1;
87 ip->effect1_depth = ix.effect1_depth;
88 ip->effect2 = ix.effect2;
89 ip->effect2_depth = ix.effect2_depth;
90 real_size = snd_seq_simple_size(ip->size, ip->format);
91 if (len < (long)real_size)
92 return -EINVAL;
93 if (ops->put_sample) {
94 err = ops->put_sample(ops->private_data, ip,
95 instr_data, real_size, atomic);
96 if (err < 0)
97 return err;
98 }
99 return 0;
100}
101
102static int snd_seq_simple_get(void *private_data, struct snd_seq_kinstr *instr,
103 char __user *instr_data, long len,
104 int atomic, int cmd)
105{
106 struct snd_simple_ops *ops = private_data;
107 struct simple_instrument *ip;
108 struct simple_xinstrument ix;
109 int err;
110 unsigned int real_size;
111
112 if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
113 return -EINVAL;
114 if (len < (long)sizeof(ix))
115 return -ENOMEM;
116 memset(&ix, 0, sizeof(ix));
117 ip = (struct simple_instrument *)KINSTR_DATA(instr);
118 ix.stype = SIMPLE_STRU_INSTR;
119 ix.share_id[0] = cpu_to_le32(ip->share_id[0]);
120 ix.share_id[1] = cpu_to_le32(ip->share_id[1]);
121 ix.share_id[2] = cpu_to_le32(ip->share_id[2]);
122 ix.share_id[3] = cpu_to_le32(ip->share_id[3]);
123 ix.format = cpu_to_le32(ip->format);
124 ix.size = cpu_to_le32(ip->size);
125 ix.start = cpu_to_le32(ip->start);
126 ix.loop_start = cpu_to_le32(ip->loop_start);
127 ix.loop_end = cpu_to_le32(ip->loop_end);
128 ix.loop_repeat = cpu_to_le32(ip->loop_repeat);
129 ix.effect1 = cpu_to_le16(ip->effect1);
130 ix.effect1_depth = cpu_to_le16(ip->effect1_depth);
131 ix.effect2 = ip->effect2;
132 ix.effect2_depth = ip->effect2_depth;
133 if (copy_to_user(instr_data, &ix, sizeof(ix)))
134 return -EFAULT;
135 instr_data += sizeof(ix);
136 len -= sizeof(ix);
137 real_size = snd_seq_simple_size(ip->size, ip->format);
138 if (len < (long)real_size)
139 return -ENOMEM;
140 if (ops->get_sample) {
141 err = ops->get_sample(ops->private_data, ip,
142 instr_data, real_size, atomic);
143 if (err < 0)
144 return err;
145 }
146 return 0;
147}
148
149static int snd_seq_simple_get_size(void *private_data, struct snd_seq_kinstr *instr,
150 long *size)
151{
152 struct simple_instrument *ip;
153
154 ip = (struct simple_instrument *)KINSTR_DATA(instr);
155 *size = sizeof(struct simple_xinstrument) + snd_seq_simple_size(ip->size, ip->format);
156 return 0;
157}
158
159static int snd_seq_simple_remove(void *private_data,
160 struct snd_seq_kinstr *instr,
161 int atomic)
162{
163 struct snd_simple_ops *ops = private_data;
164 struct simple_instrument *ip;
165
166 ip = (struct simple_instrument *)KINSTR_DATA(instr);
167 snd_seq_simple_instr_free(ops, ip, atomic);
168 return 0;
169}
170
171static void snd_seq_simple_notify(void *private_data,
172 struct snd_seq_kinstr *instr,
173 int what)
174{
175 struct snd_simple_ops *ops = private_data;
176
177 if (ops->notify)
178 ops->notify(ops->private_data, instr, what);
179}
180
181int snd_seq_simple_init(struct snd_simple_ops *ops,
182 void *private_data,
183 struct snd_seq_kinstr_ops *next)
184{
185 memset(ops, 0, sizeof(*ops));
186 ops->private_data = private_data;
187 ops->kops.private_data = ops;
188 ops->kops.add_len = sizeof(struct simple_instrument);
189 ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE;
190 ops->kops.put = snd_seq_simple_put;
191 ops->kops.get = snd_seq_simple_get;
192 ops->kops.get_size = snd_seq_simple_get_size;
193 ops->kops.remove = snd_seq_simple_remove;
194 ops->kops.notify = snd_seq_simple_notify;
195 ops->kops.next = next;
196 return 0;
197}
198
199/*
200 * Init part
201 */
202
203static int __init alsa_ainstr_simple_init(void)
204{
205 return 0;
206}
207
208static void __exit alsa_ainstr_simple_exit(void)
209{
210}
211
212module_init(alsa_ainstr_simple_init)
213module_exit(alsa_ainstr_simple_exit)
214
215EXPORT_SYMBOL(snd_seq_simple_init);
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index bc0992398461..777796e94490 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -20,7 +20,6 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
26#include <linux/mutex.h> 25#include <linux/mutex.h>
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index 9a8567c928ec..bf8d2b4cb15e 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -21,7 +21,6 @@
21#ifndef __SEQ_OSS_DEVICE_H 21#ifndef __SEQ_OSS_DEVICE_H
22#define __SEQ_OSS_DEVICE_H 22#define __SEQ_OSS_DEVICE_H
23 23
24#include <sound/driver.h>
25#include <linux/time.h> 24#include <linux/time.h>
26#include <linux/wait.h> 25#include <linux/wait.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 1878208a8026..ee0f8405ab35 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
25#include <sound/core.h> 24#include <sound/core.h>
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 2e3fa25ab19f..f97c1ba43a28 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <sound/core.h> 26#include <sound/core.h>
@@ -130,8 +129,6 @@ static struct snd_seq_client *clientptr(int clientid)
130 return clienttab[clientid]; 129 return clienttab[clientid];
131} 130}
132 131
133extern int seq_client_load[];
134
135struct snd_seq_client *snd_seq_client_use_ptr(int clientid) 132struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
136{ 133{
137 unsigned long flags; 134 unsigned long flags;
@@ -966,8 +963,7 @@ static int check_event_type_and_length(struct snd_seq_event *ev)
966 return -EINVAL; 963 return -EINVAL;
967 break; 964 break;
968 case SNDRV_SEQ_EVENT_LENGTH_VARUSR: 965 case SNDRV_SEQ_EVENT_LENGTH_VARUSR:
969 if (! snd_seq_ev_is_instr_type(ev) || 966 if (! snd_seq_ev_is_direct(ev))
970 ! snd_seq_ev_is_direct(ev))
971 return -EINVAL; 967 return -EINVAL;
972 break; 968 break;
973 } 969 }
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
index 5e04e20e239f..20f0a725ec7d 100644
--- a/sound/core/seq/seq_clientmgr.h
+++ b/sound/core/seq/seq_clientmgr.h
@@ -98,4 +98,6 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table
98int snd_seq_client_notify_subscription(int client, int port, 98int snd_seq_client_notify_subscription(int client, int port,
99 struct snd_seq_port_subscribe *info, int evtype); 99 struct snd_seq_port_subscribe *info, int evtype);
100 100
101extern int seq_client_load[15];
102
101#endif 103#endif
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 37852cdace76..155dc7da4722 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -36,7 +36,6 @@
36 * 36 *
37 */ 37 */
38 38
39#include <sound/driver.h>
40#include <linux/init.h> 39#include <linux/init.h>
41#include <sound/core.h> 40#include <sound/core.h>
42#include <sound/info.h> 41#include <sound/info.h>
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index e55488d1237c..f3bdc54b429a 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <sound/driver.h>
22#include <linux/init.h> 21#include <linux/init.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 6b055aed7a4b..3a94ed021bd9 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <sound/core.h> 22#include <sound/core.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include "seq_fifo.h" 24#include "seq_fifo.h"
diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c
index 8a7fe5cca1c9..201f8106ffdd 100644
--- a/sound/core/seq/seq_info.c
+++ b/sound/core/seq/seq_info.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <sound/core.h> 23#include <sound/core.h>
25 24
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
deleted file mode 100644
index 9a6fd56c9109..000000000000
--- a/sound/core/seq/seq_instr.c
+++ /dev/null
@@ -1,655 +0,0 @@
1/*
2 * Generic Instrument routines for ALSA sequencer
3 * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include "seq_clientmgr.h"
26#include <sound/seq_instr.h>
27#include <sound/initval.h>
28
29MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
30MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer instrument library.");
31MODULE_LICENSE("GPL");
32
33
34static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list)
35{
36 if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
37 spin_lock_irqsave(&list->ops_lock, list->ops_flags);
38 } else {
39 mutex_lock(&list->ops_mutex);
40 }
41}
42
43static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list)
44{
45 if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
46 spin_unlock_irqrestore(&list->ops_lock, list->ops_flags);
47 } else {
48 mutex_unlock(&list->ops_mutex);
49 }
50}
51
52static struct snd_seq_kinstr *snd_seq_instr_new(int add_len, int atomic)
53{
54 struct snd_seq_kinstr *instr;
55
56 instr = kzalloc(sizeof(struct snd_seq_kinstr) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
57 if (instr == NULL)
58 return NULL;
59 instr->add_len = add_len;
60 return instr;
61}
62
63static int snd_seq_instr_free(struct snd_seq_kinstr *instr, int atomic)
64{
65 int result = 0;
66
67 if (instr == NULL)
68 return -EINVAL;
69 if (instr->ops && instr->ops->remove)
70 result = instr->ops->remove(instr->ops->private_data, instr, 1);
71 if (!result)
72 kfree(instr);
73 return result;
74}
75
76struct snd_seq_kinstr_list *snd_seq_instr_list_new(void)
77{
78 struct snd_seq_kinstr_list *list;
79
80 list = kzalloc(sizeof(struct snd_seq_kinstr_list), GFP_KERNEL);
81 if (list == NULL)
82 return NULL;
83 spin_lock_init(&list->lock);
84 spin_lock_init(&list->ops_lock);
85 mutex_init(&list->ops_mutex);
86 list->owner = -1;
87 return list;
88}
89
90void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr)
91{
92 struct snd_seq_kinstr_list *list;
93 struct snd_seq_kinstr *instr;
94 struct snd_seq_kcluster *cluster;
95 int idx;
96 unsigned long flags;
97
98 if (list_ptr == NULL)
99 return;
100 list = *list_ptr;
101 *list_ptr = NULL;
102 if (list == NULL)
103 return;
104
105 for (idx = 0; idx < SNDRV_SEQ_INSTR_HASH_SIZE; idx++) {
106 while ((instr = list->hash[idx]) != NULL) {
107 list->hash[idx] = instr->next;
108 list->count--;
109 spin_lock_irqsave(&list->lock, flags);
110 while (instr->use) {
111 spin_unlock_irqrestore(&list->lock, flags);
112 schedule_timeout_uninterruptible(1);
113 spin_lock_irqsave(&list->lock, flags);
114 }
115 spin_unlock_irqrestore(&list->lock, flags);
116 if (snd_seq_instr_free(instr, 0)<0)
117 snd_printk(KERN_WARNING "instrument free problem\n");
118 }
119 while ((cluster = list->chash[idx]) != NULL) {
120 list->chash[idx] = cluster->next;
121 list->ccount--;
122 kfree(cluster);
123 }
124 }
125 kfree(list);
126}
127
128static int instr_free_compare(struct snd_seq_kinstr *instr,
129 struct snd_seq_instr_header *ifree,
130 unsigned int client)
131{
132 switch (ifree->cmd) {
133 case SNDRV_SEQ_INSTR_FREE_CMD_ALL:
134 /* all, except private for other clients */
135 if ((instr->instr.std & 0xff000000) == 0)
136 return 0;
137 if (((instr->instr.std >> 24) & 0xff) == client)
138 return 0;
139 return 1;
140 case SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE:
141 /* all my private instruments */
142 if ((instr->instr.std & 0xff000000) == 0)
143 return 1;
144 if (((instr->instr.std >> 24) & 0xff) == client)
145 return 0;
146 return 1;
147 case SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER:
148 /* all my private instruments */
149 if ((instr->instr.std & 0xff000000) == 0) {
150 if (instr->instr.cluster == ifree->id.cluster)
151 return 0;
152 return 1;
153 }
154 if (((instr->instr.std >> 24) & 0xff) == client) {
155 if (instr->instr.cluster == ifree->id.cluster)
156 return 0;
157 }
158 return 1;
159 }
160 return 1;
161}
162
163int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list,
164 struct snd_seq_instr_header *ifree,
165 int client,
166 int atomic)
167{
168 struct snd_seq_kinstr *instr, *prev, *next, *flist;
169 int idx;
170 unsigned long flags;
171
172 snd_instr_lock_ops(list);
173 for (idx = 0; idx < SNDRV_SEQ_INSTR_HASH_SIZE; idx++) {
174 spin_lock_irqsave(&list->lock, flags);
175 instr = list->hash[idx];
176 prev = flist = NULL;
177 while (instr) {
178 while (instr && instr_free_compare(instr, ifree, (unsigned int)client)) {
179 prev = instr;
180 instr = instr->next;
181 }
182 if (instr == NULL)
183 continue;
184 if (instr->ops && instr->ops->notify)
185 instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
186 next = instr->next;
187 if (prev == NULL) {
188 list->hash[idx] = next;
189 } else {
190 prev->next = next;
191 }
192 list->count--;
193 instr->next = flist;
194 flist = instr;
195 instr = next;
196 }
197 spin_unlock_irqrestore(&list->lock, flags);
198 while (flist) {
199 instr = flist;
200 flist = instr->next;
201 while (instr->use) {
202 schedule_timeout_uninterruptible(1);
203 barrier();
204 }
205 if (snd_seq_instr_free(instr, atomic)<0)
206 snd_printk(KERN_WARNING "instrument free problem\n");
207 instr = next;
208 }
209 }
210 snd_instr_unlock_ops(list);
211 return 0;
212}
213
214static int compute_hash_instr_key(struct snd_seq_instr *instr)
215{
216 int result;
217
218 result = instr->bank | (instr->prg << 16);
219 result += result >> 24;
220 result += result >> 16;
221 result += result >> 8;
222 return result & (SNDRV_SEQ_INSTR_HASH_SIZE-1);
223}
224
225#if 0
226static int compute_hash_cluster_key(snd_seq_instr_cluster_t cluster)
227{
228 int result;
229
230 result = cluster;
231 result += result >> 24;
232 result += result >> 16;
233 result += result >> 8;
234 return result & (SNDRV_SEQ_INSTR_HASH_SIZE-1);
235}
236#endif
237
238static int compare_instr(struct snd_seq_instr *i1, struct snd_seq_instr *i2, int exact)
239{
240 if (exact) {
241 if (i1->cluster != i2->cluster ||
242 i1->bank != i2->bank ||
243 i1->prg != i2->prg)
244 return 1;
245 if ((i1->std & 0xff000000) != (i2->std & 0xff000000))
246 return 1;
247 if (!(i1->std & i2->std))
248 return 1;
249 return 0;
250 } else {
251 unsigned int client_check;
252
253 if (i2->cluster && i1->cluster != i2->cluster)
254 return 1;
255 client_check = i2->std & 0xff000000;
256 if (client_check) {
257 if ((i1->std & 0xff000000) != client_check)
258 return 1;
259 } else {
260 if ((i1->std & i2->std) != i2->std)
261 return 1;
262 }
263 return i1->bank != i2->bank || i1->prg != i2->prg;
264 }
265}
266
267struct snd_seq_kinstr *snd_seq_instr_find(struct snd_seq_kinstr_list *list,
268 struct snd_seq_instr *instr,
269 int exact,
270 int follow_alias)
271{
272 unsigned long flags;
273 int depth = 0;
274 struct snd_seq_kinstr *result;
275
276 if (list == NULL || instr == NULL)
277 return NULL;
278 spin_lock_irqsave(&list->lock, flags);
279 __again:
280 result = list->hash[compute_hash_instr_key(instr)];
281 while (result) {
282 if (!compare_instr(&result->instr, instr, exact)) {
283 if (follow_alias && (result->type == SNDRV_SEQ_INSTR_ATYPE_ALIAS)) {
284 instr = (struct snd_seq_instr *)KINSTR_DATA(result);
285 if (++depth > 10)
286 goto __not_found;
287 goto __again;
288 }
289 result->use++;
290 spin_unlock_irqrestore(&list->lock, flags);
291 return result;
292 }
293 result = result->next;
294 }
295 __not_found:
296 spin_unlock_irqrestore(&list->lock, flags);
297 return NULL;
298}
299
300void snd_seq_instr_free_use(struct snd_seq_kinstr_list *list,
301 struct snd_seq_kinstr *instr)
302{
303 unsigned long flags;
304
305 if (list == NULL || instr == NULL)
306 return;
307 spin_lock_irqsave(&list->lock, flags);
308 if (instr->use <= 0) {
309 snd_printk(KERN_ERR "free_use: fatal!!! use = %i, name = '%s'\n", instr->use, instr->name);
310 } else {
311 instr->use--;
312 }
313 spin_unlock_irqrestore(&list->lock, flags);
314}
315
316static struct snd_seq_kinstr_ops *instr_ops(struct snd_seq_kinstr_ops *ops,
317 char *instr_type)
318{
319 while (ops) {
320 if (!strcmp(ops->instr_type, instr_type))
321 return ops;
322 ops = ops->next;
323 }
324 return NULL;
325}
326
327static int instr_result(struct snd_seq_event *ev,
328 int type, int result,
329 int atomic)
330{
331 struct snd_seq_event sev;
332
333 memset(&sev, 0, sizeof(sev));
334 sev.type = SNDRV_SEQ_EVENT_RESULT;
335 sev.flags = SNDRV_SEQ_TIME_STAMP_REAL | SNDRV_SEQ_EVENT_LENGTH_FIXED |
336 SNDRV_SEQ_PRIORITY_NORMAL;
337 sev.source = ev->dest;
338 sev.dest = ev->source;
339 sev.data.result.event = type;
340 sev.data.result.result = result;
341#if 0
342 printk("instr result - type = %i, result = %i, queue = %i, source.client:port = %i:%i, dest.client:port = %i:%i\n",
343 type, result,
344 sev.queue,
345 sev.source.client, sev.source.port,
346 sev.dest.client, sev.dest.port);
347#endif
348 return snd_seq_kernel_client_dispatch(sev.source.client, &sev, atomic, 0);
349}
350
351static int instr_begin(struct snd_seq_kinstr_ops *ops,
352 struct snd_seq_kinstr_list *list,
353 struct snd_seq_event *ev,
354 int atomic, int hop)
355{
356 unsigned long flags;
357
358 spin_lock_irqsave(&list->lock, flags);
359 if (list->owner >= 0 && list->owner != ev->source.client) {
360 spin_unlock_irqrestore(&list->lock, flags);
361 return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, -EBUSY, atomic);
362 }
363 list->owner = ev->source.client;
364 spin_unlock_irqrestore(&list->lock, flags);
365 return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, 0, atomic);
366}
367
368static int instr_end(struct snd_seq_kinstr_ops *ops,
369 struct snd_seq_kinstr_list *list,
370 struct snd_seq_event *ev,
371 int atomic, int hop)
372{
373 unsigned long flags;
374
375 /* TODO: timeout handling */
376 spin_lock_irqsave(&list->lock, flags);
377 if (list->owner == ev->source.client) {
378 list->owner = -1;
379 spin_unlock_irqrestore(&list->lock, flags);
380 return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, 0, atomic);
381 }
382 spin_unlock_irqrestore(&list->lock, flags);
383 return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, -EINVAL, atomic);
384}
385
386static int instr_info(struct snd_seq_kinstr_ops *ops,
387 struct snd_seq_kinstr_list *list,
388 struct snd_seq_event *ev,
389 int atomic, int hop)
390{
391 return -ENXIO;
392}
393
394static int instr_format_info(struct snd_seq_kinstr_ops *ops,
395 struct snd_seq_kinstr_list *list,
396 struct snd_seq_event *ev,
397 int atomic, int hop)
398{
399 return -ENXIO;
400}
401
402static int instr_reset(struct snd_seq_kinstr_ops *ops,
403 struct snd_seq_kinstr_list *list,
404 struct snd_seq_event *ev,
405 int atomic, int hop)
406{
407 return -ENXIO;
408}
409
410static int instr_status(struct snd_seq_kinstr_ops *ops,
411 struct snd_seq_kinstr_list *list,
412 struct snd_seq_event *ev,
413 int atomic, int hop)
414{
415 return -ENXIO;
416}
417
418static int instr_put(struct snd_seq_kinstr_ops *ops,
419 struct snd_seq_kinstr_list *list,
420 struct snd_seq_event *ev,
421 int atomic, int hop)
422{
423 unsigned long flags;
424 struct snd_seq_instr_header put;
425 struct snd_seq_kinstr *instr;
426 int result = -EINVAL, len, key;
427
428 if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR)
429 goto __return;
430
431 if (ev->data.ext.len < sizeof(struct snd_seq_instr_header))
432 goto __return;
433 if (copy_from_user(&put, (void __user *)ev->data.ext.ptr,
434 sizeof(struct snd_seq_instr_header))) {
435 result = -EFAULT;
436 goto __return;
437 }
438 snd_instr_lock_ops(list);
439 if (put.id.instr.std & 0xff000000) { /* private instrument */
440 put.id.instr.std &= 0x00ffffff;
441 put.id.instr.std |= (unsigned int)ev->source.client << 24;
442 }
443 if ((instr = snd_seq_instr_find(list, &put.id.instr, 1, 0))) {
444 snd_seq_instr_free_use(list, instr);
445 snd_instr_unlock_ops(list);
446 result = -EBUSY;
447 goto __return;
448 }
449 ops = instr_ops(ops, put.data.data.format);
450 if (ops == NULL) {
451 snd_instr_unlock_ops(list);
452 goto __return;
453 }
454 len = ops->add_len;
455 if (put.data.type == SNDRV_SEQ_INSTR_ATYPE_ALIAS)
456 len = sizeof(struct snd_seq_instr);
457 instr = snd_seq_instr_new(len, atomic);
458 if (instr == NULL) {
459 snd_instr_unlock_ops(list);
460 result = -ENOMEM;
461 goto __return;
462 }
463 instr->ops = ops;
464 instr->instr = put.id.instr;
465 strlcpy(instr->name, put.data.name, sizeof(instr->name));
466 instr->type = put.data.type;
467 if (instr->type == SNDRV_SEQ_INSTR_ATYPE_DATA) {
468 result = ops->put(ops->private_data,
469 instr,
470 (void __user *)ev->data.ext.ptr + sizeof(struct snd_seq_instr_header),
471 ev->data.ext.len - sizeof(struct snd_seq_instr_header),
472 atomic,
473 put.cmd);
474 if (result < 0) {
475 snd_seq_instr_free(instr, atomic);
476 snd_instr_unlock_ops(list);
477 goto __return;
478 }
479 }
480 key = compute_hash_instr_key(&instr->instr);
481 spin_lock_irqsave(&list->lock, flags);
482 instr->next = list->hash[key];
483 list->hash[key] = instr;
484 list->count++;
485 spin_unlock_irqrestore(&list->lock, flags);
486 snd_instr_unlock_ops(list);
487 result = 0;
488 __return:
489 instr_result(ev, SNDRV_SEQ_EVENT_INSTR_PUT, result, atomic);
490 return result;
491}
492
493static int instr_get(struct snd_seq_kinstr_ops *ops,
494 struct snd_seq_kinstr_list *list,
495 struct snd_seq_event *ev,
496 int atomic, int hop)
497{
498 return -ENXIO;
499}
500
501static int instr_free(struct snd_seq_kinstr_ops *ops,
502 struct snd_seq_kinstr_list *list,
503 struct snd_seq_event *ev,
504 int atomic, int hop)
505{
506 struct snd_seq_instr_header ifree;
507 struct snd_seq_kinstr *instr, *prev;
508 int result = -EINVAL;
509 unsigned long flags;
510 unsigned int hash;
511
512 if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR)
513 goto __return;
514
515 if (ev->data.ext.len < sizeof(struct snd_seq_instr_header))
516 goto __return;
517 if (copy_from_user(&ifree, (void __user *)ev->data.ext.ptr,
518 sizeof(struct snd_seq_instr_header))) {
519 result = -EFAULT;
520 goto __return;
521 }
522 if (ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_ALL ||
523 ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE ||
524 ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER) {
525 result = snd_seq_instr_list_free_cond(list, &ifree, ev->dest.client, atomic);
526 goto __return;
527 }
528 if (ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_SINGLE) {
529 if (ifree.id.instr.std & 0xff000000) {
530 ifree.id.instr.std &= 0x00ffffff;
531 ifree.id.instr.std |= (unsigned int)ev->source.client << 24;
532 }
533 hash = compute_hash_instr_key(&ifree.id.instr);
534 snd_instr_lock_ops(list);
535 spin_lock_irqsave(&list->lock, flags);
536 instr = list->hash[hash];
537 prev = NULL;
538 while (instr) {
539 if (!compare_instr(&instr->instr, &ifree.id.instr, 1))
540 goto __free_single;
541 prev = instr;
542 instr = instr->next;
543 }
544 result = -ENOENT;
545 spin_unlock_irqrestore(&list->lock, flags);
546 snd_instr_unlock_ops(list);
547 goto __return;
548
549 __free_single:
550 if (prev) {
551 prev->next = instr->next;
552 } else {
553 list->hash[hash] = instr->next;
554 }
555 if (instr->ops && instr->ops->notify)
556 instr->ops->notify(instr->ops->private_data, instr,
557 SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
558 while (instr->use) {
559 spin_unlock_irqrestore(&list->lock, flags);
560 schedule_timeout_uninterruptible(1);
561 spin_lock_irqsave(&list->lock, flags);
562 }
563 spin_unlock_irqrestore(&list->lock, flags);
564 result = snd_seq_instr_free(instr, atomic);
565 snd_instr_unlock_ops(list);
566 goto __return;
567 }
568
569 __return:
570 instr_result(ev, SNDRV_SEQ_EVENT_INSTR_FREE, result, atomic);
571 return result;
572}
573
574static int instr_list(struct snd_seq_kinstr_ops *ops,
575 struct snd_seq_kinstr_list *list,
576 struct snd_seq_event *ev,
577 int atomic, int hop)
578{
579 return -ENXIO;
580}
581
582static int instr_cluster(struct snd_seq_kinstr_ops *ops,
583 struct snd_seq_kinstr_list *list,
584 struct snd_seq_event *ev,
585 int atomic, int hop)
586{
587 return -ENXIO;
588}
589
590int snd_seq_instr_event(struct snd_seq_kinstr_ops *ops,
591 struct snd_seq_kinstr_list *list,
592 struct snd_seq_event *ev,
593 int client,
594 int atomic,
595 int hop)
596{
597 int direct = 0;
598
599 snd_assert(ops != NULL && list != NULL && ev != NULL, return -EINVAL);
600 if (snd_seq_ev_is_direct(ev)) {
601 direct = 1;
602 switch (ev->type) {
603 case SNDRV_SEQ_EVENT_INSTR_BEGIN:
604 return instr_begin(ops, list, ev, atomic, hop);
605 case SNDRV_SEQ_EVENT_INSTR_END:
606 return instr_end(ops, list, ev, atomic, hop);
607 }
608 }
609 if ((list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT) && !direct)
610 return -EINVAL;
611 switch (ev->type) {
612 case SNDRV_SEQ_EVENT_INSTR_INFO:
613 return instr_info(ops, list, ev, atomic, hop);
614 case SNDRV_SEQ_EVENT_INSTR_FINFO:
615 return instr_format_info(ops, list, ev, atomic, hop);
616 case SNDRV_SEQ_EVENT_INSTR_RESET:
617 return instr_reset(ops, list, ev, atomic, hop);
618 case SNDRV_SEQ_EVENT_INSTR_STATUS:
619 return instr_status(ops, list, ev, atomic, hop);
620 case SNDRV_SEQ_EVENT_INSTR_PUT:
621 return instr_put(ops, list, ev, atomic, hop);
622 case SNDRV_SEQ_EVENT_INSTR_GET:
623 return instr_get(ops, list, ev, atomic, hop);
624 case SNDRV_SEQ_EVENT_INSTR_FREE:
625 return instr_free(ops, list, ev, atomic, hop);
626 case SNDRV_SEQ_EVENT_INSTR_LIST:
627 return instr_list(ops, list, ev, atomic, hop);
628 case SNDRV_SEQ_EVENT_INSTR_CLUSTER:
629 return instr_cluster(ops, list, ev, atomic, hop);
630 }
631 return -EINVAL;
632}
633
634/*
635 * Init part
636 */
637
638static int __init alsa_seq_instr_init(void)
639{
640 return 0;
641}
642
643static void __exit alsa_seq_instr_exit(void)
644{
645}
646
647module_init(alsa_seq_instr_init)
648module_exit(alsa_seq_instr_exit)
649
650EXPORT_SYMBOL(snd_seq_instr_list_new);
651EXPORT_SYMBOL(snd_seq_instr_list_free);
652EXPORT_SYMBOL(snd_seq_instr_list_free_cond);
653EXPORT_SYMBOL(snd_seq_instr_find);
654EXPORT_SYMBOL(snd_seq_instr_free_use);
655EXPORT_SYMBOL(snd_seq_instr_event);
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index 1a34941d4217..54f921edda79 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <sound/core.h> 22#include <sound/core.h>
24#include "seq_lock.h" 23#include "seq_lock.h"
25 24
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index a72a1945bf8a..0cf6ac477318 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 5929aaf1df9d..99b35360c506 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -26,7 +26,6 @@ Possible options for midisynth module:
26*/ 26*/
27 27
28 28
29#include <sound/driver.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index 17b3e6f13ca3..07c663135c62 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -29,7 +29,6 @@
29 * code in here. If there is it should be reported as a bug. 29 * code in here. If there is it should be reported as a bug.
30 */ 30 */
31 31
32#include <sound/driver.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/slab.h> 33#include <linux/slab.h>
35#include <linux/string.h> 34#include <linux/string.h>
@@ -229,13 +228,6 @@ snd_midi_process_event(struct snd_midi_op *ops,
229 case SNDRV_SEQ_EVENT_PORT_START: 228 case SNDRV_SEQ_EVENT_PORT_START:
230 case SNDRV_SEQ_EVENT_PORT_EXIT: 229 case SNDRV_SEQ_EVENT_PORT_EXIT:
231 case SNDRV_SEQ_EVENT_PORT_CHANGE: 230 case SNDRV_SEQ_EVENT_PORT_CHANGE:
232 case SNDRV_SEQ_EVENT_SAMPLE:
233 case SNDRV_SEQ_EVENT_SAMPLE_START:
234 case SNDRV_SEQ_EVENT_SAMPLE_STOP:
235 case SNDRV_SEQ_EVENT_SAMPLE_FREQ:
236 case SNDRV_SEQ_EVENT_SAMPLE_VOLUME:
237 case SNDRV_SEQ_EVENT_SAMPLE_LOOP:
238 case SNDRV_SEQ_EVENT_SAMPLE_POSITION:
239 case SNDRV_SEQ_EVENT_ECHO: 231 case SNDRV_SEQ_EVENT_ECHO:
240 not_yet: 232 not_yet:
241 default: 233 default:
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
index b6820a5a73fc..8284f176a342 100644
--- a/sound/core/seq/seq_midi_event.c
+++ b/sound/core/seq/seq_midi_event.c
@@ -19,7 +19,6 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <linux/errno.h> 23#include <linux/errno.h>
25#include <linux/string.h> 24#include <linux/string.h>
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index b6e23ad12ab9..1c32a53d6bd8 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include "seq_system.h" 25#include "seq_system.h"
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index 074418617ee9..85969db576c9 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <sound/core.h> 24#include <sound/core.h>
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 9b87bb0c7f33..4a48c6ee8ee8 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -35,7 +35,6 @@
35 * - Addition of experimental sync support. 35 * - Addition of experimental sync support.
36 */ 36 */
37 37
38#include <sound/driver.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/slab.h> 39#include <linux/slab.h>
41#include <sound/core.h> 40#include <sound/core.h>
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index b201b76e9412..77884e62b648 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include "seq_system.h" 24#include "seq_system.h"
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 8716352afc81..d8fcd62e400f 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -20,20 +20,12 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include "seq_timer.h" 25#include "seq_timer.h"
27#include "seq_queue.h" 26#include "seq_queue.h"
28#include "seq_info.h" 27#include "seq_info.h"
29 28
30extern int seq_default_timer_class;
31extern int seq_default_timer_sclass;
32extern int seq_default_timer_card;
33extern int seq_default_timer_device;
34extern int seq_default_timer_subdevice;
35extern int seq_default_timer_resolution;
36
37/* allowed sequencer timer frequencies, in Hz */ 29/* allowed sequencer timer frequencies, in Hz */
38#define MIN_FREQUENCY 10 30#define MIN_FREQUENCY 10
39#define MAX_FREQUENCY 6250 31#define MAX_FREQUENCY 6250
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h
index e9ee1543c924..88dfb71805ae 100644
--- a/sound/core/seq/seq_timer.h
+++ b/sound/core/seq/seq_timer.h
@@ -138,4 +138,11 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigne
138snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr); 138snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr);
139snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr); 139snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr);
140 140
141extern int seq_default_timer_class;
142extern int seq_default_timer_sclass;
143extern int seq_default_timer_card;
144extern int seq_default_timer_device;
145extern int seq_default_timer_subdevice;
146extern int seq_default_timer_resolution;
147
141#endif 148#endif
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index e11790f6debe..86e7739269ca 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -35,7 +35,6 @@
35 * 35 *
36 */ 36 */
37 37
38#include <sound/driver.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/wait.h> 39#include <linux/wait.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 7b486c4d70db..00cca4d6e562 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/time.h> 24#include <linux/time.h>
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index dc73313b733a..7be51546eb9e 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -19,8 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23
24#ifdef CONFIG_SND_OSSEMUL 22#ifdef CONFIG_SND_OSSEMUL
25 23
26#if !defined(CONFIG_SOUND) && !(defined(MODULE) && defined(CONFIG_SOUND_MODULE)) 24#if !defined(CONFIG_SOUND) && !(defined(MODULE) && defined(CONFIG_SOUND_MODULE))
diff --git a/sound/core/timer.c b/sound/core/timer.c
index e7dc56ca4b97..aece465934b8 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <sound/driver.h>
23#include <linux/delay.h> 22#include <linux/delay.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
@@ -44,11 +43,14 @@
44#endif 43#endif
45 44
46static int timer_limit = DEFAULT_TIMER_LIMIT; 45static int timer_limit = DEFAULT_TIMER_LIMIT;
46static int timer_tstamp_monotonic = 1;
47MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); 47MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
48MODULE_DESCRIPTION("ALSA timer interface"); 48MODULE_DESCRIPTION("ALSA timer interface");
49MODULE_LICENSE("GPL"); 49MODULE_LICENSE("GPL");
50module_param(timer_limit, int, 0444); 50module_param(timer_limit, int, 0444);
51MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); 51MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
52module_param(timer_tstamp_monotonic, int, 0444);
53MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
52 54
53struct snd_timer_user { 55struct snd_timer_user {
54 struct snd_timer_instance *timeri; 56 struct snd_timer_instance *timeri;
@@ -381,7 +383,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
381 struct snd_timer_instance *ts; 383 struct snd_timer_instance *ts;
382 struct timespec tstamp; 384 struct timespec tstamp;
383 385
384 getnstimeofday(&tstamp); 386 if (timer_tstamp_monotonic)
387 do_posix_clock_monotonic_gettime(&tstamp);
388 else
389 getnstimeofday(&tstamp);
385 snd_assert(event >= SNDRV_TIMER_EVENT_START && 390 snd_assert(event >= SNDRV_TIMER_EVENT_START &&
386 event <= SNDRV_TIMER_EVENT_PAUSE, return); 391 event <= SNDRV_TIMER_EVENT_PAUSE, return);
387 if (event == SNDRV_TIMER_EVENT_START || 392 if (event == SNDRV_TIMER_EVENT_START ||
@@ -1182,8 +1187,12 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1182 spin_unlock(&tu->qlock); 1187 spin_unlock(&tu->qlock);
1183 return; 1188 return;
1184 } 1189 }
1185 if (tu->last_resolution != resolution || ticks > 0) 1190 if (tu->last_resolution != resolution || ticks > 0) {
1186 getnstimeofday(&tstamp); 1191 if (timer_tstamp_monotonic)
1192 do_posix_clock_monotonic_gettime(&tstamp);
1193 else
1194 getnstimeofday(&tstamp);
1195 }
1187 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1196 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
1188 tu->last_resolution != resolution) { 1197 tu->last_resolution != resolution) {
1189 r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1198 r1.event = SNDRV_TIMER_EVENT_RESOLUTION;