aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/Kconfig1
-rw-r--r--sound/core/control.c16
-rw-r--r--sound/core/control_compat.c1
-rw-r--r--sound/core/hrtimer.c16
-rw-r--r--sound/core/info.c1
-rw-r--r--sound/core/isadma.c10
-rw-r--r--sound/core/jack.c1
-rw-r--r--sound/core/misc.c33
-rw-r--r--sound/core/oss/mixer_oss.c4
-rw-r--r--sound/core/oss/pcm_oss.c31
-rw-r--r--sound/core/oss/route.c1
-rw-r--r--sound/core/pcm.c11
-rw-r--r--sound/core/pcm_compat.c1
-rw-r--r--sound/core/pcm_lib.c451
-rw-r--r--sound/core/pcm_memory.c56
-rw-r--r--sound/core/pcm_native.c165
-rw-r--r--sound/core/pcm_timer.c17
-rw-r--r--sound/core/rawmidi.c19
-rw-r--r--sound/core/seq/oss/seq_oss_init.c1
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c1
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c1
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c1
-rw-r--r--sound/core/seq/oss/seq_oss_timer.c1
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c1
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_compat.c1
-rw-r--r--sound/core/seq/seq_system.c1
-rw-r--r--sound/core/seq/seq_timer.c27
-rw-r--r--sound/core/sound.c4
-rw-r--r--sound/core/sound_oss.c2
-rw-r--r--sound/core/timer.c7
31 files changed, 573 insertions, 312 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index c15682a2f9db..475455c76610 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -5,6 +5,7 @@ config SND_TIMER
5config SND_PCM 5config SND_PCM
6 tristate 6 tristate
7 select SND_TIMER 7 select SND_TIMER
8 select GCD
8 9
9config SND_HWDEP 10config SND_HWDEP
10 tristate 11 tristate
diff --git a/sound/core/control.c b/sound/core/control.c
index a8b7fabe645e..439ce64f9d82 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -75,7 +75,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
75 ctl->card = card; 75 ctl->card = card;
76 ctl->prefer_pcm_subdevice = -1; 76 ctl->prefer_pcm_subdevice = -1;
77 ctl->prefer_rawmidi_subdevice = -1; 77 ctl->prefer_rawmidi_subdevice = -1;
78 ctl->pid = current->pid; 78 ctl->pid = get_pid(task_pid(current));
79 file->private_data = ctl; 79 file->private_data = ctl;
80 write_lock_irqsave(&card->ctl_files_rwlock, flags); 80 write_lock_irqsave(&card->ctl_files_rwlock, flags);
81 list_add_tail(&ctl->list, &card->ctl_files); 81 list_add_tail(&ctl->list, &card->ctl_files);
@@ -125,6 +125,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
125 control->vd[idx].owner = NULL; 125 control->vd[idx].owner = NULL;
126 up_write(&card->controls_rwsem); 126 up_write(&card->controls_rwsem);
127 snd_ctl_empty_read_queue(ctl); 127 snd_ctl_empty_read_queue(ctl);
128 put_pid(ctl->pid);
128 kfree(ctl); 129 kfree(ctl);
129 module_put(card->module); 130 module_put(card->module);
130 snd_card_file_remove(card, file); 131 snd_card_file_remove(card, file);
@@ -236,8 +237,9 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
236 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 237 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
237 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 238 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
238 SNDRV_CTL_ELEM_ACCESS_INACTIVE| 239 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
239 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE| 240 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
240 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)); 241 SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
242 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
241 kctl.info = ncontrol->info; 243 kctl.info = ncontrol->info;
242 kctl.get = ncontrol->get; 244 kctl.get = ncontrol->get;
243 kctl.put = ncontrol->put; 245 kctl.put = ncontrol->put;
@@ -672,7 +674,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
672 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK; 674 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
673 if (vd->owner == ctl) 675 if (vd->owner == ctl)
674 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER; 676 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
675 info->owner = vd->owner_pid; 677 info->owner = pid_vnr(vd->owner->pid);
676 } else { 678 } else {
677 info->owner = -1; 679 info->owner = -1;
678 } 680 }
@@ -827,7 +829,6 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file,
827 result = -EBUSY; 829 result = -EBUSY;
828 else { 830 else {
829 vd->owner = file; 831 vd->owner = file;
830 vd->owner_pid = current->pid;
831 result = 0; 832 result = 0;
832 } 833 }
833 } 834 }
@@ -858,7 +859,6 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
858 result = -EPERM; 859 result = -EPERM;
859 else { 860 else {
860 vd->owner = NULL; 861 vd->owner = NULL;
861 vd->owner_pid = 0;
862 result = 0; 862 result = 0;
863 } 863 }
864 } 864 }
@@ -1100,7 +1100,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1100 1100
1101 if (copy_from_user(&tlv, _tlv, sizeof(tlv))) 1101 if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
1102 return -EFAULT; 1102 return -EFAULT;
1103 if (tlv.length < sizeof(unsigned int) * 3) 1103 if (tlv.length < sizeof(unsigned int) * 2)
1104 return -EINVAL; 1104 return -EINVAL;
1105 down_read(&card->controls_rwsem); 1105 down_read(&card->controls_rwsem);
1106 kctl = snd_ctl_find_numid(card, tlv.numid); 1106 kctl = snd_ctl_find_numid(card, tlv.numid);
@@ -1120,7 +1120,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1120 goto __kctl_end; 1120 goto __kctl_end;
1121 } 1121 }
1122 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { 1122 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1123 if (file && vd->owner != NULL && vd->owner != file) { 1123 if (vd->owner != NULL && vd->owner != file) {
1124 err = -EPERM; 1124 err = -EPERM;
1125 goto __kctl_end; 1125 goto __kctl_end;
1126 } 1126 }
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 368dc9c4aef8..426874429a5e 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -21,6 +21,7 @@
21/* this file included from control.c */ 21/* this file included from control.c */
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/slab.h>
24 25
25struct snd_ctl_elem_list32 { 26struct snd_ctl_elem_list32 {
26 u32 offset; 27 u32 offset;
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 34c7d48f5061..7730575bfadd 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
24#include <linux/hrtimer.h> 25#include <linux/hrtimer.h>
@@ -37,14 +38,22 @@ static unsigned int resolution;
37struct snd_hrtimer { 38struct snd_hrtimer {
38 struct snd_timer *timer; 39 struct snd_timer *timer;
39 struct hrtimer hrt; 40 struct hrtimer hrt;
41 atomic_t running;
40}; 42};
41 43
42static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) 44static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
43{ 45{
44 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); 46 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
45 struct snd_timer *t = stime->timer; 47 struct snd_timer *t = stime->timer;
48
49 if (!atomic_read(&stime->running))
50 return HRTIMER_NORESTART;
51
46 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); 52 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
47 snd_timer_interrupt(stime->timer, t->sticks); 53 snd_timer_interrupt(stime->timer, t->sticks);
54
55 if (!atomic_read(&stime->running))
56 return HRTIMER_NORESTART;
48 return HRTIMER_RESTART; 57 return HRTIMER_RESTART;
49} 58}
50 59
@@ -58,6 +67,7 @@ static int snd_hrtimer_open(struct snd_timer *t)
58 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 67 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59 stime->timer = t; 68 stime->timer = t;
60 stime->hrt.function = snd_hrtimer_callback; 69 stime->hrt.function = snd_hrtimer_callback;
70 atomic_set(&stime->running, 0);
61 t->private_data = stime; 71 t->private_data = stime;
62 return 0; 72 return 0;
63} 73}
@@ -78,16 +88,18 @@ static int snd_hrtimer_start(struct snd_timer *t)
78{ 88{
79 struct snd_hrtimer *stime = t->private_data; 89 struct snd_hrtimer *stime = t->private_data;
80 90
91 atomic_set(&stime->running, 0);
92 hrtimer_cancel(&stime->hrt);
81 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), 93 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
82 HRTIMER_MODE_REL); 94 HRTIMER_MODE_REL);
95 atomic_set(&stime->running, 1);
83 return 0; 96 return 0;
84} 97}
85 98
86static int snd_hrtimer_stop(struct snd_timer *t) 99static int snd_hrtimer_stop(struct snd_timer *t)
87{ 100{
88 struct snd_hrtimer *stime = t->private_data; 101 struct snd_hrtimer *stime = t->private_data;
89 102 atomic_set(&stime->running, 0);
90 hrtimer_cancel(&stime->hrt);
91 return 0; 103 return 0;
92} 104}
93 105
diff --git a/sound/core/info.c b/sound/core/info.c
index d749a0d394a7..cc4a53d4b7f8 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/slab.h>
25#include <linux/smp_lock.h> 26#include <linux/smp_lock.h>
26#include <linux/string.h> 27#include <linux/string.h>
27#include <sound/core.h> 28#include <sound/core.h>
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index 79f0f16af339..950e19ba91fc 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -85,16 +85,24 @@ EXPORT_SYMBOL(snd_dma_disable);
85unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) 85unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
86{ 86{
87 unsigned long flags; 87 unsigned long flags;
88 unsigned int result; 88 unsigned int result, result1;
89 89
90 flags = claim_dma_lock(); 90 flags = claim_dma_lock();
91 clear_dma_ff(dma); 91 clear_dma_ff(dma);
92 if (!isa_dma_bridge_buggy) 92 if (!isa_dma_bridge_buggy)
93 disable_dma(dma); 93 disable_dma(dma);
94 result = get_dma_residue(dma); 94 result = get_dma_residue(dma);
95 /*
96 * HACK - read the counter again and choose higher value in order to
97 * avoid reading during counter lower byte roll over if the
98 * isa_dma_bridge_buggy is set.
99 */
100 result1 = get_dma_residue(dma);
95 if (!isa_dma_bridge_buggy) 101 if (!isa_dma_bridge_buggy)
96 enable_dma(dma); 102 enable_dma(dma);
97 release_dma_lock(flags); 103 release_dma_lock(flags);
104 if (unlikely(result < result1))
105 result = result1;
98#ifdef CONFIG_SND_DEBUG 106#ifdef CONFIG_SND_DEBUG
99 if (result > size) 107 if (result > size)
100 snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size); 108 snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
diff --git a/sound/core/jack.c b/sound/core/jack.c
index f705eec7372a..14b8a4ee690d 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/slab.h>
23#include <sound/jack.h> 24#include <sound/jack.h>
24#include <sound/core.h> 25#include <sound/core.h>
25 26
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 23a032c6d487..2c41825c836e 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/slab.h>
24#include <linux/ioport.h> 25#include <linux/ioport.h>
25#include <sound/core.h> 26#include <sound/core.h>
26 27
@@ -101,8 +102,9 @@ EXPORT_SYMBOL_GPL(__snd_printk);
101#ifdef CONFIG_PCI 102#ifdef CONFIG_PCI
102#include <linux/pci.h> 103#include <linux/pci.h>
103/** 104/**
104 * snd_pci_quirk_lookup - look up a PCI SSID quirk list 105 * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
105 * @pci: pci_dev handle 106 * @vendor: PCI SSV id
107 * @device: PCI SSD id
106 * @list: quirk list, terminated by a null entry 108 * @list: quirk list, terminated by a null entry
107 * 109 *
108 * Look through the given quirk list and finds a matching entry 110 * Look through the given quirk list and finds a matching entry
@@ -112,18 +114,39 @@ EXPORT_SYMBOL_GPL(__snd_printk);
112 * Returns the matched entry pointer, or NULL if nothing matched. 114 * Returns the matched entry pointer, or NULL if nothing matched.
113 */ 115 */
114const struct snd_pci_quirk * 116const struct snd_pci_quirk *
115snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) 117snd_pci_quirk_lookup_id(u16 vendor, u16 device,
118 const struct snd_pci_quirk *list)
116{ 119{
117 const struct snd_pci_quirk *q; 120 const struct snd_pci_quirk *q;
118 121
119 for (q = list; q->subvendor; q++) { 122 for (q = list; q->subvendor; q++) {
120 if (q->subvendor != pci->subsystem_vendor) 123 if (q->subvendor != vendor)
121 continue; 124 continue;
122 if (!q->subdevice || 125 if (!q->subdevice ||
123 (pci->subsystem_device & q->subdevice_mask) == q->subdevice) 126 (device & q->subdevice_mask) == q->subdevice)
124 return q; 127 return q;
125 } 128 }
126 return NULL; 129 return NULL;
127} 130}
131EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
132
133/**
134 * snd_pci_quirk_lookup - look up a PCI SSID quirk list
135 * @pci: pci_dev handle
136 * @list: quirk list, terminated by a null entry
137 *
138 * Look through the given quirk list and finds a matching entry
139 * with the same PCI SSID. When subdevice is 0, all subdevice
140 * values may match.
141 *
142 * Returns the matched entry pointer, or NULL if nothing matched.
143 */
144const struct snd_pci_quirk *
145snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
146{
147 return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
148 pci->subsystem_device,
149 list);
150}
128EXPORT_SYMBOL(snd_pci_quirk_lookup); 151EXPORT_SYMBOL(snd_pci_quirk_lookup);
129#endif 152#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 772423889eb3..54e2eb56e4c2 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1251,7 +1251,9 @@ static void snd_mixer_oss_build(struct snd_mixer_oss *mixer)
1251 { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */ 1251 { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */
1252 { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */ 1252 { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */
1253 { SOUND_MIXER_PCM, "PCM", 0 }, 1253 { SOUND_MIXER_PCM, "PCM", 0 },
1254 { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, 1254 { SOUND_MIXER_SPEAKER, "Beep", 0 },
1255 { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, /* fallback */
1256 { SOUND_MIXER_SPEAKER, "Speaker", 0 }, /* fallback */
1255 { SOUND_MIXER_LINE, "Line", 0 }, 1257 { SOUND_MIXER_LINE, "Line", 0 },
1256 { SOUND_MIXER_MIC, "Mic", 0 }, 1258 { SOUND_MIXER_MIC, "Mic", 0 },
1257 { SOUND_MIXER_CD, "CD", 0 }, 1259 { SOUND_MIXER_CD, "CD", 0 },
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c96353121a..82d4e3329b3d 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -632,6 +632,12 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); 632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
633} 633}
634 634
635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{
638 return runtime->hw_ptr_interrupt;
639}
640
635/* define extended formats in the recent OSS versions (if any) */ 641/* define extended formats in the recent OSS versions (if any) */
636/* linear formats */ 642/* linear formats */
637#define AFMT_S32_LE 0x00001000 643#define AFMT_S32_LE 0x00001000
@@ -1102,7 +1108,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1102 return err; 1108 return err;
1103 } 1109 }
1104 runtime->oss.prepare = 0; 1110 runtime->oss.prepare = 0;
1105 runtime->oss.prev_hw_ptr_interrupt = 0; 1111 runtime->oss.prev_hw_ptr_period = 0;
1106 runtime->oss.period_ptr = 0; 1112 runtime->oss.period_ptr = 0;
1107 runtime->oss.buffer_used = 0; 1113 runtime->oss.buffer_used = 0;
1108 1114
@@ -1950,7 +1956,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1950 return result; 1956 return result;
1951} 1957}
1952 1958
1953static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) 1959static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1960 snd_pcm_uframes_t hw_ptr)
1954{ 1961{
1955 struct snd_pcm_runtime *runtime = substream->runtime; 1962 struct snd_pcm_runtime *runtime = substream->runtime;
1956 snd_pcm_uframes_t appl_ptr; 1963 snd_pcm_uframes_t appl_ptr;
@@ -1986,7 +1993,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1986 if (runtime->oss.trigger) 1993 if (runtime->oss.trigger)
1987 goto _skip1; 1994 goto _skip1;
1988 if (atomic_read(&psubstream->mmap_count)) 1995 if (atomic_read(&psubstream->mmap_count))
1989 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1996 snd_pcm_oss_simulate_fill(psubstream,
1997 get_hw_ptr_period(runtime));
1990 runtime->oss.trigger = 1; 1998 runtime->oss.trigger = 1;
1991 runtime->start_threshold = 1; 1999 runtime->start_threshold = 1;
1992 cmd = SNDRV_PCM_IOCTL_START; 2000 cmd = SNDRV_PCM_IOCTL_START;
@@ -2105,11 +2113,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
2105 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2113 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2106 if (atomic_read(&substream->mmap_count)) { 2114 if (atomic_read(&substream->mmap_count)) {
2107 snd_pcm_sframes_t n; 2115 snd_pcm_sframes_t n;
2108 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2116 delay = get_hw_ptr_period(runtime);
2117 n = delay - runtime->oss.prev_hw_ptr_period;
2109 if (n < 0) 2118 if (n < 0)
2110 n += runtime->boundary; 2119 n += runtime->boundary;
2111 info.blocks = n / runtime->period_size; 2120 info.blocks = n / runtime->period_size;
2112 runtime->oss.prev_hw_ptr_interrupt = delay; 2121 runtime->oss.prev_hw_ptr_period = delay;
2113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2122 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2114 snd_pcm_oss_simulate_fill(substream, delay); 2123 snd_pcm_oss_simulate_fill(substream, delay);
2115 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; 2124 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
@@ -2673,18 +2682,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2673{ 2682{
2674 struct snd_pcm_runtime *runtime = substream->runtime; 2683 struct snd_pcm_runtime *runtime = substream->runtime;
2675 if (atomic_read(&substream->mmap_count)) 2684 if (atomic_read(&substream->mmap_count))
2676 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2685 return runtime->oss.prev_hw_ptr_period !=
2686 get_hw_ptr_period(runtime);
2677 else 2687 else
2678 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2688 return snd_pcm_playback_avail(runtime) >=
2689 runtime->oss.period_frames;
2679} 2690}
2680 2691
2681static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2692static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2682{ 2693{
2683 struct snd_pcm_runtime *runtime = substream->runtime; 2694 struct snd_pcm_runtime *runtime = substream->runtime;
2684 if (atomic_read(&substream->mmap_count)) 2695 if (atomic_read(&substream->mmap_count))
2685 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2696 return runtime->oss.prev_hw_ptr_period !=
2697 get_hw_ptr_period(runtime);
2686 else 2698 else
2687 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2699 return snd_pcm_capture_avail(runtime) >=
2700 runtime->oss.period_frames;
2688} 2701}
2689 2702
2690static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) 2703static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index 0dcc2870d537..bbe25d8c450a 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 <linux/slab.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/pcm.c b/sound/core/pcm.c
index c69c60b2a48a..0d428d0896db 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -435,6 +435,7 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
435 return; 435 return;
436 } 436 }
437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); 437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
438 snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
438 snd_iprintf(buffer, "trigger_time: %ld.%09ld\n", 439 snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
439 status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec); 440 status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
440 snd_iprintf(buffer, "tstamp : %ld.%09ld\n", 441 snd_iprintf(buffer, "tstamp : %ld.%09ld\n",
@@ -809,7 +810,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
809 card = pcm->card; 810 card = pcm->card;
810 read_lock(&card->ctl_files_rwlock); 811 read_lock(&card->ctl_files_rwlock);
811 list_for_each_entry(kctl, &card->ctl_files, list) { 812 list_for_each_entry(kctl, &card->ctl_files, list) {
812 if (kctl->pid == current->pid) { 813 if (kctl->pid == task_pid(current)) {
813 prefer_subdevice = kctl->prefer_pcm_subdevice; 814 prefer_subdevice = kctl->prefer_pcm_subdevice;
814 if (prefer_subdevice != -1) 815 if (prefer_subdevice != -1)
815 break; 816 break;
@@ -893,6 +894,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
893 memset((void*)runtime->control, 0, size); 894 memset((void*)runtime->control, 0, size);
894 895
895 init_waitqueue_head(&runtime->sleep); 896 init_waitqueue_head(&runtime->sleep);
897 init_waitqueue_head(&runtime->tsleep);
896 898
897 runtime->status->state = SNDRV_PCM_STATE_OPEN; 899 runtime->status->state = SNDRV_PCM_STATE_OPEN;
898 900
@@ -900,6 +902,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
900 substream->private_data = pcm->private_data; 902 substream->private_data = pcm->private_data;
901 substream->ref_count = 1; 903 substream->ref_count = 1;
902 substream->f_flags = file->f_flags; 904 substream->f_flags = file->f_flags;
905 substream->pid = get_pid(task_pid(current));
903 pstr->substream_opened++; 906 pstr->substream_opened++;
904 *rsubstream = substream; 907 *rsubstream = substream;
905 return 0; 908 return 0;
@@ -919,8 +922,14 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
919 snd_free_pages((void*)runtime->control, 922 snd_free_pages((void*)runtime->control,
920 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); 923 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
921 kfree(runtime->hw_constraints.rules); 924 kfree(runtime->hw_constraints.rules);
925#ifdef CONFIG_SND_PCM_XRUN_DEBUG
926 if (runtime->hwptr_log)
927 kfree(runtime->hwptr_log);
928#endif
922 kfree(runtime); 929 kfree(runtime);
923 substream->runtime = NULL; 930 substream->runtime = NULL;
931 put_pid(substream->pid);
932 substream->pid = NULL;
924 substream->pstr->substream_opened--; 933 substream->pstr->substream_opened--;
925} 934}
926 935
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 08bfed594a83..5fb2e28e796f 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -21,6 +21,7 @@
21/* This file included from pcm_native.c */ 21/* This file included from pcm_native.c */
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/slab.h>
24 25
25static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream, 26static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
26 s32 __user *src) 27 s32 __user *src)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 30f410832a25..a2ff86189d2a 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -126,17 +126,6 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
126 } 126 }
127} 127}
128 128
129#ifdef CONFIG_SND_PCM_XRUN_DEBUG
130#define xrun_debug(substream, mask) ((substream)->pstr->xrun_debug & (mask))
131#else
132#define xrun_debug(substream, mask) 0
133#endif
134
135#define dump_stack_on_xrun(substream) do { \
136 if (xrun_debug(substream, 2)) \
137 dump_stack(); \
138 } while (0)
139
140static void pcm_debug_name(struct snd_pcm_substream *substream, 129static void pcm_debug_name(struct snd_pcm_substream *substream,
141 char *name, size_t len) 130 char *name, size_t len)
142{ 131{
@@ -147,6 +136,27 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
147 substream->number); 136 substream->number);
148} 137}
149 138
139#define XRUN_DEBUG_BASIC (1<<0)
140#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
141#define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */
142#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */
143#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */
144#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */
145#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */
146
147#ifdef CONFIG_SND_PCM_XRUN_DEBUG
148
149#define xrun_debug(substream, mask) \
150 ((substream)->pstr->xrun_debug & (mask))
151#else
152#define xrun_debug(substream, mask) 0
153#endif
154
155#define dump_stack_on_xrun(substream) do { \
156 if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
157 dump_stack(); \
158 } while (0)
159
150static void xrun(struct snd_pcm_substream *substream) 160static void xrun(struct snd_pcm_substream *substream)
151{ 161{
152 struct snd_pcm_runtime *runtime = substream->runtime; 162 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -154,7 +164,7 @@ static void xrun(struct snd_pcm_substream *substream)
154 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 164 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
155 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 165 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
156 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 166 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
157 if (xrun_debug(substream, 1)) { 167 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
158 char name[16]; 168 char name[16];
159 pcm_debug_name(substream, name, sizeof(name)); 169 pcm_debug_name(substream, name, sizeof(name));
160 snd_printd(KERN_DEBUG "XRUN: %s\n", name); 170 snd_printd(KERN_DEBUG "XRUN: %s\n", name);
@@ -162,32 +172,101 @@ static void xrun(struct snd_pcm_substream *substream)
162 } 172 }
163} 173}
164 174
165static snd_pcm_uframes_t 175#ifdef CONFIG_SND_PCM_XRUN_DEBUG
166snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, 176#define hw_ptr_error(substream, fmt, args...) \
167 struct snd_pcm_runtime *runtime) 177 do { \
168{ 178 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
179 xrun_log_show(substream); \
180 if (printk_ratelimit()) { \
181 snd_printd("PCM: " fmt, ##args); \
182 } \
183 dump_stack_on_xrun(substream); \
184 } \
185 } while (0)
186
187#define XRUN_LOG_CNT 10
188
189struct hwptr_log_entry {
190 unsigned long jiffies;
169 snd_pcm_uframes_t pos; 191 snd_pcm_uframes_t pos;
192 snd_pcm_uframes_t period_size;
193 snd_pcm_uframes_t buffer_size;
194 snd_pcm_uframes_t old_hw_ptr;
195 snd_pcm_uframes_t hw_ptr_base;
196};
170 197
171 pos = substream->ops->pointer(substream); 198struct snd_pcm_hwptr_log {
172 if (pos == SNDRV_PCM_POS_XRUN) 199 unsigned int idx;
173 return pos; /* XRUN */ 200 unsigned int hit: 1;
174 if (pos >= runtime->buffer_size) { 201 struct hwptr_log_entry entries[XRUN_LOG_CNT];
175 if (printk_ratelimit()) { 202};
176 char name[16]; 203
177 pcm_debug_name(substream, name, sizeof(name)); 204static void xrun_log(struct snd_pcm_substream *substream,
178 snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, " 205 snd_pcm_uframes_t pos)
179 "buffer size = 0x%lx, period size = 0x%lx\n", 206{
180 name, pos, runtime->buffer_size, 207 struct snd_pcm_runtime *runtime = substream->runtime;
181 runtime->period_size); 208 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
182 } 209 struct hwptr_log_entry *entry;
183 pos = 0; 210
211 if (log == NULL) {
212 log = kzalloc(sizeof(*log), GFP_ATOMIC);
213 if (log == NULL)
214 return;
215 runtime->hwptr_log = log;
216 } else {
217 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
218 return;
184 } 219 }
185 pos -= pos % runtime->min_align; 220 entry = &log->entries[log->idx];
186 return pos; 221 entry->jiffies = jiffies;
222 entry->pos = pos;
223 entry->period_size = runtime->period_size;
224 entry->buffer_size = runtime->buffer_size;;
225 entry->old_hw_ptr = runtime->status->hw_ptr;
226 entry->hw_ptr_base = runtime->hw_ptr_base;
227 log->idx = (log->idx + 1) % XRUN_LOG_CNT;
187} 228}
188 229
189static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, 230static void xrun_log_show(struct snd_pcm_substream *substream)
190 struct snd_pcm_runtime *runtime) 231{
232 struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log;
233 struct hwptr_log_entry *entry;
234 char name[16];
235 unsigned int idx;
236 int cnt;
237
238 if (log == NULL)
239 return;
240 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
241 return;
242 pcm_debug_name(substream, name, sizeof(name));
243 for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
244 entry = &log->entries[idx];
245 if (entry->period_size == 0)
246 break;
247 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, "
248 "hwptr=%ld/%ld\n",
249 name, entry->jiffies, (unsigned long)entry->pos,
250 (unsigned long)entry->period_size,
251 (unsigned long)entry->buffer_size,
252 (unsigned long)entry->old_hw_ptr,
253 (unsigned long)entry->hw_ptr_base);
254 idx++;
255 idx %= XRUN_LOG_CNT;
256 }
257 log->hit = 1;
258}
259
260#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
261
262#define hw_ptr_error(substream, fmt, args...) do { } while (0)
263#define xrun_log(substream, pos) do { } while (0)
264#define xrun_log_show(substream) do { } while (0)
265
266#endif
267
268int snd_pcm_update_state(struct snd_pcm_substream *substream,
269 struct snd_pcm_runtime *runtime)
191{ 270{
192 snd_pcm_uframes_t avail; 271 snd_pcm_uframes_t avail;
193 272
@@ -209,88 +288,94 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
209 } 288 }
210 } 289 }
211 if (avail >= runtime->control->avail_min) 290 if (avail >= runtime->control->avail_min)
212 wake_up(&runtime->sleep); 291 wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
213 return 0; 292 return 0;
214} 293}
215 294
216#define hw_ptr_error(substream, fmt, args...) \ 295static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
217 do { \ 296 unsigned int in_interrupt)
218 if (xrun_debug(substream, 1)) { \
219 if (printk_ratelimit()) { \
220 snd_printd("PCM: " fmt, ##args); \
221 } \
222 dump_stack_on_xrun(substream); \
223 } \
224 } while (0)
225
226static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
227{ 297{
228 struct snd_pcm_runtime *runtime = substream->runtime; 298 struct snd_pcm_runtime *runtime = substream->runtime;
229 snd_pcm_uframes_t pos; 299 snd_pcm_uframes_t pos;
230 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_ptr_interrupt, hw_base; 300 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
231 snd_pcm_sframes_t hdelta, delta; 301 snd_pcm_sframes_t hdelta, delta;
232 unsigned long jdelta; 302 unsigned long jdelta;
233 303
234 old_hw_ptr = runtime->status->hw_ptr; 304 old_hw_ptr = runtime->status->hw_ptr;
235 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 305 pos = substream->ops->pointer(substream);
236 if (pos == SNDRV_PCM_POS_XRUN) { 306 if (pos == SNDRV_PCM_POS_XRUN) {
237 xrun(substream); 307 xrun(substream);
238 return -EPIPE; 308 return -EPIPE;
239 } 309 }
240 if (xrun_debug(substream, 8)) { 310 if (pos >= runtime->buffer_size) {
241 char name[16]; 311 if (printk_ratelimit()) {
242 pcm_debug_name(substream, name, sizeof(name)); 312 char name[16];
243 snd_printd("period_update: %s: pos=0x%x/0x%x/0x%x, " 313 pcm_debug_name(substream, name, sizeof(name));
244 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", 314 xrun_log_show(substream);
245 name, (unsigned int)pos, 315 snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
246 (unsigned int)runtime->period_size, 316 "buffer size = %ld, period size = %ld\n",
247 (unsigned int)runtime->buffer_size, 317 name, pos, runtime->buffer_size,
248 (unsigned long)old_hw_ptr, 318 runtime->period_size);
249 (unsigned long)runtime->hw_ptr_base, 319 }
250 (unsigned long)runtime->hw_ptr_interrupt); 320 pos = 0;
251 } 321 }
322 pos -= pos % runtime->min_align;
323 if (xrun_debug(substream, XRUN_DEBUG_LOG))
324 xrun_log(substream, pos);
252 hw_base = runtime->hw_ptr_base; 325 hw_base = runtime->hw_ptr_base;
253 new_hw_ptr = hw_base + pos; 326 new_hw_ptr = hw_base + pos;
254 hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; 327 if (in_interrupt) {
255 delta = new_hw_ptr - hw_ptr_interrupt; 328 /* we know that one period was processed */
256 if (hw_ptr_interrupt >= runtime->boundary) { 329 /* delta = "expected next hw_ptr" for in_interrupt != 0 */
257 hw_ptr_interrupt -= runtime->boundary; 330 delta = runtime->hw_ptr_interrupt + runtime->period_size;
258 if (hw_base < runtime->boundary / 2) 331 if (delta > new_hw_ptr) {
259 /* hw_base was already lapped; recalc delta */
260 delta = new_hw_ptr - hw_ptr_interrupt;
261 }
262 if (delta < 0) {
263 if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr)
264 delta += runtime->buffer_size;
265 if (delta < 0) {
266 hw_ptr_error(substream,
267 "Unexpected hw_pointer value "
268 "(stream=%i, pos=%ld, intr_ptr=%ld)\n",
269 substream->stream, (long)pos,
270 (long)hw_ptr_interrupt);
271#if 1
272 /* simply skipping the hwptr update seems more
273 * robust in some cases, e.g. on VMware with
274 * inaccurate timer source
275 */
276 return 0; /* skip this update */
277#else
278 /* rebase to interrupt position */
279 hw_base = new_hw_ptr = hw_ptr_interrupt;
280 /* align hw_base to buffer_size */
281 hw_base -= hw_base % runtime->buffer_size;
282 delta = 0;
283#endif
284 } else {
285 hw_base += runtime->buffer_size; 332 hw_base += runtime->buffer_size;
286 if (hw_base >= runtime->boundary) 333 if (hw_base >= runtime->boundary)
287 hw_base = 0; 334 hw_base = 0;
288 new_hw_ptr = hw_base + pos; 335 new_hw_ptr = hw_base + pos;
336 goto __delta;
289 } 337 }
290 } 338 }
339 /* new_hw_ptr might be lower than old_hw_ptr in case when */
340 /* pointer crosses the end of the ring buffer */
341 if (new_hw_ptr < old_hw_ptr) {
342 hw_base += runtime->buffer_size;
343 if (hw_base >= runtime->boundary)
344 hw_base = 0;
345 new_hw_ptr = hw_base + pos;
346 }
347 __delta:
348 delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary;
349 if (xrun_debug(substream, in_interrupt ?
350 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
351 char name[16];
352 pcm_debug_name(substream, name, sizeof(name));
353 snd_printd("%s_update: %s: pos=%u/%u/%u, "
354 "hwptr=%ld/%ld/%ld/%ld\n",
355 in_interrupt ? "period" : "hwptr",
356 name,
357 (unsigned int)pos,
358 (unsigned int)runtime->period_size,
359 (unsigned int)runtime->buffer_size,
360 (unsigned long)delta,
361 (unsigned long)old_hw_ptr,
362 (unsigned long)new_hw_ptr,
363 (unsigned long)runtime->hw_ptr_base);
364 }
365 /* something must be really wrong */
366 if (delta >= runtime->buffer_size + runtime->period_size) {
367 hw_ptr_error(substream,
368 "Unexpected hw_pointer value %s"
369 "(stream=%i, pos=%ld, new_hw_ptr=%ld, "
370 "old_hw_ptr=%ld)\n",
371 in_interrupt ? "[Q] " : "[P]",
372 substream->stream, (long)pos,
373 (long)new_hw_ptr, (long)old_hw_ptr);
374 return 0;
375 }
291 376
292 /* Do jiffies check only in xrun_debug mode */ 377 /* Do jiffies check only in xrun_debug mode */
293 if (!xrun_debug(substream, 4)) 378 if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK))
294 goto no_jiffies_check; 379 goto no_jiffies_check;
295 380
296 /* Skip the jiffies check for hardwares with BATCH flag. 381 /* Skip the jiffies check for hardwares with BATCH flag.
@@ -299,7 +384,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
299 */ 384 */
300 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) 385 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
301 goto no_jiffies_check; 386 goto no_jiffies_check;
302 hdelta = new_hw_ptr - old_hw_ptr; 387 hdelta = delta;
303 if (hdelta < runtime->delay) 388 if (hdelta < runtime->delay)
304 goto no_jiffies_check; 389 goto no_jiffies_check;
305 hdelta -= runtime->delay; 390 hdelta -= runtime->delay;
@@ -308,130 +393,68 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
308 delta = jdelta / 393 delta = jdelta /
309 (((runtime->period_size * HZ) / runtime->rate) 394 (((runtime->period_size * HZ) / runtime->rate)
310 + HZ/100); 395 + HZ/100);
396 /* move new_hw_ptr according jiffies not pos variable */
397 new_hw_ptr = old_hw_ptr;
398 hw_base = delta;
399 /* use loop to avoid checks for delta overflows */
400 /* the delta value is small or zero in most cases */
401 while (delta > 0) {
402 new_hw_ptr += runtime->period_size;
403 if (new_hw_ptr >= runtime->boundary)
404 new_hw_ptr -= runtime->boundary;
405 delta--;
406 }
407 /* align hw_base to buffer_size */
311 hw_ptr_error(substream, 408 hw_ptr_error(substream,
312 "hw_ptr skipping! [Q] " 409 "hw_ptr skipping! %s"
313 "(pos=%ld, delta=%ld, period=%ld, " 410 "(pos=%ld, delta=%ld, period=%ld, "
314 "jdelta=%lu/%lu/%lu)\n", 411 "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n",
412 in_interrupt ? "[Q] " : "",
315 (long)pos, (long)hdelta, 413 (long)pos, (long)hdelta,
316 (long)runtime->period_size, jdelta, 414 (long)runtime->period_size, jdelta,
317 ((hdelta * HZ) / runtime->rate), delta); 415 ((hdelta * HZ) / runtime->rate), hw_base,
318 hw_ptr_interrupt = runtime->hw_ptr_interrupt + 416 (unsigned long)old_hw_ptr,
319 runtime->period_size * delta; 417 (unsigned long)new_hw_ptr);
320 if (hw_ptr_interrupt >= runtime->boundary) 418 /* reset values to proper state */
321 hw_ptr_interrupt -= runtime->boundary;
322 /* rebase to interrupt position */
323 hw_base = new_hw_ptr = hw_ptr_interrupt;
324 /* align hw_base to buffer_size */
325 hw_base -= hw_base % runtime->buffer_size;
326 delta = 0; 419 delta = 0;
420 hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
327 } 421 }
328 no_jiffies_check: 422 no_jiffies_check:
329 if (delta > runtime->period_size + runtime->period_size / 2) { 423 if (delta > runtime->period_size + runtime->period_size / 2) {
330 hw_ptr_error(substream, 424 hw_ptr_error(substream,
331 "Lost interrupts? " 425 "Lost interrupts? %s"
332 "(stream=%i, delta=%ld, intr_ptr=%ld)\n", 426 "(stream=%i, delta=%ld, new_hw_ptr=%ld, "
427 "old_hw_ptr=%ld)\n",
428 in_interrupt ? "[Q] " : "",
333 substream->stream, (long)delta, 429 substream->stream, (long)delta,
334 (long)hw_ptr_interrupt); 430 (long)new_hw_ptr,
335 /* rebase hw_ptr_interrupt */ 431 (long)old_hw_ptr);
336 hw_ptr_interrupt =
337 new_hw_ptr - new_hw_ptr % runtime->period_size;
338 } 432 }
339 runtime->hw_ptr_interrupt = hw_ptr_interrupt; 433
434 if (runtime->status->hw_ptr == new_hw_ptr)
435 return 0;
340 436
341 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 437 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
342 runtime->silence_size > 0) 438 runtime->silence_size > 0)
343 snd_pcm_playback_silence(substream, new_hw_ptr); 439 snd_pcm_playback_silence(substream, new_hw_ptr);
344 440
345 if (runtime->status->hw_ptr == new_hw_ptr) 441 if (in_interrupt) {
346 return 0; 442 runtime->hw_ptr_interrupt = new_hw_ptr -
347 443 (new_hw_ptr % runtime->period_size);
444 }
348 runtime->hw_ptr_base = hw_base; 445 runtime->hw_ptr_base = hw_base;
349 runtime->status->hw_ptr = new_hw_ptr; 446 runtime->status->hw_ptr = new_hw_ptr;
350 runtime->hw_ptr_jiffies = jiffies; 447 runtime->hw_ptr_jiffies = jiffies;
351 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 448 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
352 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 449 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
353 450
354 return snd_pcm_update_hw_ptr_post(substream, runtime); 451 return snd_pcm_update_state(substream, runtime);
355} 452}
356 453
357/* CAUTION: call it with irq disabled */ 454/* CAUTION: call it with irq disabled */
358int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) 455int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
359{ 456{
360 struct snd_pcm_runtime *runtime = substream->runtime; 457 return snd_pcm_update_hw_ptr0(substream, 0);
361 snd_pcm_uframes_t pos;
362 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
363 snd_pcm_sframes_t delta;
364 unsigned long jdelta;
365
366 old_hw_ptr = runtime->status->hw_ptr;
367 pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
368 if (pos == SNDRV_PCM_POS_XRUN) {
369 xrun(substream);
370 return -EPIPE;
371 }
372 if (xrun_debug(substream, 16)) {
373 char name[16];
374 pcm_debug_name(substream, name, sizeof(name));
375 snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, "
376 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n",
377 name, (unsigned int)pos,
378 (unsigned int)runtime->period_size,
379 (unsigned int)runtime->buffer_size,
380 (unsigned long)old_hw_ptr,
381 (unsigned long)runtime->hw_ptr_base,
382 (unsigned long)runtime->hw_ptr_interrupt);
383 }
384
385 hw_base = runtime->hw_ptr_base;
386 new_hw_ptr = hw_base + pos;
387
388 delta = new_hw_ptr - old_hw_ptr;
389 jdelta = jiffies - runtime->hw_ptr_jiffies;
390 if (delta < 0) {
391 delta += runtime->buffer_size;
392 if (delta < 0) {
393 hw_ptr_error(substream,
394 "Unexpected hw_pointer value [2] "
395 "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n",
396 substream->stream, (long)pos,
397 (long)old_hw_ptr, jdelta);
398 return 0;
399 }
400 hw_base += runtime->buffer_size;
401 if (hw_base >= runtime->boundary)
402 hw_base = 0;
403 new_hw_ptr = hw_base + pos;
404 }
405 /* Do jiffies check only in xrun_debug mode */
406 if (!xrun_debug(substream, 4))
407 goto no_jiffies_check;
408 if (delta < runtime->delay)
409 goto no_jiffies_check;
410 delta -= runtime->delay;
411 if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
412 hw_ptr_error(substream,
413 "hw_ptr skipping! "
414 "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
415 (long)pos, (long)delta,
416 (long)runtime->period_size, jdelta,
417 ((delta * HZ) / runtime->rate));
418 return 0;
419 }
420 no_jiffies_check:
421 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
422 runtime->silence_size > 0)
423 snd_pcm_playback_silence(substream, new_hw_ptr);
424
425 if (runtime->status->hw_ptr == new_hw_ptr)
426 return 0;
427
428 runtime->hw_ptr_base = hw_base;
429 runtime->status->hw_ptr = new_hw_ptr;
430 runtime->hw_ptr_jiffies = jiffies;
431 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
432 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
433
434 return snd_pcm_update_hw_ptr_post(substream, runtime);
435} 458}
436 459
437/** 460/**
@@ -745,10 +768,13 @@ int snd_interval_ratnum(struct snd_interval *i,
745 unsigned int rats_count, struct snd_ratnum *rats, 768 unsigned int rats_count, struct snd_ratnum *rats,
746 unsigned int *nump, unsigned int *denp) 769 unsigned int *nump, unsigned int *denp)
747{ 770{
748 unsigned int best_num, best_diff, best_den; 771 unsigned int best_num, best_den;
772 int best_diff;
749 unsigned int k; 773 unsigned int k;
750 struct snd_interval t; 774 struct snd_interval t;
751 int err; 775 int err;
776 unsigned int result_num, result_den;
777 int result_diff;
752 778
753 best_num = best_den = best_diff = 0; 779 best_num = best_den = best_diff = 0;
754 for (k = 0; k < rats_count; ++k) { 780 for (k = 0; k < rats_count; ++k) {
@@ -758,7 +784,7 @@ int snd_interval_ratnum(struct snd_interval *i,
758 int diff; 784 int diff;
759 if (q == 0) 785 if (q == 0)
760 q = 1; 786 q = 1;
761 den = div_down(num, q); 787 den = div_up(num, q);
762 if (den < rats[k].den_min) 788 if (den < rats[k].den_min)
763 continue; 789 continue;
764 if (den > rats[k].den_max) 790 if (den > rats[k].den_max)
@@ -770,6 +796,8 @@ int snd_interval_ratnum(struct snd_interval *i,
770 den -= r; 796 den -= r;
771 } 797 }
772 diff = num - q * den; 798 diff = num - q * den;
799 if (diff < 0)
800 diff = -diff;
773 if (best_num == 0 || 801 if (best_num == 0 ||
774 diff * best_den < best_diff * den) { 802 diff * best_den < best_diff * den) {
775 best_diff = diff; 803 best_diff = diff;
@@ -784,6 +812,9 @@ int snd_interval_ratnum(struct snd_interval *i,
784 t.min = div_down(best_num, best_den); 812 t.min = div_down(best_num, best_den);
785 t.openmin = !!(best_num % best_den); 813 t.openmin = !!(best_num % best_den);
786 814
815 result_num = best_num;
816 result_diff = best_diff;
817 result_den = best_den;
787 best_num = best_den = best_diff = 0; 818 best_num = best_den = best_diff = 0;
788 for (k = 0; k < rats_count; ++k) { 819 for (k = 0; k < rats_count; ++k) {
789 unsigned int num = rats[k].num; 820 unsigned int num = rats[k].num;
@@ -794,7 +825,7 @@ int snd_interval_ratnum(struct snd_interval *i,
794 i->empty = 1; 825 i->empty = 1;
795 return -EINVAL; 826 return -EINVAL;
796 } 827 }
797 den = div_up(num, q); 828 den = div_down(num, q);
798 if (den > rats[k].den_max) 829 if (den > rats[k].den_max)
799 continue; 830 continue;
800 if (den < rats[k].den_min) 831 if (den < rats[k].den_min)
@@ -806,6 +837,8 @@ int snd_interval_ratnum(struct snd_interval *i,
806 den += rats[k].den_step - r; 837 den += rats[k].den_step - r;
807 } 838 }
808 diff = q * den - num; 839 diff = q * den - num;
840 if (diff < 0)
841 diff = -diff;
809 if (best_num == 0 || 842 if (best_num == 0 ||
810 diff * best_den < best_diff * den) { 843 diff * best_den < best_diff * den) {
811 best_diff = diff; 844 best_diff = diff;
@@ -825,10 +858,14 @@ int snd_interval_ratnum(struct snd_interval *i,
825 return err; 858 return err;
826 859
827 if (snd_interval_single(i)) { 860 if (snd_interval_single(i)) {
861 if (best_diff * result_den < result_diff * best_den) {
862 result_num = best_num;
863 result_den = best_den;
864 }
828 if (nump) 865 if (nump)
829 *nump = best_num; 866 *nump = result_num;
830 if (denp) 867 if (denp)
831 *denp = best_den; 868 *denp = result_den;
832 } 869 }
833 return err; 870 return err;
834} 871}
@@ -1643,7 +1680,7 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1643 1680
1644 snd_pcm_stream_lock_irqsave(substream, flags); 1681 snd_pcm_stream_lock_irqsave(substream, flags);
1645 if (!snd_pcm_running(substream) || 1682 if (!snd_pcm_running(substream) ||
1646 snd_pcm_update_hw_ptr_interrupt(substream) < 0) 1683 snd_pcm_update_hw_ptr0(substream, 1) < 0)
1647 goto _end; 1684 goto _end;
1648 1685
1649 if (substream->timer_running) 1686 if (substream->timer_running)
@@ -1674,7 +1711,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1674 long tout; 1711 long tout;
1675 1712
1676 init_waitqueue_entry(&wait, current); 1713 init_waitqueue_entry(&wait, current);
1677 add_wait_queue(&runtime->sleep, &wait); 1714 add_wait_queue(&runtime->tsleep, &wait);
1678 for (;;) { 1715 for (;;) {
1679 if (signal_pending(current)) { 1716 if (signal_pending(current)) {
1680 err = -ERESTARTSYS; 1717 err = -ERESTARTSYS;
@@ -1717,7 +1754,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1717 break; 1754 break;
1718 } 1755 }
1719 _endloop: 1756 _endloop:
1720 remove_wait_queue(&runtime->sleep, &wait); 1757 remove_wait_queue(&runtime->tsleep, &wait);
1721 *availp = avail; 1758 *availp = avail;
1722 return err; 1759 return err;
1723} 1760}
@@ -1776,6 +1813,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1776 goto _end_unlock; 1813 goto _end_unlock;
1777 } 1814 }
1778 1815
1816 runtime->twake = 1;
1779 while (size > 0) { 1817 while (size > 0) {
1780 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1818 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1781 snd_pcm_uframes_t avail; 1819 snd_pcm_uframes_t avail;
@@ -1797,15 +1835,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1797 if (frames > cont) 1835 if (frames > cont)
1798 frames = cont; 1836 frames = cont;
1799 if (snd_BUG_ON(!frames)) { 1837 if (snd_BUG_ON(!frames)) {
1838 runtime->twake = 0;
1800 snd_pcm_stream_unlock_irq(substream); 1839 snd_pcm_stream_unlock_irq(substream);
1801 return -EINVAL; 1840 return -EINVAL;
1802 } 1841 }
1803 appl_ptr = runtime->control->appl_ptr; 1842 appl_ptr = runtime->control->appl_ptr;
1804 appl_ofs = appl_ptr % runtime->buffer_size; 1843 appl_ofs = appl_ptr % runtime->buffer_size;
1805 snd_pcm_stream_unlock_irq(substream); 1844 snd_pcm_stream_unlock_irq(substream);
1806 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 1845 err = transfer(substream, appl_ofs, data, offset, frames);
1807 goto _end;
1808 snd_pcm_stream_lock_irq(substream); 1846 snd_pcm_stream_lock_irq(substream);
1847 if (err < 0)
1848 goto _end_unlock;
1809 switch (runtime->status->state) { 1849 switch (runtime->status->state) {
1810 case SNDRV_PCM_STATE_XRUN: 1850 case SNDRV_PCM_STATE_XRUN:
1811 err = -EPIPE; 1851 err = -EPIPE;
@@ -1834,8 +1874,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1834 } 1874 }
1835 } 1875 }
1836 _end_unlock: 1876 _end_unlock:
1877 runtime->twake = 0;
1878 if (xfer > 0 && err >= 0)
1879 snd_pcm_update_state(substream, runtime);
1837 snd_pcm_stream_unlock_irq(substream); 1880 snd_pcm_stream_unlock_irq(substream);
1838 _end:
1839 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 1881 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1840} 1882}
1841 1883
@@ -1993,6 +2035,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1993 goto _end_unlock; 2035 goto _end_unlock;
1994 } 2036 }
1995 2037
2038 runtime->twake = 1;
1996 while (size > 0) { 2039 while (size > 0) {
1997 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2040 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1998 snd_pcm_uframes_t avail; 2041 snd_pcm_uframes_t avail;
@@ -2021,15 +2064,17 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2021 if (frames > cont) 2064 if (frames > cont)
2022 frames = cont; 2065 frames = cont;
2023 if (snd_BUG_ON(!frames)) { 2066 if (snd_BUG_ON(!frames)) {
2067 runtime->twake = 0;
2024 snd_pcm_stream_unlock_irq(substream); 2068 snd_pcm_stream_unlock_irq(substream);
2025 return -EINVAL; 2069 return -EINVAL;
2026 } 2070 }
2027 appl_ptr = runtime->control->appl_ptr; 2071 appl_ptr = runtime->control->appl_ptr;
2028 appl_ofs = appl_ptr % runtime->buffer_size; 2072 appl_ofs = appl_ptr % runtime->buffer_size;
2029 snd_pcm_stream_unlock_irq(substream); 2073 snd_pcm_stream_unlock_irq(substream);
2030 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2074 err = transfer(substream, appl_ofs, data, offset, frames);
2031 goto _end;
2032 snd_pcm_stream_lock_irq(substream); 2075 snd_pcm_stream_lock_irq(substream);
2076 if (err < 0)
2077 goto _end_unlock;
2033 switch (runtime->status->state) { 2078 switch (runtime->status->state) {
2034 case SNDRV_PCM_STATE_XRUN: 2079 case SNDRV_PCM_STATE_XRUN:
2035 err = -EPIPE; 2080 err = -EPIPE;
@@ -2052,8 +2097,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2052 xfer += frames; 2097 xfer += frames;
2053 } 2098 }
2054 _end_unlock: 2099 _end_unlock:
2100 runtime->twake = 0;
2101 if (xfer > 0 && err >= 0)
2102 snd_pcm_update_state(substream, runtime);
2055 snd_pcm_stream_unlock_irq(substream); 2103 snd_pcm_stream_unlock_irq(substream);
2056 _end:
2057 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2104 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
2058} 2105}
2059 2106
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index caa7796bc2f5..917e4055ee30 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -22,7 +22,9 @@
22#include <asm/io.h> 22#include <asm/io.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/slab.h>
25#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/vmalloc.h>
26#include <sound/core.h> 28#include <sound/core.h>
27#include <sound/pcm.h> 29#include <sound/pcm.h>
28#include <sound/info.h> 30#include <sound/info.h>
@@ -434,3 +436,57 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
434} 436}
435 437
436EXPORT_SYMBOL(snd_pcm_lib_free_pages); 438EXPORT_SYMBOL(snd_pcm_lib_free_pages);
439
440int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
441 size_t size, gfp_t gfp_flags)
442{
443 struct snd_pcm_runtime *runtime;
444
445 if (PCM_RUNTIME_CHECK(substream))
446 return -EINVAL;
447 runtime = substream->runtime;
448 if (runtime->dma_area) {
449 if (runtime->dma_bytes >= size)
450 return 0; /* already large enough */
451 vfree(runtime->dma_area);
452 }
453 runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
454 if (!runtime->dma_area)
455 return -ENOMEM;
456 runtime->dma_bytes = size;
457 return 1;
458}
459EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer);
460
461/**
462 * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer
463 * @substream: the substream with a buffer allocated by
464 * snd_pcm_lib_alloc_vmalloc_buffer()
465 */
466int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream)
467{
468 struct snd_pcm_runtime *runtime;
469
470 if (PCM_RUNTIME_CHECK(substream))
471 return -EINVAL;
472 runtime = substream->runtime;
473 vfree(runtime->dma_area);
474 runtime->dma_area = NULL;
475 return 0;
476}
477EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer);
478
479/**
480 * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct
481 * @substream: the substream with a buffer allocated by
482 * snd_pcm_lib_alloc_vmalloc_buffer()
483 * @offset: offset in the buffer
484 *
485 * This function is to be used as the page callback in the PCM ops.
486 */
487struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
488 unsigned long offset)
489{
490 return vmalloc_to_page(substream->runtime->dma_area + offset);
491}
492EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ab73edf2c89a..20b5982c996b 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -26,6 +26,8 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/pm_qos_params.h> 27#include <linux/pm_qos_params.h>
28#include <linux/uio.h> 28#include <linux/uio.h>
29#include <linux/dma-mapping.h>
30#include <linux/math64.h>
29#include <sound/core.h> 31#include <sound/core.h>
30#include <sound/control.h> 32#include <sound/control.h>
31#include <sound/info.h> 33#include <sound/info.h>
@@ -34,6 +36,9 @@
34#include <sound/timer.h> 36#include <sound/timer.h>
35#include <sound/minors.h> 37#include <sound/minors.h>
36#include <asm/io.h> 38#include <asm/io.h>
39#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
40#include <dma-coherence.h>
41#endif
37 42
38/* 43/*
39 * Compatibility 44 * Compatibility
@@ -314,10 +319,10 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
314 if (!params->info) 319 if (!params->info)
315 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; 320 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
316 if (!params->fifo_size) { 321 if (!params->fifo_size) {
317 if (snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) == 322 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
318 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) && 323 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
319 snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) == 324 if (snd_mask_min(m) == snd_mask_max(m) &&
320 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) { 325 snd_interval_min(i) == snd_interval_max(i)) {
321 changed = substream->ops->ioctl(substream, 326 changed = substream->ops->ioctl(substream,
322 SNDRV_PCM_IOCTL1_FIFO_SIZE, params); 327 SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
323 if (changed < 0) 328 if (changed < 0)
@@ -365,6 +370,38 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
365 return usecs; 370 return usecs;
366} 371}
367 372
373static int calc_boundary(struct snd_pcm_runtime *runtime)
374{
375 u_int64_t boundary;
376
377 boundary = (u_int64_t)runtime->buffer_size *
378 (u_int64_t)runtime->period_size;
379#if BITS_PER_LONG < 64
380 /* try to find lowest common multiple for buffer and period */
381 if (boundary > LONG_MAX - runtime->buffer_size) {
382 u_int32_t remainder = -1;
383 u_int32_t divident = runtime->buffer_size;
384 u_int32_t divisor = runtime->period_size;
385 while (remainder) {
386 remainder = divident % divisor;
387 if (remainder) {
388 divident = divisor;
389 divisor = remainder;
390 }
391 }
392 boundary = div_u64(boundary, divisor);
393 if (boundary > LONG_MAX - runtime->buffer_size)
394 return -ERANGE;
395 }
396#endif
397 if (boundary == 0)
398 return -ERANGE;
399 runtime->boundary = boundary;
400 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
401 runtime->boundary *= 2;
402 return 0;
403}
404
368static int snd_pcm_hw_params(struct snd_pcm_substream *substream, 405static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params) 406 struct snd_pcm_hw_params *params)
370{ 407{
@@ -440,9 +477,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
440 runtime->stop_threshold = runtime->buffer_size; 477 runtime->stop_threshold = runtime->buffer_size;
441 runtime->silence_threshold = 0; 478 runtime->silence_threshold = 0;
442 runtime->silence_size = 0; 479 runtime->silence_size = 0;
443 runtime->boundary = runtime->buffer_size; 480 err = calc_boundary(runtime);
444 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) 481 if (err < 0)
445 runtime->boundary *= 2; 482 goto _error;
446 483
447 snd_pcm_timer_resolution_change(substream); 484 snd_pcm_timer_resolution_change(substream);
448 runtime->status->state = SNDRV_PCM_STATE_SETUP; 485 runtime->status->state = SNDRV_PCM_STATE_SETUP;
@@ -515,6 +552,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
515 struct snd_pcm_sw_params *params) 552 struct snd_pcm_sw_params *params)
516{ 553{
517 struct snd_pcm_runtime *runtime; 554 struct snd_pcm_runtime *runtime;
555 int err;
518 556
519 if (PCM_RUNTIME_CHECK(substream)) 557 if (PCM_RUNTIME_CHECK(substream))
520 return -ENXIO; 558 return -ENXIO;
@@ -539,6 +577,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
539 if (params->silence_threshold > runtime->buffer_size) 577 if (params->silence_threshold > runtime->buffer_size)
540 return -EINVAL; 578 return -EINVAL;
541 } 579 }
580 err = 0;
542 snd_pcm_stream_lock_irq(substream); 581 snd_pcm_stream_lock_irq(substream);
543 runtime->tstamp_mode = params->tstamp_mode; 582 runtime->tstamp_mode = params->tstamp_mode;
544 runtime->period_step = params->period_step; 583 runtime->period_step = params->period_step;
@@ -552,10 +591,10 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
552 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 591 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
553 runtime->silence_size > 0) 592 runtime->silence_size > 0)
554 snd_pcm_playback_silence(substream, ULONG_MAX); 593 snd_pcm_playback_silence(substream, ULONG_MAX);
555 wake_up(&runtime->sleep); 594 err = snd_pcm_update_state(substream, runtime);
556 } 595 }
557 snd_pcm_stream_unlock_irq(substream); 596 snd_pcm_stream_unlock_irq(substream);
558 return 0; 597 return err;
559} 598}
560 599
561static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream, 600static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
@@ -916,6 +955,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
916 runtime->status->state = state; 955 runtime->status->state = state;
917 } 956 }
918 wake_up(&runtime->sleep); 957 wake_up(&runtime->sleep);
958 wake_up(&runtime->tsleep);
919} 959}
920 960
921static struct action_ops snd_pcm_action_stop = { 961static struct action_ops snd_pcm_action_stop = {
@@ -1001,6 +1041,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1001 SNDRV_TIMER_EVENT_MPAUSE, 1041 SNDRV_TIMER_EVENT_MPAUSE,
1002 &runtime->trigger_tstamp); 1042 &runtime->trigger_tstamp);
1003 wake_up(&runtime->sleep); 1043 wake_up(&runtime->sleep);
1044 wake_up(&runtime->tsleep);
1004 } else { 1045 } else {
1005 runtime->status->state = SNDRV_PCM_STATE_RUNNING; 1046 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1006 if (substream->timer) 1047 if (substream->timer)
@@ -1058,6 +1099,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1058 runtime->status->suspended_state = runtime->status->state; 1099 runtime->status->suspended_state = runtime->status->state;
1059 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; 1100 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1060 wake_up(&runtime->sleep); 1101 wake_up(&runtime->sleep);
1102 wake_up(&runtime->tsleep);
1061} 1103}
1062 1104
1063static struct action_ops snd_pcm_action_suspend = { 1105static struct action_ops snd_pcm_action_suspend = {
@@ -1917,13 +1959,13 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
1917 1959
1918 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 1960 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
1919 hw->rate_min, hw->rate_max); 1961 hw->rate_min, hw->rate_max);
1920 if (err < 0) 1962 if (err < 0)
1921 return err; 1963 return err;
1922 1964
1923 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1965 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1924 hw->period_bytes_min, hw->period_bytes_max); 1966 hw->period_bytes_min, hw->period_bytes_max);
1925 if (err < 0) 1967 if (err < 0)
1926 return err; 1968 return err;
1927 1969
1928 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, 1970 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS,
1929 hw->periods_min, hw->periods_max); 1971 hw->periods_min, hw->periods_max);
@@ -3061,6 +3103,27 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3061} 3103}
3062#endif /* coherent mmap */ 3104#endif /* coherent mmap */
3063 3105
3106static inline struct page *
3107snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
3108{
3109 void *vaddr = substream->runtime->dma_area + ofs;
3110#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3111 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3112 return virt_to_page(CAC_ADDR(vaddr));
3113#endif
3114#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE)
3115 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
3116 dma_addr_t addr = substream->runtime->dma_addr + ofs;
3117 addr -= get_dma_offset(substream->dma_buffer.dev.dev);
3118 /* assume dma_handle set via pfn_to_phys() in
3119 * mm/dma-noncoherent.c
3120 */
3121 return pfn_to_page(addr >> PAGE_SHIFT);
3122 }
3123#endif
3124 return virt_to_page(vaddr);
3125}
3126
3064/* 3127/*
3065 * fault callback for mmapping a RAM page 3128 * fault callback for mmapping a RAM page
3066 */ 3129 */
@@ -3071,7 +3134,6 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3071 struct snd_pcm_runtime *runtime; 3134 struct snd_pcm_runtime *runtime;
3072 unsigned long offset; 3135 unsigned long offset;
3073 struct page * page; 3136 struct page * page;
3074 void *vaddr;
3075 size_t dma_bytes; 3137 size_t dma_bytes;
3076 3138
3077 if (substream == NULL) 3139 if (substream == NULL)
@@ -3081,36 +3143,57 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3081 dma_bytes = PAGE_ALIGN(runtime->dma_bytes); 3143 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3082 if (offset > dma_bytes - PAGE_SIZE) 3144 if (offset > dma_bytes - PAGE_SIZE)
3083 return VM_FAULT_SIGBUS; 3145 return VM_FAULT_SIGBUS;
3084 if (substream->ops->page) { 3146 if (substream->ops->page)
3085 page = substream->ops->page(substream, offset); 3147 page = substream->ops->page(substream, offset);
3086 if (!page) 3148 else
3087 return VM_FAULT_SIGBUS; 3149 page = snd_pcm_default_page_ops(substream, offset);
3088 } else { 3150 if (!page)
3089 vaddr = runtime->dma_area + offset; 3151 return VM_FAULT_SIGBUS;
3090 page = virt_to_page(vaddr);
3091 }
3092 get_page(page); 3152 get_page(page);
3093 vmf->page = page; 3153 vmf->page = page;
3094 return 0; 3154 return 0;
3095} 3155}
3096 3156
3097static const struct vm_operations_struct snd_pcm_vm_ops_data = 3157static const struct vm_operations_struct snd_pcm_vm_ops_data = {
3098{ 3158 .open = snd_pcm_mmap_data_open,
3159 .close = snd_pcm_mmap_data_close,
3160};
3161
3162static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
3099 .open = snd_pcm_mmap_data_open, 3163 .open = snd_pcm_mmap_data_open,
3100 .close = snd_pcm_mmap_data_close, 3164 .close = snd_pcm_mmap_data_close,
3101 .fault = snd_pcm_mmap_data_fault, 3165 .fault = snd_pcm_mmap_data_fault,
3102}; 3166};
3103 3167
3168#ifndef ARCH_HAS_DMA_MMAP_COHERENT
3169/* This should be defined / handled globally! */
3170#ifdef CONFIG_ARM
3171#define ARCH_HAS_DMA_MMAP_COHERENT
3172#endif
3173#endif
3174
3104/* 3175/*
3105 * mmap the DMA buffer on RAM 3176 * mmap the DMA buffer on RAM
3106 */ 3177 */
3107static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, 3178static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3108 struct vm_area_struct *area) 3179 struct vm_area_struct *area)
3109{ 3180{
3110 area->vm_ops = &snd_pcm_vm_ops_data;
3111 area->vm_private_data = substream;
3112 area->vm_flags |= VM_RESERVED; 3181 area->vm_flags |= VM_RESERVED;
3113 atomic_inc(&substream->mmap_count); 3182#ifdef ARCH_HAS_DMA_MMAP_COHERENT
3183 if (!substream->ops->page &&
3184 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3185 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
3186 area,
3187 substream->runtime->dma_area,
3188 substream->runtime->dma_addr,
3189 area->vm_end - area->vm_start);
3190#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3191 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
3192 !plat_device_is_coherent(substream->dma_buffer.dev.dev))
3193 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3194#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
3195 /* mmap with fault handler */
3196 area->vm_ops = &snd_pcm_vm_ops_data_fault;
3114 return 0; 3197 return 0;
3115} 3198}
3116 3199
@@ -3118,23 +3201,13 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3118 * mmap the DMA buffer on I/O memory area 3201 * mmap the DMA buffer on I/O memory area
3119 */ 3202 */
3120#if SNDRV_PCM_INFO_MMAP_IOMEM 3203#if SNDRV_PCM_INFO_MMAP_IOMEM
3121static const struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
3122{
3123 .open = snd_pcm_mmap_data_open,
3124 .close = snd_pcm_mmap_data_close,
3125};
3126
3127int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, 3204int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3128 struct vm_area_struct *area) 3205 struct vm_area_struct *area)
3129{ 3206{
3130 long size; 3207 long size;
3131 unsigned long offset; 3208 unsigned long offset;
3132 3209
3133#ifdef pgprot_noncached
3134 area->vm_page_prot = pgprot_noncached(area->vm_page_prot); 3210 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3135#endif
3136 area->vm_ops = &snd_pcm_vm_ops_data_mmio;
3137 area->vm_private_data = substream;
3138 area->vm_flags |= VM_IO; 3211 area->vm_flags |= VM_IO;
3139 size = area->vm_end - area->vm_start; 3212 size = area->vm_end - area->vm_start;
3140 offset = area->vm_pgoff << PAGE_SHIFT; 3213 offset = area->vm_pgoff << PAGE_SHIFT;
@@ -3142,13 +3215,21 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3142 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, 3215 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
3143 size, area->vm_page_prot)) 3216 size, area->vm_page_prot))
3144 return -EAGAIN; 3217 return -EAGAIN;
3145 atomic_inc(&substream->mmap_count);
3146 return 0; 3218 return 0;
3147} 3219}
3148 3220
3149EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); 3221EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3150#endif /* SNDRV_PCM_INFO_MMAP */ 3222#endif /* SNDRV_PCM_INFO_MMAP */
3151 3223
3224/* mmap callback with pgprot_noncached */
3225int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream,
3226 struct vm_area_struct *area)
3227{
3228 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3229 return snd_pcm_default_mmap(substream, area);
3230}
3231EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached);
3232
3152/* 3233/*
3153 * mmap DMA buffer 3234 * mmap DMA buffer
3154 */ 3235 */
@@ -3159,6 +3240,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3159 long size; 3240 long size;
3160 unsigned long offset; 3241 unsigned long offset;
3161 size_t dma_bytes; 3242 size_t dma_bytes;
3243 int err;
3162 3244
3163 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 3245 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3164 if (!(area->vm_flags & (VM_WRITE|VM_READ))) 3246 if (!(area->vm_flags & (VM_WRITE|VM_READ)))
@@ -3183,10 +3265,15 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3183 if (offset > dma_bytes - size) 3265 if (offset > dma_bytes - size)
3184 return -EINVAL; 3266 return -EINVAL;
3185 3267
3268 area->vm_ops = &snd_pcm_vm_ops_data;
3269 area->vm_private_data = substream;
3186 if (substream->ops->mmap) 3270 if (substream->ops->mmap)
3187 return substream->ops->mmap(substream, area); 3271 err = substream->ops->mmap(substream, area);
3188 else 3272 else
3189 return snd_pcm_default_mmap(substream, area); 3273 err = snd_pcm_default_mmap(substream, area);
3274 if (!err)
3275 atomic_inc(&substream->mmap_count);
3276 return err;
3190} 3277}
3191 3278
3192EXPORT_SYMBOL(snd_pcm_mmap_data); 3279EXPORT_SYMBOL(snd_pcm_mmap_data);
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index ca8068b63d6c..b01d9481d632 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/time.h> 22#include <linux/time.h>
23#include <linux/gcd.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/timer.h> 26#include <sound/timer.h>
@@ -28,22 +29,6 @@
28 * Timer functions 29 * Timer functions
29 */ 30 */
30 31
31/* Greatest common divisor */
32static unsigned long gcd(unsigned long a, unsigned long b)
33{
34 unsigned long r;
35 if (a < b) {
36 r = a;
37 a = b;
38 b = r;
39 }
40 while ((r = a % b) != 0) {
41 a = b;
42 b = r;
43 }
44 return b;
45}
46
47void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) 32void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
48{ 33{
49 unsigned long rate, mult, fsize, l, post; 34 unsigned long rate, mult, fsize, l, post;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 70d6f25ba526..0f5a194695d9 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -242,8 +242,6 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
242 return -ENXIO; 242 return -ENXIO;
243 if (subdevice >= 0 && subdevice >= s->substream_count) 243 if (subdevice >= 0 && subdevice >= s->substream_count)
244 return -ENODEV; 244 return -ENODEV;
245 if (s->substream_opened >= s->substream_count)
246 return -EAGAIN;
247 245
248 list_for_each_entry(substream, &s->substreams, list) { 246 list_for_each_entry(substream, &s->substreams, list) {
249 if (substream->opened) { 247 if (substream->opened) {
@@ -280,9 +278,10 @@ static int open_substream(struct snd_rawmidi *rmidi,
280 substream->active_sensing = 0; 278 substream->active_sensing = 0;
281 if (mode & SNDRV_RAWMIDI_LFLG_APPEND) 279 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
282 substream->append = 1; 280 substream->append = 1;
281 substream->pid = get_pid(task_pid(current));
282 rmidi->streams[substream->stream].substream_opened++;
283 } 283 }
284 substream->use_count++; 284 substream->use_count++;
285 rmidi->streams[substream->stream].substream_opened++;
286 return 0; 285 return 0;
287} 286}
288 287
@@ -413,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
413 subdevice = -1; 412 subdevice = -1;
414 read_lock(&card->ctl_files_rwlock); 413 read_lock(&card->ctl_files_rwlock);
415 list_for_each_entry(kctl, &card->ctl_files, list) { 414 list_for_each_entry(kctl, &card->ctl_files, list) {
416 if (kctl->pid == current->pid) { 415 if (kctl->pid == task_pid(current)) {
417 subdevice = kctl->prefer_rawmidi_subdevice; 416 subdevice = kctl->prefer_rawmidi_subdevice;
418 if (subdevice != -1) 417 if (subdevice != -1)
419 break; 418 break;
@@ -466,7 +465,6 @@ static void close_substream(struct snd_rawmidi *rmidi,
466 struct snd_rawmidi_substream *substream, 465 struct snd_rawmidi_substream *substream,
467 int cleanup) 466 int cleanup)
468{ 467{
469 rmidi->streams[substream->stream].substream_opened--;
470 if (--substream->use_count) 468 if (--substream->use_count)
471 return; 469 return;
472 470
@@ -491,6 +489,9 @@ static void close_substream(struct snd_rawmidi *rmidi,
491 snd_rawmidi_runtime_free(substream); 489 snd_rawmidi_runtime_free(substream);
492 substream->opened = 0; 490 substream->opened = 0;
493 substream->append = 0; 491 substream->append = 0;
492 put_pid(substream->pid);
493 substream->pid = NULL;
494 rmidi->streams[substream->stream].substream_opened--;
494} 495}
495 496
496static void rawmidi_release_priv(struct snd_rawmidi_file *rfile) 497static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
@@ -1256,7 +1257,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1256 break; 1257 break;
1257 count -= count1; 1258 count -= count1;
1258 } 1259 }
1259 if (file->f_flags & O_SYNC) { 1260 if (file->f_flags & O_DSYNC) {
1260 spin_lock_irq(&runtime->lock); 1261 spin_lock_irq(&runtime->lock);
1261 while (runtime->avail != runtime->buffer_size) { 1262 while (runtime->avail != runtime->buffer_size) {
1262 wait_queue_t wait; 1263 wait_queue_t wait;
@@ -1338,6 +1339,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1338 substream->number, 1339 substream->number,
1339 (unsigned long) substream->bytes); 1340 (unsigned long) substream->bytes);
1340 if (substream->opened) { 1341 if (substream->opened) {
1342 snd_iprintf(buffer,
1343 " Owner PID : %d\n",
1344 pid_vnr(substream->pid));
1341 runtime = substream->runtime; 1345 runtime = substream->runtime;
1342 snd_iprintf(buffer, 1346 snd_iprintf(buffer,
1343 " Mode : %s\n" 1347 " Mode : %s\n"
@@ -1359,6 +1363,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1359 substream->number, 1363 substream->number,
1360 (unsigned long) substream->bytes); 1364 (unsigned long) substream->bytes);
1361 if (substream->opened) { 1365 if (substream->opened) {
1366 snd_iprintf(buffer,
1367 " Owner PID : %d\n",
1368 pid_vnr(substream->pid));
1362 runtime = substream->runtime; 1369 runtime = substream->runtime;
1363 snd_iprintf(buffer, 1370 snd_iprintf(buffer,
1364 " Buffer size : %lu\n" 1371 " Buffer size : %lu\n"
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index d0d721c22eac..685712276ac9 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -29,6 +29,7 @@
29#include "seq_oss_event.h" 29#include "seq_oss_event.h"
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32#include <linux/slab.h>
32 33
33/* 34/*
34 * common variables 35 * common variables
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 9dfb2f77be60..677dc84590c7 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -28,6 +28,7 @@
28#include <sound/seq_midi_event.h> 28#include <sound/seq_midi_event.h>
29#include "../seq_lock.h" 29#include "../seq_lock.h"
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/slab.h>
31 32
32 33
33/* 34/*
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index f5de79f29f1e..73661c4ab82a 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -25,6 +25,7 @@
25#include <sound/seq_oss_legacy.h> 25#include <sound/seq_oss_legacy.h>
26#include "../seq_lock.h" 26#include "../seq_lock.h"
27#include <linux/wait.h> 27#include <linux/wait.h>
28#include <linux/slab.h>
28 29
29/* 30/*
30 * constants 31 * constants
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 945a27c34a9d..ee44ab9593c0 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -24,6 +24,7 @@
24#include "seq_oss_midi.h" 24#include "seq_oss_midi.h"
25#include "../seq_lock.h" 25#include "../seq_lock.h"
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/slab.h>
27 28
28/* 29/*
29 * constants 30 * constants
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index c440fdacec93..ab59cbfbcaf2 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -23,6 +23,7 @@
23#include "seq_oss_timer.h" 23#include "seq_oss_timer.h"
24#include "seq_oss_event.h" 24#include "seq_oss_event.h"
25#include <sound/seq_oss_legacy.h> 25#include <sound/seq_oss_legacy.h>
26#include <linux/slab.h>
26 27
27/* 28/*
28 */ 29 */
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 217424858191..d50338bbc21f 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -27,6 +27,7 @@
27#include "../seq_lock.h" 27#include "../seq_lock.h"
28#include "../seq_clientmgr.h" 28#include "../seq_clientmgr.h"
29#include <linux/wait.h> 29#include <linux/wait.h>
30#include <linux/slab.h>
30 31
31 32
32/* 33/*
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 8ca2be339f3b..48eca9ff9ee7 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -2190,7 +2190,7 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
2190 if (p->cmd == cmd) 2190 if (p->cmd == cmd)
2191 return p->func(client, arg); 2191 return p->func(client, arg);
2192 } 2192 }
2193 snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n", 2193 snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2194 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2194 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
2195 return -ENOTTY; 2195 return -ENOTTY;
2196} 2196}
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index c956fe462569..81f7c109dc46 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -21,6 +21,7 @@
21/* This file included from seq.c */ 21/* This file included from seq.c */
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/slab.h>
24 25
25struct snd_seq_port_info32 { 26struct snd_seq_port_info32 {
26 struct snd_seq_addr addr; /* client/port numbers */ 27 struct snd_seq_addr addr; /* client/port numbers */
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index 77884e62b648..c38b90cf3cb0 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include "seq_system.h" 25#include "seq_system.h"
25#include "seq_timer.h" 26#include "seq_timer.h"
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index f745c317d6af..160b1bd0cd62 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -33,22 +33,21 @@
33 33
34#define SKEW_BASE 0x10000 /* 16bit shift */ 34#define SKEW_BASE 0x10000 /* 16bit shift */
35 35
36static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer_tick *tick, 36static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer *tmr)
37 int tempo, int ppq)
38{ 37{
39 if (tempo < 1000000) 38 if (tmr->tempo < 1000000)
40 tick->resolution = (tempo * 1000) / ppq; 39 tmr->tick.resolution = (tmr->tempo * 1000) / tmr->ppq;
41 else { 40 else {
42 /* might overflow.. */ 41 /* might overflow.. */
43 unsigned int s; 42 unsigned int s;
44 s = tempo % ppq; 43 s = tmr->tempo % tmr->ppq;
45 s = (s * 1000) / ppq; 44 s = (s * 1000) / tmr->ppq;
46 tick->resolution = (tempo / ppq) * 1000; 45 tmr->tick.resolution = (tmr->tempo / tmr->ppq) * 1000;
47 tick->resolution += s; 46 tmr->tick.resolution += s;
48 } 47 }
49 if (tick->resolution <= 0) 48 if (tmr->tick.resolution <= 0)
50 tick->resolution = 1; 49 tmr->tick.resolution = 1;
51 snd_seq_timer_update_tick(tick, 0); 50 snd_seq_timer_update_tick(&tmr->tick, 0);
52} 51}
53 52
54/* create new timer (constructor) */ 53/* create new timer (constructor) */
@@ -96,7 +95,7 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
96 /* setup defaults */ 95 /* setup defaults */
97 tmr->ppq = 96; /* 96 PPQ */ 96 tmr->ppq = 96; /* 96 PPQ */
98 tmr->tempo = 500000; /* 120 BPM */ 97 tmr->tempo = 500000; /* 120 BPM */
99 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 98 snd_seq_timer_set_tick_resolution(tmr);
100 tmr->running = 0; 99 tmr->running = 0;
101 100
102 tmr->type = SNDRV_SEQ_TIMER_ALSA; 101 tmr->type = SNDRV_SEQ_TIMER_ALSA;
@@ -180,7 +179,7 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
180 spin_lock_irqsave(&tmr->lock, flags); 179 spin_lock_irqsave(&tmr->lock, flags);
181 if ((unsigned int)tempo != tmr->tempo) { 180 if ((unsigned int)tempo != tmr->tempo) {
182 tmr->tempo = tempo; 181 tmr->tempo = tempo;
183 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 182 snd_seq_timer_set_tick_resolution(tmr);
184 } 183 }
185 spin_unlock_irqrestore(&tmr->lock, flags); 184 spin_unlock_irqrestore(&tmr->lock, flags);
186 return 0; 185 return 0;
@@ -205,7 +204,7 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
205 } 204 }
206 205
207 tmr->ppq = ppq; 206 tmr->ppq = ppq;
208 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 207 snd_seq_timer_set_tick_resolution(tmr);
209 spin_unlock_irqrestore(&tmr->lock, flags); 208 spin_unlock_irqrestore(&tmr->lock, flags);
210 return 0; 209 return 0;
211} 210}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 7872a02f6ca9..563d1967a0ad 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -468,5 +468,5 @@ static void __exit alsa_sound_exit(void)
468 unregister_chrdev(major, "alsa"); 468 unregister_chrdev(major, "alsa");
469} 469}
470 470
471module_init(alsa_sound_init) 471subsys_initcall(alsa_sound_init);
472module_exit(alsa_sound_exit) 472module_exit(alsa_sound_exit);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 7fe12264ff80..0c164e5e4322 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -93,7 +93,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
93 default: 93 default:
94 return -EINVAL; 94 return -EINVAL;
95 } 95 }
96 if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OSS_MINORS)) 96 if (minor < 0 || minor >= SNDRV_OSS_MINORS)
97 return -EINVAL; 97 return -EINVAL;
98 return minor; 98 return minor;
99} 99}
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 8f8b17ac074d..5040c7b862fe 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -393,7 +393,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
393 event == SNDRV_TIMER_EVENT_CONTINUE) 393 event == SNDRV_TIMER_EVENT_CONTINUE)
394 resolution = snd_timer_resolution(ti); 394 resolution = snd_timer_resolution(ti);
395 if (ti->ccallback) 395 if (ti->ccallback)
396 ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); 396 ti->ccallback(ti, event, &tstamp, resolution);
397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) 397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
398 return; 398 return;
399 timer = ti->timer; 399 timer = ti->timer;
@@ -1160,6 +1160,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1160{ 1160{
1161 struct snd_timer_user *tu = timeri->callback_data; 1161 struct snd_timer_user *tu = timeri->callback_data;
1162 struct snd_timer_tread r1; 1162 struct snd_timer_tread r1;
1163 unsigned long flags;
1163 1164
1164 if (event >= SNDRV_TIMER_EVENT_START && 1165 if (event >= SNDRV_TIMER_EVENT_START &&
1165 event <= SNDRV_TIMER_EVENT_PAUSE) 1166 event <= SNDRV_TIMER_EVENT_PAUSE)
@@ -1169,9 +1170,9 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1169 r1.event = event; 1170 r1.event = event;
1170 r1.tstamp = *tstamp; 1171 r1.tstamp = *tstamp;
1171 r1.val = resolution; 1172 r1.val = resolution;
1172 spin_lock(&tu->qlock); 1173 spin_lock_irqsave(&tu->qlock, flags);
1173 snd_timer_user_append_to_tqueue(tu, &r1); 1174 snd_timer_user_append_to_tqueue(tu, &r1);
1174 spin_unlock(&tu->qlock); 1175 spin_unlock_irqrestore(&tu->qlock, flags);
1175 kill_fasync(&tu->fasync, SIGIO, POLL_IN); 1176 kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1176 wake_up(&tu->qchange_sleep); 1177 wake_up(&tu->qchange_sleep);
1177} 1178}