diff options
Diffstat (limited to 'sound/core')
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 | ||
67 | EXPORT_SYMBOL(snd_oss_info_register); | 66 | EXPORT_SYMBOL(snd_oss_info_register); |
68 | 67 | ||
69 | extern void snd_card_info_read_oss(struct snd_info_buffer *buffer); | ||
70 | |||
71 | static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) | 68 | static 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 | ||
44 | static DEFINE_MUTEX(snd_card_mutex); | 43 | static DEFINE_MUTEX(snd_card_mutex); |
45 | 44 | ||
45 | static char *slots[SNDRV_CARDS]; | ||
46 | module_param_array(slots, charp, NULL, 0444); | ||
47 | MODULE_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 | */ | ||
52 | static 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) |
47 | int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); | 80 | int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); |
48 | EXPORT_SYMBOL(snd_mixer_oss_notify_callback); | 81 | EXPORT_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 | ||
229 | static char *snd_pcm_tstamp_mode_names[] = { | 228 | static char *snd_pcm_tstamp_mode_names[] = { |
230 | TSTAMP(NONE), | 229 | TSTAMP(NONE), |
231 | TSTAMP(MMAP), | 230 | TSTAMP(ENABLE), |
232 | }; | 231 | }; |
233 | 232 | ||
234 | static const char *snd_pcm_stream_name(int stream) | 233 | static 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 | ||
768 | static 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 | |||
774 | int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | 764 | int 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 | ||
1140 | static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | 1139 | static 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 | ||
1452 | EXPORT_SYMBOL(snd_pcm_lib_ioctl); | 1451 | EXPORT_SYMBOL(snd_pcm_lib_ioctl); |
1453 | 1452 | ||
1454 | /* | ||
1455 | * Conditions | ||
1456 | */ | ||
1457 | |||
1458 | static 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 */ | ||
1472 | void snd_pcm_tick_set(struct snd_pcm_substream *substream, unsigned long ticks) | ||
1473 | { | ||
1474 | snd_pcm_system_tick_set(substream, ticks); | ||
1475 | } | ||
1476 | |||
1477 | void 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 | |||
1530 | void 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 | ||
1588 | EXPORT_SYMBOL(snd_pcm_period_elapsed); | 1490 | EXPORT_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 | */ | ||
1498 | static 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 | |||
1590 | static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, | 1557 | static 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 | ||
1184 | static struct action_ops snd_pcm_action_resume = { | 1163 | static 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 | |||
2480 | static 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 | ||
2523 | static int snd_pcm_common_ioctl1(struct file *file, | 2495 | static 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 | */ |
3021 | static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, | 2995 | static 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 | ||
3038 | static struct vm_operations_struct snd_pcm_vm_ops_status = | 3009 | static 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 | ||
3043 | static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, | 3014 | static 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 | */ |
3064 | static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, | 3035 | static 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 | ||
3081 | static struct vm_operations_struct snd_pcm_vm_ops_control = | 3049 | static 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 | ||
3086 | static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, | 3054 | static 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 | */ |
3122 | static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, | 3090 | static 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 | ||
3155 | static struct vm_operations_struct snd_pcm_vm_ops_data = | 3120 | static 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 | ||
914 | static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, | 913 | static 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 | ||
955 | static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, | 955 | static 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 | ||
1134 | static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, | 1135 | static 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, | |||
1185 | long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, | 1188 | long 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 | ||
1191 | static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, | 1194 | static 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 | ||
6 | obj-$(CONFIG_SND) += instr/ | ||
7 | ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) | 6 | ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) |
8 | obj-$(CONFIG_SND_SEQUENCER) += oss/ | 7 | obj-$(CONFIG_SND_SEQUENCER) += oss/ |
9 | endif | 8 | endif |
@@ -15,7 +14,6 @@ snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ | |||
15 | snd-seq-midi-objs := seq_midi.o | 14 | snd-seq-midi-objs := seq_midi.o |
16 | snd-seq-midi-emul-objs := seq_midi_emul.o | 15 | snd-seq-midi-emul-objs := seq_midi_emul.o |
17 | snd-seq-midi-event-objs := seq_midi_event.o | 16 | snd-seq-midi-event-objs := seq_midi_event.o |
18 | snd-seq-instr-objs := seq_instr.o | ||
19 | snd-seq-dummy-objs := seq_dummy.o | 17 | snd-seq-dummy-objs := seq_dummy.o |
20 | snd-seq-virmidi-objs := seq_virmidi.o | 18 | snd-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 |
37 | obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o | 35 | obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o |
38 | obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o | 36 | obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o |
39 | obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o | 37 | obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o |
40 | obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o | 38 | obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o |
41 | obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-midi-emul.o snd-seq-instr.o | ||
42 | obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o | 39 | obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o |
43 | obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o | 40 | obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o |
44 | obj-$(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 | |||
6 | snd-ainstr-fm-objs := ainstr_fm.o | ||
7 | snd-ainstr-simple-objs := ainstr_simple.o | ||
8 | snd-ainstr-gf1-objs := ainstr_gf1.o | ||
9 | snd-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 | # | ||
17 | sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) | ||
18 | |||
19 | # Toplevel Module Dependency | ||
20 | obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-ainstr-fm.o | ||
21 | obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-ainstr-fm.o | ||
22 | obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-iw.o | ||
23 | obj-$(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 | |||
28 | MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); | ||
29 | MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support."); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | static 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 | |||
74 | static 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 | |||
116 | static 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 | |||
123 | int 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 | |||
143 | static int __init alsa_ainstr_fm_init(void) | ||
144 | { | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void __exit alsa_ainstr_fm_exit(void) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | module_init(alsa_ainstr_fm_init) | ||
153 | module_exit(alsa_ainstr_fm_exit) | ||
154 | |||
155 | EXPORT_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 | |||
29 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | ||
30 | MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support."); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | static 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 | |||
44 | static 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 | |||
118 | static 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 | |||
127 | static 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 | |||
139 | static 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 | |||
191 | static 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 | |||
253 | static 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 | |||
285 | static 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 | |||
303 | static 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 | |||
315 | static 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 | |||
325 | int 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 | |||
347 | static int __init alsa_ainstr_gf1_init(void) | ||
348 | { | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static void __exit alsa_ainstr_gf1_exit(void) | ||
353 | { | ||
354 | } | ||
355 | |||
356 | module_init(alsa_ainstr_gf1_init) | ||
357 | module_exit(alsa_ainstr_gf1_exit) | ||
358 | |||
359 | EXPORT_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 | |||
29 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | ||
30 | MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support."); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | static 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 | |||
44 | static 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 | |||
54 | static 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 | |||
122 | static 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 | |||
188 | static 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 | |||
200 | static 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 | |||
209 | static 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 | |||
228 | static 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 | |||
337 | static 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 | |||
347 | static 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 | |||
394 | static 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 | |||
449 | static 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 | |||
522 | static 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 | |||
534 | static 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 | |||
547 | static 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 | |||
567 | static 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 | |||
579 | static 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 | |||
589 | int 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 | |||
611 | static int __init alsa_ainstr_iw_init(void) | ||
612 | { | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static void __exit alsa_ainstr_iw_exit(void) | ||
617 | { | ||
618 | } | ||
619 | |||
620 | module_init(alsa_ainstr_iw_init) | ||
621 | module_exit(alsa_ainstr_iw_exit) | ||
622 | |||
623 | EXPORT_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 | |||
29 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | ||
30 | MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support."); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | static 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 | |||
44 | static 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 | |||
52 | static 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 | |||
102 | static 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 | |||
149 | static 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 | |||
159 | static 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 | |||
171 | static 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 | |||
181 | int 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 | |||
203 | static int __init alsa_ainstr_simple_init(void) | ||
204 | { | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static void __exit alsa_ainstr_simple_exit(void) | ||
209 | { | ||
210 | } | ||
211 | |||
212 | module_init(alsa_ainstr_simple_init) | ||
213 | module_exit(alsa_ainstr_simple_exit) | ||
214 | |||
215 | EXPORT_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 | ||
133 | extern int seq_client_load[]; | ||
134 | |||
135 | struct snd_seq_client *snd_seq_client_use_ptr(int clientid) | 132 | struct 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 | |||
98 | int snd_seq_client_notify_subscription(int client, int port, | 98 | int 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 | ||
101 | extern 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 | |||
29 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | ||
30 | MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer instrument library."); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | |||
34 | static 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 | |||
43 | static 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 | |||
52 | static 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 | |||
63 | static 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 | |||
76 | struct 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 | |||
90 | void 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 | |||
128 | static 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 | |||
163 | int 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 | |||
214 | static 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 | ||
226 | static 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 | |||
238 | static 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 | |||
267 | struct 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 | |||
300 | void 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 | |||
316 | static 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 | |||
327 | static 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 | |||
351 | static 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 | |||
368 | static 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 | |||
386 | static 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 | |||
394 | static 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 | |||
402 | static 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 | |||
410 | static 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 | |||
418 | static 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 | |||
493 | static 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 | |||
501 | static 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 | |||
574 | static 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 | |||
582 | static 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 | |||
590 | int 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 | |||
638 | static int __init alsa_seq_instr_init(void) | ||
639 | { | ||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | static void __exit alsa_seq_instr_exit(void) | ||
644 | { | ||
645 | } | ||
646 | |||
647 | module_init(alsa_seq_instr_init) | ||
648 | module_exit(alsa_seq_instr_exit) | ||
649 | |||
650 | EXPORT_SYMBOL(snd_seq_instr_list_new); | ||
651 | EXPORT_SYMBOL(snd_seq_instr_list_free); | ||
652 | EXPORT_SYMBOL(snd_seq_instr_list_free_cond); | ||
653 | EXPORT_SYMBOL(snd_seq_instr_find); | ||
654 | EXPORT_SYMBOL(snd_seq_instr_free_use); | ||
655 | EXPORT_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 | ||
30 | extern int seq_default_timer_class; | ||
31 | extern int seq_default_timer_sclass; | ||
32 | extern int seq_default_timer_card; | ||
33 | extern int seq_default_timer_device; | ||
34 | extern int seq_default_timer_subdevice; | ||
35 | extern 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 | |||
138 | snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr); | 138 | snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr); |
139 | snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr); | 139 | snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr); |
140 | 140 | ||
141 | extern int seq_default_timer_class; | ||
142 | extern int seq_default_timer_sclass; | ||
143 | extern int seq_default_timer_card; | ||
144 | extern int seq_default_timer_device; | ||
145 | extern int seq_default_timer_subdevice; | ||
146 | extern 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 | ||
46 | static int timer_limit = DEFAULT_TIMER_LIMIT; | 45 | static int timer_limit = DEFAULT_TIMER_LIMIT; |
46 | static int timer_tstamp_monotonic = 1; | ||
47 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); | 47 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); |
48 | MODULE_DESCRIPTION("ALSA timer interface"); | 48 | MODULE_DESCRIPTION("ALSA timer interface"); |
49 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
50 | module_param(timer_limit, int, 0444); | 50 | module_param(timer_limit, int, 0444); |
51 | MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); | 51 | MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); |
52 | module_param(timer_tstamp_monotonic, int, 0444); | ||
53 | MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); | ||
52 | 54 | ||
53 | struct snd_timer_user { | 55 | struct 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; |