aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/Kconfig4
-rw-r--r--sound/core/Makefile2
-rw-r--r--sound/core/control.c34
-rw-r--r--sound/core/info.c8
-rw-r--r--sound/core/init.c8
-rw-r--r--sound/core/memalloc.c4
-rw-r--r--sound/core/misc.c75
-rw-r--r--sound/core/oss/mixer_oss.c3
-rw-r--r--sound/core/oss/pcm_oss.c12
-rw-r--r--sound/core/pcm.c26
-rw-r--r--sound/core/pcm_lib.c51
-rw-r--r--sound/core/pcm_memory.c2
-rw-r--r--sound/core/pcm_native.c64
-rw-r--r--sound/core/rawmidi.c2
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c14
-rw-r--r--sound/core/seq/seq_midi.c7
-rw-r--r--sound/core/vmaster.c8
17 files changed, 187 insertions, 137 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 6061fb5f4e1c..c15682a2f9db 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -206,4 +206,8 @@ config SND_PCM_XRUN_DEBUG
206config SND_VMASTER 206config SND_VMASTER
207 bool 207 bool
208 208
209config SND_DMA_SGBUF
210 def_bool y
211 depends on X86
212
209source "sound/core/seq/Kconfig" 213source "sound/core/seq/Kconfig"
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 4229052e7b91..350a08d277f4 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -13,7 +13,7 @@ snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
13 pcm_memory.o 13 pcm_memory.o
14 14
15snd-page-alloc-y := memalloc.o 15snd-page-alloc-y := memalloc.o
16snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o 16snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
17 17
18snd-rawmidi-objs := rawmidi.o 18snd-rawmidi-objs := rawmidi.o
19snd-timer-objs := timer.o 19snd-timer-objs := timer.o
diff --git a/sound/core/control.c b/sound/core/control.c
index 17b8d47a5cd0..a8b7fabe645e 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
414EXPORT_SYMBOL(snd_ctl_remove_id); 414EXPORT_SYMBOL(snd_ctl_remove_id);
415 415
416/** 416/**
417 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it 417 * snd_ctl_remove_user_ctl - remove and release the unlocked user control
418 * @file: active control handle 418 * @file: active control handle
419 * @id: the control id to remove 419 * @id: the control id to remove
420 * 420 *
@@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id);
423 * 423 *
424 * Returns 0 if successful, or a negative error code on failure. 424 * Returns 0 if successful, or a negative error code on failure.
425 */ 425 */
426static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, 426static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
427 struct snd_ctl_elem_id *id) 427 struct snd_ctl_elem_id *id)
428{ 428{
429 struct snd_card *card = file->card; 429 struct snd_card *card = file->card;
430 struct snd_kcontrol *kctl; 430 struct snd_kcontrol *kctl;
@@ -433,15 +433,23 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file,
433 down_write(&card->controls_rwsem); 433 down_write(&card->controls_rwsem);
434 kctl = snd_ctl_find_id(card, id); 434 kctl = snd_ctl_find_id(card, id);
435 if (kctl == NULL) { 435 if (kctl == NULL) {
436 up_write(&card->controls_rwsem); 436 ret = -ENOENT;
437 return -ENOENT; 437 goto error;
438 }
439 if (!(kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_USER)) {
440 ret = -EINVAL;
441 goto error;
438 } 442 }
439 for (idx = 0; idx < kctl->count; idx++) 443 for (idx = 0; idx < kctl->count; idx++)
440 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) { 444 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
441 up_write(&card->controls_rwsem); 445 ret = -EBUSY;
442 return -EBUSY; 446 goto error;
443 } 447 }
444 ret = snd_ctl_remove(card, kctl); 448 ret = snd_ctl_remove(card, kctl);
449 if (ret < 0)
450 goto error;
451 card->user_ctl_count--;
452error:
445 up_write(&card->controls_rwsem); 453 up_write(&card->controls_rwsem);
446 return ret; 454 return ret;
447} 455}
@@ -951,7 +959,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
951 959
952 if (card->user_ctl_count >= MAX_USER_CONTROLS) 960 if (card->user_ctl_count >= MAX_USER_CONTROLS)
953 return -ENOMEM; 961 return -ENOMEM;
954 if (info->count > 1024) 962 if (info->count < 1)
955 return -EINVAL; 963 return -EINVAL;
956 access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 964 access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
957 (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 965 (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
@@ -1052,18 +1060,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file,
1052 struct snd_ctl_elem_id __user *_id) 1060 struct snd_ctl_elem_id __user *_id)
1053{ 1061{
1054 struct snd_ctl_elem_id id; 1062 struct snd_ctl_elem_id id;
1055 int err;
1056 1063
1057 if (copy_from_user(&id, _id, sizeof(id))) 1064 if (copy_from_user(&id, _id, sizeof(id)))
1058 return -EFAULT; 1065 return -EFAULT;
1059 err = snd_ctl_remove_unlocked_id(file, &id); 1066 return snd_ctl_remove_user_ctl(file, &id);
1060 if (! err) {
1061 struct snd_card *card = file->card;
1062 down_write(&card->controls_rwsem);
1063 card->user_ctl_count--;
1064 up_write(&card->controls_rwsem);
1065 }
1066 return err;
1067} 1067}
1068 1068
1069static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) 1069static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
diff --git a/sound/core/info.c b/sound/core/info.c
index 35df614f6c55..d749a0d394a7 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -88,12 +88,10 @@ static int resize_info_buffer(struct snd_info_buffer *buffer,
88 char *nbuf; 88 char *nbuf;
89 89
90 nsize = PAGE_ALIGN(nsize); 90 nsize = PAGE_ALIGN(nsize);
91 nbuf = kmalloc(nsize, GFP_KERNEL); 91 nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL);
92 if (! nbuf) 92 if (! nbuf)
93 return -ENOMEM; 93 return -ENOMEM;
94 94
95 memcpy(nbuf, buffer->buffer, buffer->len);
96 kfree(buffer->buffer);
97 buffer->buffer = nbuf; 95 buffer->buffer = nbuf;
98 buffer->len = nsize; 96 buffer->len = nsize;
99 return 0; 97 return 0;
@@ -108,7 +106,7 @@ static int resize_info_buffer(struct snd_info_buffer *buffer,
108 * 106 *
109 * Returns the size of output string. 107 * Returns the size of output string.
110 */ 108 */
111int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) 109int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...)
112{ 110{
113 va_list args; 111 va_list args;
114 int len, res; 112 int len, res;
@@ -727,7 +725,7 @@ EXPORT_SYMBOL(snd_info_get_line);
727 * Returns the updated pointer of the original string so that 725 * Returns the updated pointer of the original string so that
728 * it can be used for the next call. 726 * it can be used for the next call.
729 */ 727 */
730char *snd_info_get_str(char *dest, char *src, int len) 728const char *snd_info_get_str(char *dest, const char *src, int len)
731{ 729{
732 int c; 730 int c;
733 731
diff --git a/sound/core/init.c b/sound/core/init.c
index d5d40d78c409..ec4a50ce5656 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -31,6 +31,14 @@
31#include <sound/control.h> 31#include <sound/control.h>
32#include <sound/info.h> 32#include <sound/info.h>
33 33
34/* monitor files for graceful shutdown (hotplug) */
35struct snd_monitor_file {
36 struct file *file;
37 const struct file_operations *disconnected_f_op;
38 struct list_head shutdown_list; /* still need to shutdown */
39 struct list_head list; /* link of monitor files */
40};
41
34static DEFINE_SPINLOCK(shutdown_lock); 42static DEFINE_SPINLOCK(shutdown_lock);
35static LIST_HEAD(shutdown_files); 43static LIST_HEAD(shutdown_files);
36 44
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 1b3534d67686..9e92441f9b78 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -199,6 +199,8 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
199 case SNDRV_DMA_TYPE_DEV: 199 case SNDRV_DMA_TYPE_DEV:
200 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); 200 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
201 break; 201 break;
202#endif
203#ifdef CONFIG_SND_DMA_SGBUF
202 case SNDRV_DMA_TYPE_DEV_SG: 204 case SNDRV_DMA_TYPE_DEV_SG:
203 snd_malloc_sgbuf_pages(device, size, dmab, NULL); 205 snd_malloc_sgbuf_pages(device, size, dmab, NULL);
204 break; 206 break;
@@ -269,6 +271,8 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
269 case SNDRV_DMA_TYPE_DEV: 271 case SNDRV_DMA_TYPE_DEV:
270 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); 272 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
271 break; 273 break;
274#endif
275#ifdef CONFIG_SND_DMA_SGBUF
272 case SNDRV_DMA_TYPE_DEV_SG: 276 case SNDRV_DMA_TYPE_DEV_SG:
273 snd_free_sgbuf_pages(dmab); 277 snd_free_sgbuf_pages(dmab);
274 break; 278 break;
diff --git a/sound/core/misc.c b/sound/core/misc.c
index a9710e0c97af..23a032c6d487 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -24,6 +24,20 @@
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <sound/core.h> 25#include <sound/core.h>
26 26
27#ifdef CONFIG_SND_DEBUG
28
29#ifdef CONFIG_SND_DEBUG_VERBOSE
30#define DEFAULT_DEBUG_LEVEL 2
31#else
32#define DEFAULT_DEBUG_LEVEL 1
33#endif
34
35static int debug = DEFAULT_DEBUG_LEVEL;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Debug level (0 = disable)");
38
39#endif /* CONFIG_SND_DEBUG */
40
27void release_and_free_resource(struct resource *res) 41void release_and_free_resource(struct resource *res)
28{ 42{
29 if (res) { 43 if (res) {
@@ -35,46 +49,53 @@ void release_and_free_resource(struct resource *res)
35EXPORT_SYMBOL(release_and_free_resource); 49EXPORT_SYMBOL(release_and_free_resource);
36 50
37#ifdef CONFIG_SND_VERBOSE_PRINTK 51#ifdef CONFIG_SND_VERBOSE_PRINTK
38void snd_verbose_printk(const char *file, int line, const char *format, ...) 52/* strip the leading path if the given path is absolute */
53static const char *sanity_file_name(const char *path)
39{ 54{
40 va_list args; 55 if (*path == '/')
41 56 return strrchr(path, '/') + 1;
42 if (format[0] == '<' && format[1] >= '0' && format[1] <= '7' && format[2] == '>') { 57 else
43 char tmp[] = "<0>"; 58 return path;
59}
60
61/* print file and line with a certain printk prefix */
62static int print_snd_pfx(unsigned int level, const char *path, int line,
63 const char *format)
64{
65 const char *file = sanity_file_name(path);
66 char tmp[] = "<0>";
67 const char *pfx = level ? KERN_DEBUG : KERN_DEFAULT;
68 int ret = 0;
69
70 if (format[0] == '<' && format[2] == '>') {
44 tmp[1] = format[1]; 71 tmp[1] = format[1];
45 printk("%sALSA %s:%d: ", tmp, file, line); 72 pfx = tmp;
46 format += 3; 73 ret = 1;
47 } else {
48 printk("ALSA %s:%d: ", file, line);
49 } 74 }
50 va_start(args, format); 75 printk("%sALSA %s:%d: ", pfx, file, line);
51 vprintk(format, args); 76 return ret;
52 va_end(args);
53} 77}
54 78#else
55EXPORT_SYMBOL(snd_verbose_printk); 79#define print_snd_pfx(level, path, line, format) 0
56#endif 80#endif
57 81
58#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) 82#if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
59void snd_verbose_printd(const char *file, int line, const char *format, ...) 83void __snd_printk(unsigned int level, const char *path, int line,
84 const char *format, ...)
60{ 85{
61 va_list args; 86 va_list args;
62 87
63 if (format[0] == '<' && format[1] >= '0' && format[1] <= '7' && format[2] == '>') { 88#ifdef CONFIG_SND_DEBUG
64 char tmp[] = "<0>"; 89 if (debug < level)
65 tmp[1] = format[1]; 90 return;
66 printk("%sALSA %s:%d: ", tmp, file, line); 91#endif
67 format += 3;
68 } else {
69 printk(KERN_DEBUG "ALSA %s:%d: ", file, line);
70 }
71 va_start(args, format); 92 va_start(args, format);
93 if (print_snd_pfx(level, path, line, format))
94 format += 3; /* skip the printk level-prefix */
72 vprintk(format, args); 95 vprintk(format, args);
73 va_end(args); 96 va_end(args);
74
75} 97}
76 98EXPORT_SYMBOL_GPL(__snd_printk);
77EXPORT_SYMBOL(snd_verbose_printd);
78#endif 99#endif
79 100
80#ifdef CONFIG_PCI 101#ifdef CONFIG_PCI
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 5dcd8a526970..772423889eb3 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1154,7 +1154,8 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
1154 struct snd_info_buffer *buffer) 1154 struct snd_info_buffer *buffer)
1155{ 1155{
1156 struct snd_mixer_oss *mixer = entry->private_data; 1156 struct snd_mixer_oss *mixer = entry->private_data;
1157 char line[128], str[32], idxstr[16], *cptr; 1157 char line[128], str[32], idxstr[16];
1158 const char *cptr;
1158 int ch, idx; 1159 int ch, idx;
1159 struct snd_mixer_oss_assign_table *tbl; 1160 struct snd_mixer_oss_assign_table *tbl;
1160 struct slot *slot; 1161 struct slot *slot;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index dbe406b82591..d9c96353121a 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1043,10 +1043,15 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
1043 runtime->oss.channels = params_channels(params); 1043 runtime->oss.channels = params_channels(params);
1044 runtime->oss.rate = params_rate(params); 1044 runtime->oss.rate = params_rate(params);
1045 1045
1046 runtime->oss.params = 0;
1047 runtime->oss.prepare = 1;
1048 vfree(runtime->oss.buffer); 1046 vfree(runtime->oss.buffer);
1049 runtime->oss.buffer = vmalloc(runtime->oss.period_bytes); 1047 runtime->oss.buffer = vmalloc(runtime->oss.period_bytes);
1048 if (!runtime->oss.buffer) {
1049 err = -ENOMEM;
1050 goto failure;
1051 }
1052
1053 runtime->oss.params = 0;
1054 runtime->oss.prepare = 1;
1050 runtime->oss.buffer_used = 0; 1055 runtime->oss.buffer_used = 0;
1051 if (runtime->dma_area) 1056 if (runtime->dma_area)
1052 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes)); 1057 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
@@ -2836,7 +2841,8 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
2836 struct snd_info_buffer *buffer) 2841 struct snd_info_buffer *buffer)
2837{ 2842{
2838 struct snd_pcm_str *pstr = entry->private_data; 2843 struct snd_pcm_str *pstr = entry->private_data;
2839 char line[128], str[32], task_name[32], *ptr; 2844 char line[128], str[32], task_name[32];
2845 const char *ptr;
2840 int idx1; 2846 int idx1;
2841 struct snd_pcm_oss_setup *setup, *setup1, template; 2847 struct snd_pcm_oss_setup *setup, *setup1, template;
2842 2848
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 145931a9ff30..0c1440121c22 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -162,18 +162,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
162 return -ENOIOCTLCMD; 162 return -ENOIOCTLCMD;
163} 163}
164 164
165#ifdef CONFIG_SND_VERBOSE_PROCFS
166
167#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
168#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
169#define READY(v) [SNDRV_PCM_READY_##v] = #v
170#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
171#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
172#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
173#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
174#define START(v) [SNDRV_PCM_START_##v] = #v
175#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v 165#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
176#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
177 166
178static char *snd_pcm_format_names[] = { 167static char *snd_pcm_format_names[] = {
179 FORMAT(S8), 168 FORMAT(S8),
@@ -216,10 +205,23 @@ static char *snd_pcm_format_names[] = {
216 FORMAT(U18_3BE), 205 FORMAT(U18_3BE),
217}; 206};
218 207
219static const char *snd_pcm_format_name(snd_pcm_format_t format) 208const char *snd_pcm_format_name(snd_pcm_format_t format)
220{ 209{
221 return snd_pcm_format_names[format]; 210 return snd_pcm_format_names[format];
222} 211}
212EXPORT_SYMBOL_GPL(snd_pcm_format_name);
213
214#ifdef CONFIG_SND_VERBOSE_PROCFS
215
216#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
217#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
218#define READY(v) [SNDRV_PCM_READY_##v] = #v
219#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
220#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
221#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
222#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
223#define START(v) [SNDRV_PCM_START_##v] = #v
224#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
223 225
224static char *snd_pcm_stream_names[] = { 226static char *snd_pcm_stream_names[] = {
225 STREAM(PLAYBACK), 227 STREAM(PLAYBACK),
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 72cfd47af6b8..30f410832a25 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -197,12 +197,16 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
197 avail = snd_pcm_capture_avail(runtime); 197 avail = snd_pcm_capture_avail(runtime);
198 if (avail > runtime->avail_max) 198 if (avail > runtime->avail_max)
199 runtime->avail_max = avail; 199 runtime->avail_max = avail;
200 if (avail >= runtime->stop_threshold) { 200 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
201 if (substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING) 201 if (avail >= runtime->buffer_size) {
202 snd_pcm_drain_done(substream); 202 snd_pcm_drain_done(substream);
203 else 203 return -EPIPE;
204 }
205 } else {
206 if (avail >= runtime->stop_threshold) {
204 xrun(substream); 207 xrun(substream);
205 return -EPIPE; 208 return -EPIPE;
209 }
206 } 210 }
207 if (avail >= runtime->control->avail_min) 211 if (avail >= runtime->control->avail_min)
208 wake_up(&runtime->sleep); 212 wake_up(&runtime->sleep);
@@ -943,47 +947,24 @@ static int snd_interval_ratden(struct snd_interval *i,
943int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) 947int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask)
944{ 948{
945 unsigned int k; 949 unsigned int k;
946 int changed = 0; 950 struct snd_interval list_range;
947 951
948 if (!count) { 952 if (!count) {
949 i->empty = 1; 953 i->empty = 1;
950 return -EINVAL; 954 return -EINVAL;
951 } 955 }
956 snd_interval_any(&list_range);
957 list_range.min = UINT_MAX;
958 list_range.max = 0;
952 for (k = 0; k < count; k++) { 959 for (k = 0; k < count; k++) {
953 if (mask && !(mask & (1 << k))) 960 if (mask && !(mask & (1 << k)))
954 continue; 961 continue;
955 if (i->min == list[k] && !i->openmin) 962 if (!snd_interval_test(i, list[k]))
956 goto _l1;
957 if (i->min < list[k]) {
958 i->min = list[k];
959 i->openmin = 0;
960 changed = 1;
961 goto _l1;
962 }
963 }
964 i->empty = 1;
965 return -EINVAL;
966 _l1:
967 for (k = count; k-- > 0;) {
968 if (mask && !(mask & (1 << k)))
969 continue; 963 continue;
970 if (i->max == list[k] && !i->openmax) 964 list_range.min = min(list_range.min, list[k]);
971 goto _l2; 965 list_range.max = max(list_range.max, list[k]);
972 if (i->max > list[k]) {
973 i->max = list[k];
974 i->openmax = 0;
975 changed = 1;
976 goto _l2;
977 }
978 } 966 }
979 i->empty = 1; 967 return snd_interval_refine(i, &list_range);
980 return -EINVAL;
981 _l2:
982 if (snd_interval_checkempty(i)) {
983 i->empty = 1;
984 return -EINVAL;
985 }
986 return changed;
987} 968}
988 969
989EXPORT_SYMBOL(snd_interval_list); 970EXPORT_SYMBOL(snd_interval_list);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index a6d42808828c..caa7796bc2f5 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -304,6 +304,7 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
304 304
305EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); 305EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
306 306
307#ifdef CONFIG_SND_DMA_SGBUF
307/** 308/**
308 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 309 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
309 * @substream: the pcm substream instance 310 * @substream: the pcm substream instance
@@ -349,6 +350,7 @@ unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
349 return size; 350 return size;
350} 351}
351EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size); 352EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
353#endif /* CONFIG_SND_DMA_SGBUF */
352 354
353/** 355/**
354 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 356 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ac2150e0670d..59e5fbe6af51 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1343,8 +1343,6 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1343 1343
1344static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) 1344static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1345{ 1345{
1346 if (substream->f_flags & O_NONBLOCK)
1347 return -EAGAIN;
1348 substream->runtime->trigger_master = substream; 1346 substream->runtime->trigger_master = substream;
1349 return 0; 1347 return 0;
1350} 1348}
@@ -1392,7 +1390,6 @@ static struct action_ops snd_pcm_action_drain_init = {
1392struct drain_rec { 1390struct drain_rec {
1393 struct snd_pcm_substream *substream; 1391 struct snd_pcm_substream *substream;
1394 wait_queue_t wait; 1392 wait_queue_t wait;
1395 snd_pcm_uframes_t stop_threshold;
1396}; 1393};
1397 1394
1398static int snd_pcm_drop(struct snd_pcm_substream *substream); 1395static int snd_pcm_drop(struct snd_pcm_substream *substream);
@@ -1404,13 +1401,15 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream);
1404 * After this call, all streams are supposed to be either SETUP or DRAINING 1401 * After this call, all streams are supposed to be either SETUP or DRAINING
1405 * (capture only) state. 1402 * (capture only) state.
1406 */ 1403 */
1407static int snd_pcm_drain(struct snd_pcm_substream *substream) 1404static int snd_pcm_drain(struct snd_pcm_substream *substream,
1405 struct file *file)
1408{ 1406{
1409 struct snd_card *card; 1407 struct snd_card *card;
1410 struct snd_pcm_runtime *runtime; 1408 struct snd_pcm_runtime *runtime;
1411 struct snd_pcm_substream *s; 1409 struct snd_pcm_substream *s;
1412 int result = 0; 1410 int result = 0;
1413 int i, num_drecs; 1411 int i, num_drecs;
1412 int nonblock = 0;
1414 struct drain_rec *drec, drec_tmp, *d; 1413 struct drain_rec *drec, drec_tmp, *d;
1415 1414
1416 card = substream->pcm->card; 1415 card = substream->pcm->card;
@@ -1428,6 +1427,15 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1428 } 1427 }
1429 } 1428 }
1430 1429
1430 if (file) {
1431 if (file->f_flags & O_NONBLOCK)
1432 nonblock = 1;
1433 } else if (substream->f_flags & O_NONBLOCK)
1434 nonblock = 1;
1435
1436 if (nonblock)
1437 goto lock; /* no need to allocate waitqueues */
1438
1431 /* allocate temporary record for drain sync */ 1439 /* allocate temporary record for drain sync */
1432 down_read(&snd_pcm_link_rwsem); 1440 down_read(&snd_pcm_link_rwsem);
1433 if (snd_pcm_stream_linked(substream)) { 1441 if (snd_pcm_stream_linked(substream)) {
@@ -1449,16 +1457,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1449 d->substream = s; 1457 d->substream = s;
1450 init_waitqueue_entry(&d->wait, current); 1458 init_waitqueue_entry(&d->wait, current);
1451 add_wait_queue(&runtime->sleep, &d->wait); 1459 add_wait_queue(&runtime->sleep, &d->wait);
1452 /* stop_threshold fixup to avoid endless loop when
1453 * stop_threshold > buffer_size
1454 */
1455 d->stop_threshold = runtime->stop_threshold;
1456 if (runtime->stop_threshold > runtime->buffer_size)
1457 runtime->stop_threshold = runtime->buffer_size;
1458 } 1460 }
1459 } 1461 }
1460 up_read(&snd_pcm_link_rwsem); 1462 up_read(&snd_pcm_link_rwsem);
1461 1463
1464 lock:
1462 snd_pcm_stream_lock_irq(substream); 1465 snd_pcm_stream_lock_irq(substream);
1463 /* resume pause */ 1466 /* resume pause */
1464 if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED) 1467 if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED)
@@ -1466,9 +1469,12 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1466 1469
1467 /* pre-start/stop - all running streams are changed to DRAINING state */ 1470 /* pre-start/stop - all running streams are changed to DRAINING state */
1468 result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); 1471 result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
1469 if (result < 0) { 1472 if (result < 0)
1470 snd_pcm_stream_unlock_irq(substream); 1473 goto unlock;
1471 goto _error; 1474 /* in non-blocking, we don't wait in ioctl but let caller poll */
1475 if (nonblock) {
1476 result = -EAGAIN;
1477 goto unlock;
1472 } 1478 }
1473 1479
1474 for (;;) { 1480 for (;;) {
@@ -1504,18 +1510,18 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1504 } 1510 }
1505 } 1511 }
1506 1512
1513 unlock:
1507 snd_pcm_stream_unlock_irq(substream); 1514 snd_pcm_stream_unlock_irq(substream);
1508 1515
1509 _error: 1516 if (!nonblock) {
1510 for (i = 0; i < num_drecs; i++) { 1517 for (i = 0; i < num_drecs; i++) {
1511 d = &drec[i]; 1518 d = &drec[i];
1512 runtime = d->substream->runtime; 1519 runtime = d->substream->runtime;
1513 remove_wait_queue(&runtime->sleep, &d->wait); 1520 remove_wait_queue(&runtime->sleep, &d->wait);
1514 runtime->stop_threshold = d->stop_threshold; 1521 }
1522 if (drec != &drec_tmp)
1523 kfree(drec);
1515 } 1524 }
1516
1517 if (drec != &drec_tmp)
1518 kfree(drec);
1519 snd_power_unlock(card); 1525 snd_power_unlock(card);
1520 1526
1521 return result; 1527 return result;
@@ -2208,6 +2214,9 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
2208 case SNDRV_PCM_STATE_XRUN: 2214 case SNDRV_PCM_STATE_XRUN:
2209 ret = -EPIPE; 2215 ret = -EPIPE;
2210 goto __end; 2216 goto __end;
2217 case SNDRV_PCM_STATE_SUSPENDED:
2218 ret = -ESTRPIPE;
2219 goto __end;
2211 default: 2220 default:
2212 ret = -EBADFD; 2221 ret = -EBADFD;
2213 goto __end; 2222 goto __end;
@@ -2253,6 +2262,9 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
2253 case SNDRV_PCM_STATE_XRUN: 2262 case SNDRV_PCM_STATE_XRUN:
2254 ret = -EPIPE; 2263 ret = -EPIPE;
2255 goto __end; 2264 goto __end;
2265 case SNDRV_PCM_STATE_SUSPENDED:
2266 ret = -ESTRPIPE;
2267 goto __end;
2256 default: 2268 default:
2257 ret = -EBADFD; 2269 ret = -EBADFD;
2258 goto __end; 2270 goto __end;
@@ -2299,6 +2311,9 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
2299 case SNDRV_PCM_STATE_XRUN: 2311 case SNDRV_PCM_STATE_XRUN:
2300 ret = -EPIPE; 2312 ret = -EPIPE;
2301 goto __end; 2313 goto __end;
2314 case SNDRV_PCM_STATE_SUSPENDED:
2315 ret = -ESTRPIPE;
2316 goto __end;
2302 default: 2317 default:
2303 ret = -EBADFD; 2318 ret = -EBADFD;
2304 goto __end; 2319 goto __end;
@@ -2345,6 +2360,9 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
2345 case SNDRV_PCM_STATE_XRUN: 2360 case SNDRV_PCM_STATE_XRUN:
2346 ret = -EPIPE; 2361 ret = -EPIPE;
2347 goto __end; 2362 goto __end;
2363 case SNDRV_PCM_STATE_SUSPENDED:
2364 ret = -ESTRPIPE;
2365 goto __end;
2348 default: 2366 default:
2349 ret = -EBADFD; 2367 ret = -EBADFD;
2350 goto __end; 2368 goto __end;
@@ -2544,7 +2562,7 @@ static int snd_pcm_common_ioctl1(struct file *file,
2544 return snd_pcm_hw_params_old_user(substream, arg); 2562 return snd_pcm_hw_params_old_user(substream, arg);
2545#endif 2563#endif
2546 case SNDRV_PCM_IOCTL_DRAIN: 2564 case SNDRV_PCM_IOCTL_DRAIN:
2547 return snd_pcm_drain(substream); 2565 return snd_pcm_drain(substream, file);
2548 case SNDRV_PCM_IOCTL_DROP: 2566 case SNDRV_PCM_IOCTL_DROP:
2549 return snd_pcm_drop(substream); 2567 return snd_pcm_drop(substream);
2550 case SNDRV_PCM_IOCTL_PAUSE: 2568 case SNDRV_PCM_IOCTL_PAUSE:
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 473247c8e6d3..c0adc14c91f0 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -274,7 +274,7 @@ static int open_substream(struct snd_rawmidi *rmidi,
274 return err; 274 return err;
275 substream->opened = 1; 275 substream->opened = 1;
276 if (substream->use_count++ == 0) 276 if (substream->use_count++ == 0)
277 substream->active_sensing = 1; 277 substream->active_sensing = 0;
278 if (mode & SNDRV_RAWMIDI_LFLG_APPEND) 278 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
279 substream->append = 1; 279 substream->append = 1;
280 rmidi->streams[substream->stream].substream_opened++; 280 rmidi->streams[substream->stream].substream_opened++;
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 0a711d2d04f0..9dfb2f77be60 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -20,6 +20,7 @@
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/asoundef.h>
23#include "seq_oss_midi.h" 24#include "seq_oss_midi.h"
24#include "seq_oss_readq.h" 25#include "seq_oss_readq.h"
25#include "seq_oss_timer.h" 26#include "seq_oss_timer.h"
@@ -476,19 +477,20 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
476 ev.source.port = dp->port; 477 ev.source.port = dp->port;
477 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) { 478 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
478 ev.type = SNDRV_SEQ_EVENT_SENSING; 479 ev.type = SNDRV_SEQ_EVENT_SENSING;
479 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* active sensing */ 480 snd_seq_oss_dispatch(dp, &ev, 0, 0);
480 } 481 }
481 for (c = 0; c < 16; c++) { 482 for (c = 0; c < 16; c++) {
482 ev.type = SNDRV_SEQ_EVENT_CONTROLLER; 483 ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
483 ev.data.control.channel = c; 484 ev.data.control.channel = c;
484 ev.data.control.param = 123; 485 ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
485 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* all notes off */ 486 snd_seq_oss_dispatch(dp, &ev, 0, 0);
486 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) { 487 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
487 ev.data.control.param = 121; 488 ev.data.control.param =
488 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */ 489 MIDI_CTL_RESET_CONTROLLERS;
490 snd_seq_oss_dispatch(dp, &ev, 0, 0);
489 ev.type = SNDRV_SEQ_EVENT_PITCHBEND; 491 ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
490 ev.data.control.value = 0; 492 ev.data.control.value = 0;
491 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */ 493 snd_seq_oss_dispatch(dp, &ev, 0, 0);
492 } 494 }
493 } 495 }
494 } 496 }
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 4d26146a62cc..ebaf1b541dcd 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -120,7 +120,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
120 return -EINVAL; 120 return -EINVAL;
121 runtime = substream->runtime; 121 runtime = substream->runtime;
122 if ((tmp = runtime->avail) < count) { 122 if ((tmp = runtime->avail) < count) {
123 snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp); 123 if (printk_ratelimit())
124 snd_printk(KERN_ERR "MIDI output buffer overrun\n");
124 return -ENOMEM; 125 return -ENOMEM;
125 } 126 }
126 if (snd_rawmidi_kernel_write(substream, buf, count) < count) 127 if (snd_rawmidi_kernel_write(substream, buf, count) < count)
@@ -236,6 +237,7 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
236 memset(&params, 0, sizeof(params)); 237 memset(&params, 0, sizeof(params));
237 params.avail_min = 1; 238 params.avail_min = 1;
238 params.buffer_size = output_buffer_size; 239 params.buffer_size = output_buffer_size;
240 params.no_active_sensing = 1;
239 if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) { 241 if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) {
240 snd_rawmidi_kernel_release(&msynth->output_rfile); 242 snd_rawmidi_kernel_release(&msynth->output_rfile);
241 return err; 243 return err;
@@ -248,12 +250,9 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
248static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info) 250static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
249{ 251{
250 struct seq_midisynth *msynth = private_data; 252 struct seq_midisynth *msynth = private_data;
251 unsigned char buf = 0xff; /* MIDI reset */
252 253
253 if (snd_BUG_ON(!msynth->output_rfile.output)) 254 if (snd_BUG_ON(!msynth->output_rfile.output))
254 return -EINVAL; 255 return -EINVAL;
255 /* sending single MIDI reset message to shut the device up */
256 snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1);
257 snd_rawmidi_drain_output(msynth->output_rfile.output); 256 snd_rawmidi_drain_output(msynth->output_rfile.output);
258 return snd_rawmidi_kernel_release(&msynth->output_rfile); 257 return snd_rawmidi_kernel_release(&msynth->output_rfile);
259} 258}
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 257624bd1997..3b9b550109cb 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -353,7 +353,8 @@ static void master_free(struct snd_kcontrol *kcontrol)
353 * 353 *
354 * The optional argument @tlv can be used to specify the TLV information 354 * The optional argument @tlv can be used to specify the TLV information
355 * for dB scale of the master control. It should be a single element 355 * for dB scale of the master control. It should be a single element
356 * with #SNDRV_CTL_TLVT_DB_SCALE type, and should be the max 0dB. 356 * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or
357 * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB.
357 */ 358 */
358struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, 359struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
359 const unsigned int *tlv) 360 const unsigned int *tlv)
@@ -384,7 +385,10 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
384 kctl->private_free = master_free; 385 kctl->private_free = master_free;
385 386
386 /* additional (constant) TLV read */ 387 /* additional (constant) TLV read */
387 if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { 388 if (tlv &&
389 (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE ||
390 tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX ||
391 tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) {
388 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 392 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
389 memcpy(master->tlv, tlv, sizeof(master->tlv)); 393 memcpy(master->tlv, tlv, sizeof(master->tlv));
390 kctl->tlv.p = master->tlv; 394 kctl->tlv.p = master->tlv;