aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-06-26 11:35:44 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-06-26 11:35:44 -0400
commit62ed948cb1405fe95d61d8c6445c102e0c9da0a6 (patch)
treef139adcc861a05e7cc09cdb387a271a652fc2d07 /sound/core
parent17ffc7ba6d7ea68b8d5f55a5ca1b87163e69720d (diff)
parentfcc18e83e1f6fd9fa6b333735bf0fcd530655511 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c31
-rw-r--r--sound/core/device.c6
-rw-r--r--sound/core/hwdep.c1
-rw-r--r--sound/core/info.c178
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/init.c78
-rw-r--r--sound/core/isadma.c6
-rw-r--r--sound/core/memory.c5
-rw-r--r--sound/core/misc.c6
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/oss/pcm_oss.c529
-rw-r--r--sound/core/pcm.c90
-rw-r--r--sound/core/pcm_compat.c4
-rw-r--r--sound/core/pcm_lib.c725
-rw-r--r--sound/core/pcm_memory.c14
-rw-r--r--sound/core/pcm_misc.c24
-rw-r--r--sound/core/pcm_native.c113
-rw-r--r--sound/core/rawmidi.c3
-rw-r--r--sound/core/seq/oss/seq_oss.c1
-rw-r--r--sound/core/seq/seq.c22
-rw-r--r--sound/core/seq/seq_clientmgr.c12
-rw-r--r--sound/core/seq/seq_device.c3
-rw-r--r--sound/core/seq/seq_dummy.c6
-rw-r--r--sound/core/seq/seq_info.c11
-rw-r--r--sound/core/seq/seq_lock.c2
-rw-r--r--sound/core/seq/seq_memory.c3
-rw-r--r--sound/core/seq/seq_midi.c11
-rw-r--r--sound/core/seq/seq_ports.c5
-rw-r--r--sound/core/seq/seq_virmidi.c4
-rw-r--r--sound/core/sound.c109
-rw-r--r--sound/core/sound_oss.c9
-rw-r--r--sound/core/timer.c6
32 files changed, 1023 insertions, 999 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 22565c9b9603..bb397eaa7187 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -176,6 +176,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
176 read_unlock(&card->ctl_files_rwlock); 176 read_unlock(&card->ctl_files_rwlock);
177} 177}
178 178
179EXPORT_SYMBOL(snd_ctl_notify);
180
179/** 181/**
180 * snd_ctl_new - create a control instance from the template 182 * snd_ctl_new - create a control instance from the template
181 * @control: the control template 183 * @control: the control template
@@ -204,6 +206,8 @@ struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int acce
204 return kctl; 206 return kctl;
205} 207}
206 208
209EXPORT_SYMBOL(snd_ctl_new);
210
207/** 211/**
208 * snd_ctl_new1 - create a control instance from the template 212 * snd_ctl_new1 - create a control instance from the template
209 * @ncontrol: the initialization record 213 * @ncontrol: the initialization record
@@ -242,6 +246,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
242 return snd_ctl_new(&kctl, access); 246 return snd_ctl_new(&kctl, access);
243} 247}
244 248
249EXPORT_SYMBOL(snd_ctl_new1);
250
245/** 251/**
246 * snd_ctl_free_one - release the control instance 252 * snd_ctl_free_one - release the control instance
247 * @kcontrol: the control instance 253 * @kcontrol: the control instance
@@ -259,6 +265,8 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
259 } 265 }
260} 266}
261 267
268EXPORT_SYMBOL(snd_ctl_free_one);
269
262static unsigned int snd_ctl_hole_check(struct snd_card *card, 270static unsigned int snd_ctl_hole_check(struct snd_card *card,
263 unsigned int count) 271 unsigned int count)
264{ 272{
@@ -347,6 +355,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
347 return err; 355 return err;
348} 356}
349 357
358EXPORT_SYMBOL(snd_ctl_add);
359
350/** 360/**
351 * snd_ctl_remove - remove the control from the card and release it 361 * snd_ctl_remove - remove the control from the card and release it
352 * @card: the card instance 362 * @card: the card instance
@@ -373,6 +383,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
373 return 0; 383 return 0;
374} 384}
375 385
386EXPORT_SYMBOL(snd_ctl_remove);
387
376/** 388/**
377 * snd_ctl_remove_id - remove the control of the given id and release it 389 * snd_ctl_remove_id - remove the control of the given id and release it
378 * @card: the card instance 390 * @card: the card instance
@@ -399,6 +411,8 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
399 return ret; 411 return ret;
400} 412}
401 413
414EXPORT_SYMBOL(snd_ctl_remove_id);
415
402/** 416/**
403 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it 417 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it
404 * @file: active control handle 418 * @file: active control handle
@@ -461,6 +475,8 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
461 return 0; 475 return 0;
462} 476}
463 477
478EXPORT_SYMBOL(snd_ctl_rename_id);
479
464/** 480/**
465 * snd_ctl_find_numid - find the control instance with the given number-id 481 * snd_ctl_find_numid - find the control instance with the given number-id
466 * @card: the card instance 482 * @card: the card instance
@@ -487,6 +503,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
487 return NULL; 503 return NULL;
488} 504}
489 505
506EXPORT_SYMBOL(snd_ctl_find_numid);
507
490/** 508/**
491 * snd_ctl_find_id - find the control instance with the given id 509 * snd_ctl_find_id - find the control instance with the given id
492 * @card: the card instance 510 * @card: the card instance
@@ -527,6 +545,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
527 return NULL; 545 return NULL;
528} 546}
529 547
548EXPORT_SYMBOL(snd_ctl_find_id);
549
530static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, 550static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
531 unsigned int cmd, void __user *arg) 551 unsigned int cmd, void __user *arg)
532{ 552{
@@ -704,6 +724,8 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
704 return result; 724 return result;
705} 725}
706 726
727EXPORT_SYMBOL(snd_ctl_elem_read);
728
707static int snd_ctl_elem_read_user(struct snd_card *card, 729static int snd_ctl_elem_read_user(struct snd_card *card,
708 struct snd_ctl_elem_value __user *_control) 730 struct snd_ctl_elem_value __user *_control)
709{ 731{
@@ -767,6 +789,8 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
767 return result; 789 return result;
768} 790}
769 791
792EXPORT_SYMBOL(snd_ctl_elem_write);
793
770static int snd_ctl_elem_write_user(struct snd_ctl_file *file, 794static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
771 struct snd_ctl_elem_value __user *_control) 795 struct snd_ctl_elem_value __user *_control)
772{ 796{
@@ -1199,11 +1223,15 @@ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
1199 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); 1223 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
1200} 1224}
1201 1225
1226EXPORT_SYMBOL(snd_ctl_register_ioctl);
1227
1202#ifdef CONFIG_COMPAT 1228#ifdef CONFIG_COMPAT
1203int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) 1229int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1204{ 1230{
1205 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); 1231 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
1206} 1232}
1233
1234EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
1207#endif 1235#endif
1208 1236
1209/* 1237/*
@@ -1236,12 +1264,15 @@ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
1236 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); 1264 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
1237} 1265}
1238 1266
1267EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
1268
1239#ifdef CONFIG_COMPAT 1269#ifdef CONFIG_COMPAT
1240int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) 1270int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1241{ 1271{
1242 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); 1272 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
1243} 1273}
1244 1274
1275EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
1245#endif 1276#endif
1246 1277
1247static int snd_ctl_fasync(int fd, struct file * file, int on) 1278static int snd_ctl_fasync(int fd, struct file * file, int on)
diff --git a/sound/core/device.c b/sound/core/device.c
index b1cf6ec56784..6ce4da4a1081 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -63,6 +63,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type,
63 return 0; 63 return 0;
64} 64}
65 65
66EXPORT_SYMBOL(snd_device_new);
67
66/** 68/**
67 * snd_device_free - release the device from the card 69 * snd_device_free - release the device from the card
68 * @card: the card instance 70 * @card: the card instance
@@ -107,6 +109,8 @@ int snd_device_free(struct snd_card *card, void *device_data)
107 return -ENXIO; 109 return -ENXIO;
108} 110}
109 111
112EXPORT_SYMBOL(snd_device_free);
113
110/** 114/**
111 * snd_device_disconnect - disconnect the device 115 * snd_device_disconnect - disconnect the device
112 * @card: the card instance 116 * @card: the card instance
@@ -182,6 +186,8 @@ int snd_device_register(struct snd_card *card, void *device_data)
182 return -ENXIO; 186 return -ENXIO;
183} 187}
184 188
189EXPORT_SYMBOL(snd_device_register);
190
185/* 191/*
186 * register all the devices on the card. 192 * register all the devices on the card.
187 * called from init.c 193 * called from init.c
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 2524e66eccdd..8bd0dcc93eba 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -486,7 +486,6 @@ static void __init snd_hwdep_proc_init(void)
486 struct snd_info_entry *entry; 486 struct snd_info_entry *entry;
487 487
488 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { 488 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
489 entry->c.text.read_size = PAGE_SIZE;
490 entry->c.text.read = snd_hwdep_proc_read; 489 entry->c.text.read = snd_hwdep_proc_read;
491 if (snd_info_register(entry) < 0) { 490 if (snd_info_register(entry) < 0) {
492 snd_info_free_entry(entry); 491 snd_info_free_entry(entry);
diff --git a/sound/core/info.c b/sound/core/info.c
index 2582b74d3199..10c1772bf3ea 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -21,7 +21,6 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/vmalloc.h>
25#include <linux/time.h> 24#include <linux/time.h>
26#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
27#include <linux/string.h> 26#include <linux/string.h>
@@ -82,6 +81,24 @@ static int snd_info_version_init(void);
82static int snd_info_version_done(void); 81static int snd_info_version_done(void);
83 82
84 83
84/* resize the proc r/w buffer */
85static int resize_info_buffer(struct snd_info_buffer *buffer,
86 unsigned int nsize)
87{
88 char *nbuf;
89
90 nsize = PAGE_ALIGN(nsize);
91 nbuf = kmalloc(nsize, GFP_KERNEL);
92 if (! nbuf)
93 return -ENOMEM;
94
95 memcpy(nbuf, buffer->buffer, buffer->len);
96 kfree(buffer->buffer);
97 buffer->buffer = nbuf;
98 buffer->len = nsize;
99 return 0;
100}
101
85/** 102/**
86 * snd_iprintf - printf on the procfs buffer 103 * snd_iprintf - printf on the procfs buffer
87 * @buffer: the procfs buffer 104 * @buffer: the procfs buffer
@@ -95,30 +112,43 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...)
95{ 112{
96 va_list args; 113 va_list args;
97 int len, res; 114 int len, res;
115 int err = 0;
98 116
117 might_sleep();
99 if (buffer->stop || buffer->error) 118 if (buffer->stop || buffer->error)
100 return 0; 119 return 0;
101 len = buffer->len - buffer->size; 120 len = buffer->len - buffer->size;
102 va_start(args, fmt); 121 va_start(args, fmt);
103 res = vsnprintf(buffer->curr, len, fmt, args); 122 for (;;) {
104 va_end(args); 123 res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
105 if (res >= len) { 124 if (res < len)
106 buffer->stop = 1; 125 break;
107 return 0; 126 err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
127 if (err < 0)
128 break;
129 len = buffer->len - buffer->size;
108 } 130 }
131 va_end(args);
132
133 if (err < 0)
134 return err;
109 buffer->curr += res; 135 buffer->curr += res;
110 buffer->size += res; 136 buffer->size += res;
111 return res; 137 return res;
112} 138}
113 139
140EXPORT_SYMBOL(snd_iprintf);
141
114/* 142/*
115 143
116 */ 144 */
117 145
118static struct proc_dir_entry *snd_proc_root = NULL; 146static struct proc_dir_entry *snd_proc_root;
119struct snd_info_entry *snd_seq_root = NULL; 147struct snd_info_entry *snd_seq_root;
148EXPORT_SYMBOL(snd_seq_root);
149
120#ifdef CONFIG_SND_OSSEMUL 150#ifdef CONFIG_SND_OSSEMUL
121struct snd_info_entry *snd_oss_root = NULL; 151struct snd_info_entry *snd_oss_root;
122#endif 152#endif
123 153
124static inline void snd_info_entry_prepare(struct proc_dir_entry *de) 154static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
@@ -221,7 +251,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
221 struct snd_info_private_data *data; 251 struct snd_info_private_data *data;
222 struct snd_info_entry *entry; 252 struct snd_info_entry *entry;
223 struct snd_info_buffer *buf; 253 struct snd_info_buffer *buf;
224 size_t size = 0; 254 ssize_t size = 0;
225 loff_t pos; 255 loff_t pos;
226 256
227 data = file->private_data; 257 data = file->private_data;
@@ -237,14 +267,20 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
237 buf = data->wbuffer; 267 buf = data->wbuffer;
238 if (buf == NULL) 268 if (buf == NULL)
239 return -EIO; 269 return -EIO;
240 if (pos >= buf->len) 270 mutex_lock(&entry->access);
241 return -ENOMEM; 271 if (pos + count >= buf->len) {
242 size = buf->len - pos; 272 if (resize_info_buffer(buf, pos + count)) {
243 size = min(count, size); 273 mutex_unlock(&entry->access);
244 if (copy_from_user(buf->buffer + pos, buffer, size)) 274 return -ENOMEM;
275 }
276 }
277 if (copy_from_user(buf->buffer + pos, buffer, count)) {
278 mutex_unlock(&entry->access);
245 return -EFAULT; 279 return -EFAULT;
246 if ((long)buf->size < pos + size) 280 }
247 buf->size = pos + size; 281 buf->size = pos + count;
282 mutex_unlock(&entry->access);
283 size = count;
248 break; 284 break;
249 case SNDRV_INFO_CONTENT_DATA: 285 case SNDRV_INFO_CONTENT_DATA:
250 if (entry->c.ops->write) 286 if (entry->c.ops->write)
@@ -279,18 +315,14 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
279 } 315 }
280 mode = file->f_flags & O_ACCMODE; 316 mode = file->f_flags & O_ACCMODE;
281 if (mode == O_RDONLY || mode == O_RDWR) { 317 if (mode == O_RDONLY || mode == O_RDWR) {
282 if ((entry->content == SNDRV_INFO_CONTENT_TEXT && 318 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
283 !entry->c.text.read_size) ||
284 (entry->content == SNDRV_INFO_CONTENT_DATA &&
285 entry->c.ops->read == NULL)) { 319 entry->c.ops->read == NULL)) {
286 err = -ENODEV; 320 err = -ENODEV;
287 goto __error; 321 goto __error;
288 } 322 }
289 } 323 }
290 if (mode == O_WRONLY || mode == O_RDWR) { 324 if (mode == O_WRONLY || mode == O_RDWR) {
291 if ((entry->content == SNDRV_INFO_CONTENT_TEXT && 325 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
292 !entry->c.text.write_size) ||
293 (entry->content == SNDRV_INFO_CONTENT_DATA &&
294 entry->c.ops->write == NULL)) { 326 entry->c.ops->write == NULL)) {
295 err = -ENODEV; 327 err = -ENODEV;
296 goto __error; 328 goto __error;
@@ -306,49 +338,23 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
306 case SNDRV_INFO_CONTENT_TEXT: 338 case SNDRV_INFO_CONTENT_TEXT:
307 if (mode == O_RDONLY || mode == O_RDWR) { 339 if (mode == O_RDONLY || mode == O_RDWR) {
308 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 340 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
309 if (buffer == NULL) { 341 if (buffer == NULL)
310 kfree(data); 342 goto __nomem;
311 err = -ENOMEM;
312 goto __error;
313 }
314 buffer->len = (entry->c.text.read_size +
315 (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
316 buffer->buffer = vmalloc(buffer->len);
317 if (buffer->buffer == NULL) {
318 kfree(buffer);
319 kfree(data);
320 err = -ENOMEM;
321 goto __error;
322 }
323 buffer->curr = buffer->buffer;
324 data->rbuffer = buffer; 343 data->rbuffer = buffer;
344 buffer->len = PAGE_SIZE;
345 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
346 if (buffer->buffer == NULL)
347 goto __nomem;
325 } 348 }
326 if (mode == O_WRONLY || mode == O_RDWR) { 349 if (mode == O_WRONLY || mode == O_RDWR) {
327 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 350 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
328 if (buffer == NULL) { 351 if (buffer == NULL)
329 if (mode == O_RDWR) { 352 goto __nomem;
330 vfree(data->rbuffer->buffer);
331 kfree(data->rbuffer);
332 }
333 kfree(data);
334 err = -ENOMEM;
335 goto __error;
336 }
337 buffer->len = (entry->c.text.write_size +
338 (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
339 buffer->buffer = vmalloc(buffer->len);
340 if (buffer->buffer == NULL) {
341 if (mode == O_RDWR) {
342 vfree(data->rbuffer->buffer);
343 kfree(data->rbuffer);
344 }
345 kfree(buffer);
346 kfree(data);
347 err = -ENOMEM;
348 goto __error;
349 }
350 buffer->curr = buffer->buffer;
351 data->wbuffer = buffer; 353 data->wbuffer = buffer;
354 buffer->len = PAGE_SIZE;
355 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
356 if (buffer->buffer == NULL)
357 goto __nomem;
352 } 358 }
353 break; 359 break;
354 case SNDRV_INFO_CONTENT_DATA: /* data */ 360 case SNDRV_INFO_CONTENT_DATA: /* data */
@@ -373,6 +379,17 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
373 } 379 }
374 return 0; 380 return 0;
375 381
382 __nomem:
383 if (data->rbuffer) {
384 kfree(data->rbuffer->buffer);
385 kfree(data->rbuffer);
386 }
387 if (data->wbuffer) {
388 kfree(data->wbuffer->buffer);
389 kfree(data->wbuffer);
390 }
391 kfree(data);
392 err = -ENOMEM;
376 __error: 393 __error:
377 module_put(entry->module); 394 module_put(entry->module);
378 __error1: 395 __error1:
@@ -391,11 +408,11 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
391 entry = data->entry; 408 entry = data->entry;
392 switch (entry->content) { 409 switch (entry->content) {
393 case SNDRV_INFO_CONTENT_TEXT: 410 case SNDRV_INFO_CONTENT_TEXT:
394 if (mode == O_RDONLY || mode == O_RDWR) { 411 if (data->rbuffer) {
395 vfree(data->rbuffer->buffer); 412 kfree(data->rbuffer->buffer);
396 kfree(data->rbuffer); 413 kfree(data->rbuffer);
397 } 414 }
398 if (mode == O_WRONLY || mode == O_RDWR) { 415 if (data->wbuffer) {
399 if (entry->c.text.write) { 416 if (entry->c.text.write) {
400 entry->c.text.write(entry, data->wbuffer); 417 entry->c.text.write(entry, data->wbuffer);
401 if (data->wbuffer->error) { 418 if (data->wbuffer->error) {
@@ -404,7 +421,7 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
404 data->wbuffer->error); 421 data->wbuffer->error);
405 } 422 }
406 } 423 }
407 vfree(data->wbuffer->buffer); 424 kfree(data->wbuffer->buffer);
408 kfree(data->wbuffer); 425 kfree(data->wbuffer);
409 } 426 }
410 break; 427 break;
@@ -664,29 +681,29 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
664 if (len <= 0 || buffer->stop || buffer->error) 681 if (len <= 0 || buffer->stop || buffer->error)
665 return 1; 682 return 1;
666 while (--len > 0) { 683 while (--len > 0) {
667 c = *buffer->curr++; 684 c = buffer->buffer[buffer->curr++];
668 if (c == '\n') { 685 if (c == '\n') {
669 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 686 if (buffer->curr >= buffer->size)
670 buffer->stop = 1; 687 buffer->stop = 1;
671 }
672 break; 688 break;
673 } 689 }
674 *line++ = c; 690 *line++ = c;
675 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 691 if (buffer->curr >= buffer->size) {
676 buffer->stop = 1; 692 buffer->stop = 1;
677 break; 693 break;
678 } 694 }
679 } 695 }
680 while (c != '\n' && !buffer->stop) { 696 while (c != '\n' && !buffer->stop) {
681 c = *buffer->curr++; 697 c = buffer->buffer[buffer->curr++];
682 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 698 if (buffer->curr >= buffer->size)
683 buffer->stop = 1; 699 buffer->stop = 1;
684 }
685 } 700 }
686 *line = '\0'; 701 *line = '\0';
687 return 0; 702 return 0;
688} 703}
689 704
705EXPORT_SYMBOL(snd_info_get_line);
706
690/** 707/**
691 * snd_info_get_str - parse a string token 708 * snd_info_get_str - parse a string token
692 * @dest: the buffer to store the string token 709 * @dest: the buffer to store the string token
@@ -723,6 +740,8 @@ char *snd_info_get_str(char *dest, char *src, int len)
723 return src; 740 return src;
724} 741}
725 742
743EXPORT_SYMBOL(snd_info_get_str);
744
726/** 745/**
727 * snd_info_create_entry - create an info entry 746 * snd_info_create_entry - create an info entry
728 * @name: the proc file name 747 * @name: the proc file name
@@ -774,6 +793,8 @@ struct snd_info_entry *snd_info_create_module_entry(struct module * module,
774 return entry; 793 return entry;
775} 794}
776 795
796EXPORT_SYMBOL(snd_info_create_module_entry);
797
777/** 798/**
778 * snd_info_create_card_entry - create an info entry for the given card 799 * snd_info_create_card_entry - create an info entry for the given card
779 * @card: the card instance 800 * @card: the card instance
@@ -797,6 +818,8 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
797 return entry; 818 return entry;
798} 819}
799 820
821EXPORT_SYMBOL(snd_info_create_card_entry);
822
800static int snd_info_dev_free_entry(struct snd_device *device) 823static int snd_info_dev_free_entry(struct snd_device *device)
801{ 824{
802 struct snd_info_entry *entry = device->device_data; 825 struct snd_info_entry *entry = device->device_data;
@@ -867,6 +890,8 @@ int snd_card_proc_new(struct snd_card *card, const char *name,
867 return 0; 890 return 0;
868} 891}
869 892
893EXPORT_SYMBOL(snd_card_proc_new);
894
870/** 895/**
871 * snd_info_free_entry - release the info entry 896 * snd_info_free_entry - release the info entry
872 * @entry: the info entry 897 * @entry: the info entry
@@ -883,6 +908,8 @@ void snd_info_free_entry(struct snd_info_entry * entry)
883 kfree(entry); 908 kfree(entry);
884} 909}
885 910
911EXPORT_SYMBOL(snd_info_free_entry);
912
886/** 913/**
887 * snd_info_register - register the info entry 914 * snd_info_register - register the info entry
888 * @entry: the info entry 915 * @entry: the info entry
@@ -913,6 +940,8 @@ int snd_info_register(struct snd_info_entry * entry)
913 return 0; 940 return 0;
914} 941}
915 942
943EXPORT_SYMBOL(snd_info_register);
944
916/** 945/**
917 * snd_info_unregister - de-register the info entry 946 * snd_info_unregister - de-register the info entry
918 * @entry: the info entry 947 * @entry: the info entry
@@ -937,11 +966,13 @@ int snd_info_unregister(struct snd_info_entry * entry)
937 return 0; 966 return 0;
938} 967}
939 968
969EXPORT_SYMBOL(snd_info_unregister);
970
940/* 971/*
941 972
942 */ 973 */
943 974
944static struct snd_info_entry *snd_info_version_entry = NULL; 975static struct snd_info_entry *snd_info_version_entry;
945 976
946static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 977static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
947{ 978{
@@ -958,7 +989,6 @@ static int __init snd_info_version_init(void)
958 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); 989 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
959 if (entry == NULL) 990 if (entry == NULL)
960 return -ENOMEM; 991 return -ENOMEM;
961 entry->c.text.read_size = 256;
962 entry->c.text.read = snd_info_version_read; 992 entry->c.text.read = snd_info_version_read;
963 if (snd_info_register(entry) < 0) { 993 if (snd_info_register(entry) < 0) {
964 snd_info_free_entry(entry); 994 snd_info_free_entry(entry);
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index f9ce854b3d11..bb2c40d0ab66 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -64,6 +64,8 @@ int snd_oss_info_register(int dev, int num, char *string)
64 return 0; 64 return 0;
65} 65}
66 66
67EXPORT_SYMBOL(snd_oss_info_register);
68
67extern void snd_card_info_read_oss(struct snd_info_buffer *buffer); 69extern void snd_card_info_read_oss(struct snd_info_buffer *buffer);
68 70
69static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) 71static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev)
@@ -117,7 +119,6 @@ int snd_info_minor_register(void)
117 119
118 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); 120 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings));
119 if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { 121 if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) {
120 entry->c.text.read_size = 2048;
121 entry->c.text.read = snd_sndstat_proc_read; 122 entry->c.text.read = snd_sndstat_proc_read;
122 if (snd_info_register(entry) < 0) { 123 if (snd_info_register(entry) < 0) {
123 snd_info_free_entry(entry); 124 snd_info_free_entry(entry);
diff --git a/sound/core/init.c b/sound/core/init.c
index 39ed2e5bb0af..4d9258884e44 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -38,12 +38,15 @@ struct snd_shutdown_f_ops {
38 struct snd_shutdown_f_ops *next; 38 struct snd_shutdown_f_ops *next;
39}; 39};
40 40
41unsigned int snd_cards_lock = 0; /* locked for registering/using */ 41static unsigned int snd_cards_lock; /* locked for registering/using */
42struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; 42struct snd_card *snd_cards[SNDRV_CARDS];
43DEFINE_RWLOCK(snd_card_rwlock); 43EXPORT_SYMBOL(snd_cards);
44
45static DEFINE_MUTEX(snd_card_mutex);
44 46
45#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 47#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
46int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); 48int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
49EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
47#endif 50#endif
48 51
49#ifdef CONFIG_PROC_FS 52#ifdef CONFIG_PROC_FS
@@ -66,7 +69,6 @@ static inline int init_info_for_card(struct snd_card *card)
66 snd_printd("unable to create card entry\n"); 69 snd_printd("unable to create card entry\n");
67 return err; 70 return err;
68 } 71 }
69 entry->c.text.read_size = PAGE_SIZE;
70 entry->c.text.read = snd_card_id_read; 72 entry->c.text.read = snd_card_id_read;
71 if (snd_info_register(entry) < 0) { 73 if (snd_info_register(entry) < 0) {
72 snd_info_free_entry(entry); 74 snd_info_free_entry(entry);
@@ -110,7 +112,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
110 strlcpy(card->id, xid, sizeof(card->id)); 112 strlcpy(card->id, xid, sizeof(card->id));
111 } 113 }
112 err = 0; 114 err = 0;
113 write_lock(&snd_card_rwlock); 115 mutex_lock(&snd_card_mutex);
114 if (idx < 0) { 116 if (idx < 0) {
115 int idx2; 117 int idx2;
116 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 118 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
@@ -128,12 +130,12 @@ struct snd_card *snd_card_new(int idx, const char *xid,
128 else 130 else
129 err = -ENODEV; 131 err = -ENODEV;
130 if (idx < 0 || err < 0) { 132 if (idx < 0 || err < 0) {
131 write_unlock(&snd_card_rwlock); 133 mutex_unlock(&snd_card_mutex);
132 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); 134 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1);
133 goto __error; 135 goto __error;
134 } 136 }
135 snd_cards_lock |= 1 << idx; /* lock it */ 137 snd_cards_lock |= 1 << idx; /* lock it */
136 write_unlock(&snd_card_rwlock); 138 mutex_unlock(&snd_card_mutex);
137 card->number = idx; 139 card->number = idx;
138 card->module = module; 140 card->module = module;
139 INIT_LIST_HEAD(&card->devices); 141 INIT_LIST_HEAD(&card->devices);
@@ -169,6 +171,19 @@ struct snd_card *snd_card_new(int idx, const char *xid,
169 return NULL; 171 return NULL;
170} 172}
171 173
174EXPORT_SYMBOL(snd_card_new);
175
176/* return non-zero if a card is already locked */
177int snd_card_locked(int card)
178{
179 int locked;
180
181 mutex_lock(&snd_card_mutex);
182 locked = snd_cards_lock & (1 << card);
183 mutex_unlock(&snd_card_mutex);
184 return locked;
185}
186
172static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) 187static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
173{ 188{
174 return -ENODEV; 189 return -ENODEV;
@@ -236,9 +251,9 @@ int snd_card_disconnect(struct snd_card *card)
236 spin_unlock(&card->files_lock); 251 spin_unlock(&card->files_lock);
237 252
238 /* phase 1: disable fops (user space) operations for ALSA API */ 253 /* phase 1: disable fops (user space) operations for ALSA API */
239 write_lock(&snd_card_rwlock); 254 mutex_lock(&snd_card_mutex);
240 snd_cards[card->number] = NULL; 255 snd_cards[card->number] = NULL;
241 write_unlock(&snd_card_rwlock); 256 mutex_unlock(&snd_card_mutex);
242 257
243 /* phase 2: replace file->f_op with special dummy operations */ 258 /* phase 2: replace file->f_op with special dummy operations */
244 259
@@ -298,6 +313,8 @@ int snd_card_disconnect(struct snd_card *card)
298 return 0; 313 return 0;
299} 314}
300 315
316EXPORT_SYMBOL(snd_card_disconnect);
317
301/** 318/**
302 * snd_card_free - frees given soundcard structure 319 * snd_card_free - frees given soundcard structure
303 * @card: soundcard structure 320 * @card: soundcard structure
@@ -315,9 +332,9 @@ int snd_card_free(struct snd_card *card)
315 332
316 if (card == NULL) 333 if (card == NULL)
317 return -EINVAL; 334 return -EINVAL;
318 write_lock(&snd_card_rwlock); 335 mutex_lock(&snd_card_mutex);
319 snd_cards[card->number] = NULL; 336 snd_cards[card->number] = NULL;
320 write_unlock(&snd_card_rwlock); 337 mutex_unlock(&snd_card_mutex);
321 338
322#ifdef CONFIG_PM 339#ifdef CONFIG_PM
323 wake_up(&card->power_sleep); 340 wake_up(&card->power_sleep);
@@ -353,13 +370,15 @@ int snd_card_free(struct snd_card *card)
353 card->s_f_ops = s_f_ops->next; 370 card->s_f_ops = s_f_ops->next;
354 kfree(s_f_ops); 371 kfree(s_f_ops);
355 } 372 }
356 write_lock(&snd_card_rwlock); 373 mutex_lock(&snd_card_mutex);
357 snd_cards_lock &= ~(1 << card->number); 374 snd_cards_lock &= ~(1 << card->number);
358 write_unlock(&snd_card_rwlock); 375 mutex_unlock(&snd_card_mutex);
359 kfree(card); 376 kfree(card);
360 return 0; 377 return 0;
361} 378}
362 379
380EXPORT_SYMBOL(snd_card_free);
381
363static void snd_card_free_thread(void * __card) 382static void snd_card_free_thread(void * __card)
364{ 383{
365 struct snd_card *card = __card; 384 struct snd_card *card = __card;
@@ -405,6 +424,8 @@ int snd_card_free_in_thread(struct snd_card *card)
405 return -EFAULT; 424 return -EFAULT;
406} 425}
407 426
427EXPORT_SYMBOL(snd_card_free_in_thread);
428
408static void choose_default_id(struct snd_card *card) 429static void choose_default_id(struct snd_card *card)
409{ 430{
410 int i, len, idx_flag = 0, loops = SNDRV_CARDS; 431 int i, len, idx_flag = 0, loops = SNDRV_CARDS;
@@ -487,16 +508,16 @@ int snd_card_register(struct snd_card *card)
487 snd_assert(card != NULL, return -EINVAL); 508 snd_assert(card != NULL, return -EINVAL);
488 if ((err = snd_device_register_all(card)) < 0) 509 if ((err = snd_device_register_all(card)) < 0)
489 return err; 510 return err;
490 write_lock(&snd_card_rwlock); 511 mutex_lock(&snd_card_mutex);
491 if (snd_cards[card->number]) { 512 if (snd_cards[card->number]) {
492 /* already registered */ 513 /* already registered */
493 write_unlock(&snd_card_rwlock); 514 mutex_unlock(&snd_card_mutex);
494 return 0; 515 return 0;
495 } 516 }
496 if (card->id[0] == '\0') 517 if (card->id[0] == '\0')
497 choose_default_id(card); 518 choose_default_id(card);
498 snd_cards[card->number] = card; 519 snd_cards[card->number] = card;
499 write_unlock(&snd_card_rwlock); 520 mutex_unlock(&snd_card_mutex);
500 init_info_for_card(card); 521 init_info_for_card(card);
501#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 522#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
502 if (snd_mixer_oss_notify_callback) 523 if (snd_mixer_oss_notify_callback)
@@ -505,8 +526,10 @@ int snd_card_register(struct snd_card *card)
505 return 0; 526 return 0;
506} 527}
507 528
529EXPORT_SYMBOL(snd_card_register);
530
508#ifdef CONFIG_PROC_FS 531#ifdef CONFIG_PROC_FS
509static struct snd_info_entry *snd_card_info_entry = NULL; 532static struct snd_info_entry *snd_card_info_entry;
510 533
511static void snd_card_info_read(struct snd_info_entry *entry, 534static void snd_card_info_read(struct snd_info_entry *entry,
512 struct snd_info_buffer *buffer) 535 struct snd_info_buffer *buffer)
@@ -515,7 +538,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
515 struct snd_card *card; 538 struct snd_card *card;
516 539
517 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 540 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
518 read_lock(&snd_card_rwlock); 541 mutex_lock(&snd_card_mutex);
519 if ((card = snd_cards[idx]) != NULL) { 542 if ((card = snd_cards[idx]) != NULL) {
520 count++; 543 count++;
521 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", 544 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
@@ -526,7 +549,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
526 snd_iprintf(buffer, " %s\n", 549 snd_iprintf(buffer, " %s\n",
527 card->longname); 550 card->longname);
528 } 551 }
529 read_unlock(&snd_card_rwlock); 552 mutex_unlock(&snd_card_mutex);
530 } 553 }
531 if (!count) 554 if (!count)
532 snd_iprintf(buffer, "--- no soundcards ---\n"); 555 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -540,12 +563,12 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer)
540 struct snd_card *card; 563 struct snd_card *card;
541 564
542 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 565 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
543 read_lock(&snd_card_rwlock); 566 mutex_lock(&snd_card_mutex);
544 if ((card = snd_cards[idx]) != NULL) { 567 if ((card = snd_cards[idx]) != NULL) {
545 count++; 568 count++;
546 snd_iprintf(buffer, "%s\n", card->longname); 569 snd_iprintf(buffer, "%s\n", card->longname);
547 } 570 }
548 read_unlock(&snd_card_rwlock); 571 mutex_unlock(&snd_card_mutex);
549 } 572 }
550 if (!count) { 573 if (!count) {
551 snd_iprintf(buffer, "--- no soundcards ---\n"); 574 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -563,11 +586,11 @@ static void snd_card_module_info_read(struct snd_info_entry *entry,
563 struct snd_card *card; 586 struct snd_card *card;
564 587
565 for (idx = 0; idx < SNDRV_CARDS; idx++) { 588 for (idx = 0; idx < SNDRV_CARDS; idx++) {
566 read_lock(&snd_card_rwlock); 589 mutex_lock(&snd_card_mutex);
567 if ((card = snd_cards[idx]) != NULL) 590 if ((card = snd_cards[idx]) != NULL)
568 snd_iprintf(buffer, "%2i %s\n", 591 snd_iprintf(buffer, "%2i %s\n",
569 idx, card->module->name); 592 idx, card->module->name);
570 read_unlock(&snd_card_rwlock); 593 mutex_unlock(&snd_card_mutex);
571 } 594 }
572} 595}
573#endif 596#endif
@@ -579,7 +602,6 @@ int __init snd_card_info_init(void)
579 entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); 602 entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
580 if (! entry) 603 if (! entry)
581 return -ENOMEM; 604 return -ENOMEM;
582 entry->c.text.read_size = PAGE_SIZE;
583 entry->c.text.read = snd_card_info_read; 605 entry->c.text.read = snd_card_info_read;
584 if (snd_info_register(entry) < 0) { 606 if (snd_info_register(entry) < 0) {
585 snd_info_free_entry(entry); 607 snd_info_free_entry(entry);
@@ -590,7 +612,6 @@ int __init snd_card_info_init(void)
590#ifdef MODULE 612#ifdef MODULE
591 entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL); 613 entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
592 if (entry) { 614 if (entry) {
593 entry->c.text.read_size = PAGE_SIZE;
594 entry->c.text.read = snd_card_module_info_read; 615 entry->c.text.read = snd_card_module_info_read;
595 if (snd_info_register(entry) < 0) 616 if (snd_info_register(entry) < 0)
596 snd_info_free_entry(entry); 617 snd_info_free_entry(entry);
@@ -644,6 +665,8 @@ int snd_component_add(struct snd_card *card, const char *component)
644 return 0; 665 return 0;
645} 666}
646 667
668EXPORT_SYMBOL(snd_component_add);
669
647/** 670/**
648 * snd_card_file_add - add the file to the file list of the card 671 * snd_card_file_add - add the file to the file list of the card
649 * @card: soundcard structure 672 * @card: soundcard structure
@@ -676,6 +699,8 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
676 return 0; 699 return 0;
677} 700}
678 701
702EXPORT_SYMBOL(snd_card_file_add);
703
679/** 704/**
680 * snd_card_file_remove - remove the file from the file list 705 * snd_card_file_remove - remove the file from the file list
681 * @card: soundcard structure 706 * @card: soundcard structure
@@ -717,6 +742,8 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
717 return 0; 742 return 0;
718} 743}
719 744
745EXPORT_SYMBOL(snd_card_file_remove);
746
720#ifdef CONFIG_PM 747#ifdef CONFIG_PM
721/** 748/**
722 * snd_power_wait - wait until the power-state is changed. 749 * snd_power_wait - wait until the power-state is changed.
@@ -753,4 +780,5 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
753 return result; 780 return result;
754} 781}
755 782
783EXPORT_SYMBOL(snd_power_wait);
756#endif /* CONFIG_PM */ 784#endif /* CONFIG_PM */
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index 1a378951da5b..d52398727f0a 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -56,6 +56,8 @@ void snd_dma_program(unsigned long dma,
56 release_dma_lock(flags); 56 release_dma_lock(flags);
57} 57}
58 58
59EXPORT_SYMBOL(snd_dma_program);
60
59/** 61/**
60 * snd_dma_disable - stop the ISA DMA transfer 62 * snd_dma_disable - stop the ISA DMA transfer
61 * @dma: the dma number 63 * @dma: the dma number
@@ -72,6 +74,8 @@ void snd_dma_disable(unsigned long dma)
72 release_dma_lock(flags); 74 release_dma_lock(flags);
73} 75}
74 76
77EXPORT_SYMBOL(snd_dma_disable);
78
75/** 79/**
76 * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes 80 * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
77 * @dma: the dma number 81 * @dma: the dma number
@@ -101,3 +105,5 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
101 else 105 else
102 return size - result; 106 return size - result;
103} 107}
108
109EXPORT_SYMBOL(snd_dma_pointer);
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 862d62d2e144..fe59850be868 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/module.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26 27
@@ -55,6 +56,8 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size
55#endif 56#endif
56} 57}
57 58
59EXPORT_SYMBOL(copy_to_user_fromio);
60
58/** 61/**
59 * copy_from_user_toio - copy data from user-space to mmio-space 62 * copy_from_user_toio - copy data from user-space to mmio-space
60 * @dst: the destination pointer on mmio-space 63 * @dst: the destination pointer on mmio-space
@@ -85,3 +88,5 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size
85 return 0; 88 return 0;
86#endif 89#endif
87} 90}
91
92EXPORT_SYMBOL(copy_from_user_toio);
diff --git a/sound/core/misc.c b/sound/core/misc.c
index b53e563c09e6..03fc711f4127 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -34,6 +34,8 @@ void release_and_free_resource(struct resource *res)
34 } 34 }
35} 35}
36 36
37EXPORT_SYMBOL(release_and_free_resource);
38
37#ifdef CONFIG_SND_VERBOSE_PRINTK 39#ifdef CONFIG_SND_VERBOSE_PRINTK
38void snd_verbose_printk(const char *file, int line, const char *format, ...) 40void snd_verbose_printk(const char *file, int line, const char *format, ...)
39{ 41{
@@ -51,6 +53,8 @@ void snd_verbose_printk(const char *file, int line, const char *format, ...)
51 vprintk(format, args); 53 vprintk(format, args);
52 va_end(args); 54 va_end(args);
53} 55}
56
57EXPORT_SYMBOL(snd_verbose_printk);
54#endif 58#endif
55 59
56#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) 60#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
@@ -71,4 +75,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
71 va_end(args); 75 va_end(args);
72 76
73} 77}
78
79EXPORT_SYMBOL(snd_verbose_printd);
74#endif 80#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 9c68bc3f97aa..71b5080fa66d 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1182,9 +1182,7 @@ static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
1182 return; 1182 return;
1183 entry->content = SNDRV_INFO_CONTENT_TEXT; 1183 entry->content = SNDRV_INFO_CONTENT_TEXT;
1184 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 1184 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
1185 entry->c.text.read_size = 8192;
1186 entry->c.text.read = snd_mixer_oss_proc_read; 1185 entry->c.text.read = snd_mixer_oss_proc_read;
1187 entry->c.text.write_size = 8192;
1188 entry->c.text.write = snd_mixer_oss_proc_write; 1186 entry->c.text.write = snd_mixer_oss_proc_write;
1189 entry->private_data = mixer; 1187 entry->private_data = mixer;
1190 if (snd_info_register(entry) < 0) { 1188 if (snd_info_register(entry) < 0) {
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index ac990bf0b48f..f5ff4f4a16ee 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -45,7 +45,7 @@
45 45
46#define OSS_ALSAEMULVER _SIOR ('M', 249, int) 46#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
47 47
48static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; 48static int dsp_map[SNDRV_CARDS];
49static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; 49static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
50static int nonblock_open = 1; 50static int nonblock_open = 1;
51 51
@@ -78,6 +78,487 @@ static inline void snd_leave_user(mm_segment_t fs)
78 set_fs(fs); 78 set_fs(fs);
79} 79}
80 80
81/*
82 * helper functions to process hw_params
83 */
84static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
85{
86 int changed = 0;
87 if (i->min < min) {
88 i->min = min;
89 i->openmin = openmin;
90 changed = 1;
91 } else if (i->min == min && !i->openmin && openmin) {
92 i->openmin = 1;
93 changed = 1;
94 }
95 if (i->integer) {
96 if (i->openmin) {
97 i->min++;
98 i->openmin = 0;
99 }
100 }
101 if (snd_interval_checkempty(i)) {
102 snd_interval_none(i);
103 return -EINVAL;
104 }
105 return changed;
106}
107
108static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
109{
110 int changed = 0;
111 if (i->max > max) {
112 i->max = max;
113 i->openmax = openmax;
114 changed = 1;
115 } else if (i->max == max && !i->openmax && openmax) {
116 i->openmax = 1;
117 changed = 1;
118 }
119 if (i->integer) {
120 if (i->openmax) {
121 i->max--;
122 i->openmax = 0;
123 }
124 }
125 if (snd_interval_checkempty(i)) {
126 snd_interval_none(i);
127 return -EINVAL;
128 }
129 return changed;
130}
131
132static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
133{
134 struct snd_interval t;
135 t.empty = 0;
136 t.min = t.max = val;
137 t.openmin = t.openmax = 0;
138 t.integer = 1;
139 return snd_interval_refine(i, &t);
140}
141
142/**
143 * snd_pcm_hw_param_value_min
144 * @params: the hw_params instance
145 * @var: parameter to retrieve
146 * @dir: pointer to the direction (-1,0,1) or NULL
147 *
148 * Return the minimum value for field PAR.
149 */
150static unsigned int
151snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
152 snd_pcm_hw_param_t var, int *dir)
153{
154 if (hw_is_mask(var)) {
155 if (dir)
156 *dir = 0;
157 return snd_mask_min(hw_param_mask_c(params, var));
158 }
159 if (hw_is_interval(var)) {
160 const struct snd_interval *i = hw_param_interval_c(params, var);
161 if (dir)
162 *dir = i->openmin;
163 return snd_interval_min(i);
164 }
165 return -EINVAL;
166}
167
168/**
169 * snd_pcm_hw_param_value_max
170 * @params: the hw_params instance
171 * @var: parameter to retrieve
172 * @dir: pointer to the direction (-1,0,1) or NULL
173 *
174 * Return the maximum value for field PAR.
175 */
176static unsigned int
177snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
178 snd_pcm_hw_param_t var, int *dir)
179{
180 if (hw_is_mask(var)) {
181 if (dir)
182 *dir = 0;
183 return snd_mask_max(hw_param_mask_c(params, var));
184 }
185 if (hw_is_interval(var)) {
186 const struct snd_interval *i = hw_param_interval_c(params, var);
187 if (dir)
188 *dir = - (int) i->openmax;
189 return snd_interval_max(i);
190 }
191 return -EINVAL;
192}
193
194static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
195 snd_pcm_hw_param_t var,
196 const struct snd_mask *val)
197{
198 int changed;
199 changed = snd_mask_refine(hw_param_mask(params, var), val);
200 if (changed) {
201 params->cmask |= 1 << var;
202 params->rmask |= 1 << var;
203 }
204 return changed;
205}
206
207static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm,
208 struct snd_pcm_hw_params *params,
209 snd_pcm_hw_param_t var,
210 const struct snd_mask *val)
211{
212 int changed = _snd_pcm_hw_param_mask(params, var, val);
213 if (changed < 0)
214 return changed;
215 if (params->rmask) {
216 int err = snd_pcm_hw_refine(pcm, params);
217 if (err < 0)
218 return err;
219 }
220 return 0;
221}
222
223static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
224 snd_pcm_hw_param_t var, unsigned int val,
225 int dir)
226{
227 int changed;
228 int open = 0;
229 if (dir) {
230 if (dir > 0) {
231 open = 1;
232 } else if (dir < 0) {
233 if (val > 0) {
234 open = 1;
235 val--;
236 }
237 }
238 }
239 if (hw_is_mask(var))
240 changed = snd_mask_refine_min(hw_param_mask(params, var),
241 val + !!open);
242 else if (hw_is_interval(var))
243 changed = snd_interval_refine_min(hw_param_interval(params, var),
244 val, open);
245 else
246 return -EINVAL;
247 if (changed) {
248 params->cmask |= 1 << var;
249 params->rmask |= 1 << var;
250 }
251 return changed;
252}
253
254/**
255 * snd_pcm_hw_param_min
256 * @pcm: PCM instance
257 * @params: the hw_params instance
258 * @var: parameter to retrieve
259 * @val: minimal value
260 * @dir: pointer to the direction (-1,0,1) or NULL
261 *
262 * Inside configuration space defined by PARAMS remove from PAR all
263 * values < VAL. Reduce configuration space accordingly.
264 * Return new minimum or -EINVAL if the configuration space is empty
265 */
266static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm,
267 struct snd_pcm_hw_params *params,
268 snd_pcm_hw_param_t var, unsigned int val,
269 int *dir)
270{
271 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
272 if (changed < 0)
273 return changed;
274 if (params->rmask) {
275 int err = snd_pcm_hw_refine(pcm, params);
276 if (err < 0)
277 return err;
278 }
279 return snd_pcm_hw_param_value_min(params, var, dir);
280}
281
282static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
283 snd_pcm_hw_param_t var, unsigned int val,
284 int dir)
285{
286 int changed;
287 int open = 0;
288 if (dir) {
289 if (dir < 0) {
290 open = 1;
291 } else if (dir > 0) {
292 open = 1;
293 val++;
294 }
295 }
296 if (hw_is_mask(var)) {
297 if (val == 0 && open) {
298 snd_mask_none(hw_param_mask(params, var));
299 changed = -EINVAL;
300 } else
301 changed = snd_mask_refine_max(hw_param_mask(params, var),
302 val - !!open);
303 } else if (hw_is_interval(var))
304 changed = snd_interval_refine_max(hw_param_interval(params, var),
305 val, open);
306 else
307 return -EINVAL;
308 if (changed) {
309 params->cmask |= 1 << var;
310 params->rmask |= 1 << var;
311 }
312 return changed;
313}
314
315/**
316 * snd_pcm_hw_param_max
317 * @pcm: PCM instance
318 * @params: the hw_params instance
319 * @var: parameter to retrieve
320 * @val: maximal value
321 * @dir: pointer to the direction (-1,0,1) or NULL
322 *
323 * Inside configuration space defined by PARAMS remove from PAR all
324 * values >= VAL + 1. Reduce configuration space accordingly.
325 * Return new maximum or -EINVAL if the configuration space is empty
326 */
327static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm,
328 struct snd_pcm_hw_params *params,
329 snd_pcm_hw_param_t var, unsigned int val,
330 int *dir)
331{
332 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
333 if (changed < 0)
334 return changed;
335 if (params->rmask) {
336 int err = snd_pcm_hw_refine(pcm, params);
337 if (err < 0)
338 return err;
339 }
340 return snd_pcm_hw_param_value_max(params, var, dir);
341}
342
343static int boundary_sub(int a, int adir,
344 int b, int bdir,
345 int *c, int *cdir)
346{
347 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
348 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
349 *c = a - b;
350 *cdir = adir - bdir;
351 if (*cdir == -2) {
352 (*c)--;
353 } else if (*cdir == 2) {
354 (*c)++;
355 }
356 return 0;
357}
358
359static int boundary_lt(unsigned int a, int adir,
360 unsigned int b, int bdir)
361{
362 if (adir < 0) {
363 a--;
364 adir = 1;
365 } else if (adir > 0)
366 adir = 1;
367 if (bdir < 0) {
368 b--;
369 bdir = 1;
370 } else if (bdir > 0)
371 bdir = 1;
372 return a < b || (a == b && adir < bdir);
373}
374
375/* Return 1 if min is nearer to best than max */
376static int boundary_nearer(int min, int mindir,
377 int best, int bestdir,
378 int max, int maxdir)
379{
380 int dmin, dmindir;
381 int dmax, dmaxdir;
382 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
383 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
384 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
385}
386
387/**
388 * snd_pcm_hw_param_near
389 * @pcm: PCM instance
390 * @params: the hw_params instance
391 * @var: parameter to retrieve
392 * @best: value to set
393 * @dir: pointer to the direction (-1,0,1) or NULL
394 *
395 * Inside configuration space defined by PARAMS set PAR to the available value
396 * nearest to VAL. Reduce configuration space accordingly.
397 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
398 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
399 * Return the value found.
400 */
401static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
402 struct snd_pcm_hw_params *params,
403 snd_pcm_hw_param_t var, unsigned int best,
404 int *dir)
405{
406 struct snd_pcm_hw_params *save = NULL;
407 int v;
408 unsigned int saved_min;
409 int last = 0;
410 int min, max;
411 int mindir, maxdir;
412 int valdir = dir ? *dir : 0;
413 /* FIXME */
414 if (best > INT_MAX)
415 best = INT_MAX;
416 min = max = best;
417 mindir = maxdir = valdir;
418 if (maxdir > 0)
419 maxdir = 0;
420 else if (maxdir == 0)
421 maxdir = -1;
422 else {
423 maxdir = 1;
424 max--;
425 }
426 save = kmalloc(sizeof(*save), GFP_KERNEL);
427 if (save == NULL)
428 return -ENOMEM;
429 *save = *params;
430 saved_min = min;
431 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
432 if (min >= 0) {
433 struct snd_pcm_hw_params *params1;
434 if (max < 0)
435 goto _end;
436 if ((unsigned int)min == saved_min && mindir == valdir)
437 goto _end;
438 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
439 if (params1 == NULL) {
440 kfree(save);
441 return -ENOMEM;
442 }
443 *params1 = *save;
444 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
445 if (max < 0) {
446 kfree(params1);
447 goto _end;
448 }
449 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
450 *params = *params1;
451 last = 1;
452 }
453 kfree(params1);
454 } else {
455 *params = *save;
456 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
457 snd_assert(max >= 0, return -EINVAL);
458 last = 1;
459 }
460 _end:
461 kfree(save);
462 if (last)
463 v = snd_pcm_hw_param_last(pcm, params, var, dir);
464 else
465 v = snd_pcm_hw_param_first(pcm, params, var, dir);
466 snd_assert(v >= 0, return -EINVAL);
467 return v;
468}
469
470static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
471 snd_pcm_hw_param_t var, unsigned int val,
472 int dir)
473{
474 int changed;
475 if (hw_is_mask(var)) {
476 struct snd_mask *m = hw_param_mask(params, var);
477 if (val == 0 && dir < 0) {
478 changed = -EINVAL;
479 snd_mask_none(m);
480 } else {
481 if (dir > 0)
482 val++;
483 else if (dir < 0)
484 val--;
485 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
486 }
487 } else if (hw_is_interval(var)) {
488 struct snd_interval *i = hw_param_interval(params, var);
489 if (val == 0 && dir < 0) {
490 changed = -EINVAL;
491 snd_interval_none(i);
492 } else if (dir == 0)
493 changed = snd_interval_refine_set(i, val);
494 else {
495 struct snd_interval t;
496 t.openmin = 1;
497 t.openmax = 1;
498 t.empty = 0;
499 t.integer = 0;
500 if (dir < 0) {
501 t.min = val - 1;
502 t.max = val;
503 } else {
504 t.min = val;
505 t.max = val+1;
506 }
507 changed = snd_interval_refine(i, &t);
508 }
509 } else
510 return -EINVAL;
511 if (changed) {
512 params->cmask |= 1 << var;
513 params->rmask |= 1 << var;
514 }
515 return changed;
516}
517
518/**
519 * snd_pcm_hw_param_set
520 * @pcm: PCM instance
521 * @params: the hw_params instance
522 * @var: parameter to retrieve
523 * @val: value to set
524 * @dir: pointer to the direction (-1,0,1) or NULL
525 *
526 * Inside configuration space defined by PARAMS remove from PAR all
527 * values != VAL. Reduce configuration space accordingly.
528 * Return VAL or -EINVAL if the configuration space is empty
529 */
530static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
531 struct snd_pcm_hw_params *params,
532 snd_pcm_hw_param_t var, unsigned int val,
533 int dir)
534{
535 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
536 if (changed < 0)
537 return changed;
538 if (params->rmask) {
539 int err = snd_pcm_hw_refine(pcm, params);
540 if (err < 0)
541 return err;
542 }
543 return snd_pcm_hw_param_value(params, var, NULL);
544}
545
546static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
547 snd_pcm_hw_param_t var)
548{
549 int changed;
550 changed = snd_interval_setinteger(hw_param_interval(params, var));
551 if (changed) {
552 params->cmask |= 1 << var;
553 params->rmask |= 1 << var;
554 }
555 return changed;
556}
557
558/*
559 * plugin
560 */
561
81#ifdef CONFIG_SND_PCM_OSS_PLUGINS 562#ifdef CONFIG_SND_PCM_OSS_PLUGINS
82static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) 563static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
83{ 564{
@@ -203,7 +684,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
203 oss_buffer_size = snd_pcm_plug_client_size(substream, 684 oss_buffer_size = snd_pcm_plug_client_size(substream,
204 snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; 685 snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
205 oss_buffer_size = 1 << ld2(oss_buffer_size); 686 oss_buffer_size = 1 << ld2(oss_buffer_size);
206 if (atomic_read(&runtime->mmap_count)) { 687 if (atomic_read(&substream->mmap_count)) {
207 if (oss_buffer_size > runtime->oss.mmap_bytes) 688 if (oss_buffer_size > runtime->oss.mmap_bytes)
208 oss_buffer_size = runtime->oss.mmap_bytes; 689 oss_buffer_size = runtime->oss.mmap_bytes;
209 } 690 }
@@ -338,7 +819,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
338 goto failure; 819 goto failure;
339 } 820 }
340 821
341 if (atomic_read(&runtime->mmap_count)) 822 if (atomic_read(&substream->mmap_count))
342 direct = 1; 823 direct = 1;
343 else 824 else
344 direct = substream->oss.setup.direct; 825 direct = substream->oss.setup.direct;
@@ -347,7 +828,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
347 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); 828 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
348 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0); 829 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
349 snd_mask_none(&mask); 830 snd_mask_none(&mask);
350 if (atomic_read(&runtime->mmap_count)) 831 if (atomic_read(&substream->mmap_count))
351 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); 832 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
352 else { 833 else {
353 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED); 834 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED);
@@ -466,7 +947,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
466 } else { 947 } else {
467 sw_params->start_threshold = runtime->boundary; 948 sw_params->start_threshold = runtime->boundary;
468 } 949 }
469 if (atomic_read(&runtime->mmap_count) || substream->stream == SNDRV_PCM_STREAM_CAPTURE) 950 if (atomic_read(&substream->mmap_count) ||
951 substream->stream == SNDRV_PCM_STREAM_CAPTURE)
470 sw_params->stop_threshold = runtime->boundary; 952 sw_params->stop_threshold = runtime->boundary;
471 else 953 else
472 sw_params->stop_threshold = runtime->buffer_size; 954 sw_params->stop_threshold = runtime->buffer_size;
@@ -476,7 +958,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
476 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 958 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
477 1 : runtime->period_size; 959 1 : runtime->period_size;
478 sw_params->xfer_align = 1; 960 sw_params->xfer_align = 1;
479 if (atomic_read(&runtime->mmap_count) || 961 if (atomic_read(&substream->mmap_count) ||
480 substream->oss.setup.nosilence) { 962 substream->oss.setup.nosilence) {
481 sw_params->silence_threshold = 0; 963 sw_params->silence_threshold = 0;
482 sw_params->silence_size = 0; 964 sw_params->silence_size = 0;
@@ -820,7 +1302,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
820 ssize_t tmp; 1302 ssize_t tmp;
821 struct snd_pcm_runtime *runtime = substream->runtime; 1303 struct snd_pcm_runtime *runtime = substream->runtime;
822 1304
823 if (atomic_read(&runtime->mmap_count)) 1305 if (atomic_read(&substream->mmap_count))
824 return -ENXIO; 1306 return -ENXIO;
825 1307
826 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1308 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
@@ -850,7 +1332,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
850 if (runtime->oss.period_ptr == 0 || 1332 if (runtime->oss.period_ptr == 0 ||
851 runtime->oss.period_ptr == runtime->oss.buffer_used) 1333 runtime->oss.period_ptr == runtime->oss.buffer_used)
852 runtime->oss.buffer_used = 0; 1334 runtime->oss.buffer_used = 0;
853 else if ((substream->ffile->f_flags & O_NONBLOCK) != 0) 1335 else if ((substream->f_flags & O_NONBLOCK) != 0)
854 return xfer > 0 ? xfer : -EAGAIN; 1336 return xfer > 0 ? xfer : -EAGAIN;
855 } 1337 }
856 } else { 1338 } else {
@@ -863,7 +1345,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
863 buf += tmp; 1345 buf += tmp;
864 bytes -= tmp; 1346 bytes -= tmp;
865 xfer += tmp; 1347 xfer += tmp;
866 if ((substream->ffile->f_flags & O_NONBLOCK) != 0 && 1348 if ((substream->f_flags & O_NONBLOCK) != 0 &&
867 tmp != runtime->oss.period_bytes) 1349 tmp != runtime->oss.period_bytes)
868 break; 1350 break;
869 } 1351 }
@@ -910,7 +1392,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
910 ssize_t tmp; 1392 ssize_t tmp;
911 struct snd_pcm_runtime *runtime = substream->runtime; 1393 struct snd_pcm_runtime *runtime = substream->runtime;
912 1394
913 if (atomic_read(&runtime->mmap_count)) 1395 if (atomic_read(&substream->mmap_count))
914 return -ENXIO; 1396 return -ENXIO;
915 1397
916 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1398 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
@@ -1040,7 +1522,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1040 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 1522 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
1041 if (substream != NULL) { 1523 if (substream != NULL) {
1042 runtime = substream->runtime; 1524 runtime = substream->runtime;
1043 if (atomic_read(&runtime->mmap_count)) 1525 if (atomic_read(&substream->mmap_count))
1044 goto __direct; 1526 goto __direct;
1045 if ((err = snd_pcm_oss_make_ready(substream)) < 0) 1527 if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1046 return err; 1528 return err;
@@ -1101,10 +1583,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1101 * finish sync: drain the buffer 1583 * finish sync: drain the buffer
1102 */ 1584 */
1103 __direct: 1585 __direct:
1104 saved_f_flags = substream->ffile->f_flags; 1586 saved_f_flags = substream->f_flags;
1105 substream->ffile->f_flags &= ~O_NONBLOCK; 1587 substream->f_flags &= ~O_NONBLOCK;
1106 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); 1588 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1107 substream->ffile->f_flags = saved_f_flags; 1589 substream->f_flags = saved_f_flags;
1108 if (err < 0) 1590 if (err < 0)
1109 return err; 1591 return err;
1110 runtime->oss.prepare = 1; 1592 runtime->oss.prepare = 1;
@@ -1209,7 +1691,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1209 1691
1210 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) 1692 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1211 return err; 1693 return err;
1212 if (atomic_read(&substream->runtime->mmap_count)) 1694 if (atomic_read(&substream->mmap_count))
1213 direct = 1; 1695 direct = 1;
1214 else 1696 else
1215 direct = substream->oss.setup.direct; 1697 direct = substream->oss.setup.direct;
@@ -1419,7 +1901,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1419 if (trigger & PCM_ENABLE_OUTPUT) { 1901 if (trigger & PCM_ENABLE_OUTPUT) {
1420 if (runtime->oss.trigger) 1902 if (runtime->oss.trigger)
1421 goto _skip1; 1903 goto _skip1;
1422 if (atomic_read(&psubstream->runtime->mmap_count)) 1904 if (atomic_read(&psubstream->mmap_count))
1423 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1905 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt);
1424 runtime->oss.trigger = 1; 1906 runtime->oss.trigger = 1;
1425 runtime->start_threshold = 1; 1907 runtime->start_threshold = 1;
@@ -1537,7 +2019,7 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
1537 if (err < 0) 2019 if (err < 0)
1538 return err; 2020 return err;
1539 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2021 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
1540 if (atomic_read(&runtime->mmap_count)) { 2022 if (atomic_read(&substream->mmap_count)) {
1541 snd_pcm_sframes_t n; 2023 snd_pcm_sframes_t n;
1542 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2024 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt;
1543 if (n < 0) 2025 if (n < 0)
@@ -1683,9 +2165,9 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
1683 substream->oss.oss = 1; 2165 substream->oss.oss = 1;
1684 substream->oss.setup = *setup; 2166 substream->oss.setup = *setup;
1685 if (setup->nonblock) 2167 if (setup->nonblock)
1686 substream->ffile->f_flags |= O_NONBLOCK; 2168 substream->f_flags |= O_NONBLOCK;
1687 else if (setup->block) 2169 else if (setup->block)
1688 substream->ffile->f_flags &= ~O_NONBLOCK; 2170 substream->f_flags &= ~O_NONBLOCK;
1689 runtime = substream->runtime; 2171 runtime = substream->runtime;
1690 runtime->oss.params = 1; 2172 runtime->oss.params = 1;
1691 runtime->oss.trigger = 1; 2173 runtime->oss.trigger = 1;
@@ -1742,6 +2224,7 @@ static int snd_pcm_oss_open_file(struct file *file,
1742 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) 2224 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
1743 f_mode = FMODE_WRITE; 2225 f_mode = FMODE_WRITE;
1744 2226
2227 file->f_flags &= ~O_APPEND;
1745 for (idx = 0; idx < 2; idx++) { 2228 for (idx = 0; idx < 2; idx++) {
1746 if (setup[idx].disable) 2229 if (setup[idx].disable)
1747 continue; 2230 continue;
@@ -2059,6 +2542,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t coun
2059 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 2542 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2060 if (substream == NULL) 2543 if (substream == NULL)
2061 return -ENXIO; 2544 return -ENXIO;
2545 substream->f_flags = file->f_flags & O_NONBLOCK;
2062#ifndef OSS_DEBUG 2546#ifndef OSS_DEBUG
2063 return snd_pcm_oss_read1(substream, buf, count); 2547 return snd_pcm_oss_read1(substream, buf, count);
2064#else 2548#else
@@ -2080,6 +2564,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2080 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 2564 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2081 if (substream == NULL) 2565 if (substream == NULL)
2082 return -ENXIO; 2566 return -ENXIO;
2567 substream->f_flags = file->f_flags & O_NONBLOCK;
2083 result = snd_pcm_oss_write1(substream, buf, count); 2568 result = snd_pcm_oss_write1(substream, buf, count);
2084#ifdef OSS_DEBUG 2569#ifdef OSS_DEBUG
2085 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); 2570 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
@@ -2090,7 +2575,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2090static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) 2575static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2091{ 2576{
2092 struct snd_pcm_runtime *runtime = substream->runtime; 2577 struct snd_pcm_runtime *runtime = substream->runtime;
2093 if (atomic_read(&runtime->mmap_count)) 2578 if (atomic_read(&substream->mmap_count))
2094 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2579 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
2095 else 2580 else
2096 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2581 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames;
@@ -2099,7 +2584,7 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2099static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2584static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2100{ 2585{
2101 struct snd_pcm_runtime *runtime = substream->runtime; 2586 struct snd_pcm_runtime *runtime = substream->runtime;
2102 if (atomic_read(&runtime->mmap_count)) 2587 if (atomic_read(&substream->mmap_count))
2103 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2588 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
2104 else 2589 else
2105 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2590 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames;
@@ -2342,9 +2827,7 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
2342 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) { 2827 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
2343 entry->content = SNDRV_INFO_CONTENT_TEXT; 2828 entry->content = SNDRV_INFO_CONTENT_TEXT;
2344 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 2829 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
2345 entry->c.text.read_size = 8192;
2346 entry->c.text.read = snd_pcm_oss_proc_read; 2830 entry->c.text.read = snd_pcm_oss_proc_read;
2347 entry->c.text.write_size = 8192;
2348 entry->c.text.write = snd_pcm_oss_proc_write; 2831 entry->c.text.write = snd_pcm_oss_proc_write;
2349 entry->private_data = pstr; 2832 entry->private_data = pstr;
2350 if (snd_info_register(entry) < 0) { 2833 if (snd_info_register(entry) < 0) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 84b00038236d..7581edd7b9ff 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -351,10 +351,8 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
351 snd_iprintf(buffer, "closed\n"); 351 snd_iprintf(buffer, "closed\n");
352 return; 352 return;
353 } 353 }
354 snd_pcm_stream_lock_irq(substream);
355 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 354 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
356 snd_iprintf(buffer, "no setup\n"); 355 snd_iprintf(buffer, "no setup\n");
357 snd_pcm_stream_unlock_irq(substream);
358 return; 356 return;
359 } 357 }
360 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); 358 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
@@ -375,7 +373,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
375 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); 373 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
376 } 374 }
377#endif 375#endif
378 snd_pcm_stream_unlock_irq(substream);
379} 376}
380 377
381static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, 378static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
@@ -387,10 +384,8 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
387 snd_iprintf(buffer, "closed\n"); 384 snd_iprintf(buffer, "closed\n");
388 return; 385 return;
389 } 386 }
390 snd_pcm_stream_lock_irq(substream);
391 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 387 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
392 snd_iprintf(buffer, "no setup\n"); 388 snd_iprintf(buffer, "no setup\n");
393 snd_pcm_stream_unlock_irq(substream);
394 return; 389 return;
395 } 390 }
396 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); 391 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
@@ -403,7 +398,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
403 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); 398 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
404 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); 399 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
405 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); 400 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
406 snd_pcm_stream_unlock_irq(substream);
407} 401}
408 402
409static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, 403static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
@@ -472,7 +466,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
472 pstr->proc_root = entry; 466 pstr->proc_root = entry;
473 467
474 if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { 468 if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {
475 snd_info_set_text_ops(entry, pstr, 256, snd_pcm_stream_proc_info_read); 469 snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
476 if (snd_info_register(entry) < 0) { 470 if (snd_info_register(entry) < 0) {
477 snd_info_free_entry(entry); 471 snd_info_free_entry(entry);
478 entry = NULL; 472 entry = NULL;
@@ -483,9 +477,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
483#ifdef CONFIG_SND_PCM_XRUN_DEBUG 477#ifdef CONFIG_SND_PCM_XRUN_DEBUG
484 if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", 478 if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
485 pstr->proc_root)) != NULL) { 479 pstr->proc_root)) != NULL) {
486 entry->c.text.read_size = 64;
487 entry->c.text.read = snd_pcm_xrun_debug_read; 480 entry->c.text.read = snd_pcm_xrun_debug_read;
488 entry->c.text.write_size = 64;
489 entry->c.text.write = snd_pcm_xrun_debug_write; 481 entry->c.text.write = snd_pcm_xrun_debug_write;
490 entry->mode |= S_IWUSR; 482 entry->mode |= S_IWUSR;
491 entry->private_data = pstr; 483 entry->private_data = pstr;
@@ -537,7 +529,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
537 substream->proc_root = entry; 529 substream->proc_root = entry;
538 530
539 if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { 531 if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {
540 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_info_read); 532 snd_info_set_text_ops(entry, substream,
533 snd_pcm_substream_proc_info_read);
541 if (snd_info_register(entry) < 0) { 534 if (snd_info_register(entry) < 0) {
542 snd_info_free_entry(entry); 535 snd_info_free_entry(entry);
543 entry = NULL; 536 entry = NULL;
@@ -546,7 +539,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
546 substream->proc_info_entry = entry; 539 substream->proc_info_entry = entry;
547 540
548 if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { 541 if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {
549 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_hw_params_read); 542 snd_info_set_text_ops(entry, substream,
543 snd_pcm_substream_proc_hw_params_read);
550 if (snd_info_register(entry) < 0) { 544 if (snd_info_register(entry) < 0) {
551 snd_info_free_entry(entry); 545 snd_info_free_entry(entry);
552 entry = NULL; 546 entry = NULL;
@@ -555,7 +549,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
555 substream->proc_hw_params_entry = entry; 549 substream->proc_hw_params_entry = entry;
556 550
557 if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { 551 if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {
558 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_sw_params_read); 552 snd_info_set_text_ops(entry, substream,
553 snd_pcm_substream_proc_sw_params_read);
559 if (snd_info_register(entry) < 0) { 554 if (snd_info_register(entry) < 0) {
560 snd_info_free_entry(entry); 555 snd_info_free_entry(entry);
561 entry = NULL; 556 entry = NULL;
@@ -564,7 +559,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
564 substream->proc_sw_params_entry = entry; 559 substream->proc_sw_params_entry = entry;
565 560
566 if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { 561 if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {
567 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_status_read); 562 snd_info_set_text_ops(entry, substream,
563 snd_pcm_substream_proc_status_read);
568 if (snd_info_register(entry) < 0) { 564 if (snd_info_register(entry) < 0) {
569 snd_info_free_entry(entry); 565 snd_info_free_entry(entry);
570 entry = NULL; 566 entry = NULL;
@@ -666,11 +662,14 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
666 INIT_LIST_HEAD(&substream->self_group.substreams); 662 INIT_LIST_HEAD(&substream->self_group.substreams);
667 list_add_tail(&substream->link_list, &substream->self_group.substreams); 663 list_add_tail(&substream->link_list, &substream->self_group.substreams);
668 spin_lock_init(&substream->timer_lock); 664 spin_lock_init(&substream->timer_lock);
665 atomic_set(&substream->mmap_count, 0);
669 prev = substream; 666 prev = substream;
670 } 667 }
671 return 0; 668 return 0;
672} 669}
673 670
671EXPORT_SYMBOL(snd_pcm_new_stream);
672
674/** 673/**
675 * snd_pcm_new - create a new PCM instance 674 * snd_pcm_new - create a new PCM instance
676 * @card: the card instance 675 * @card: the card instance
@@ -730,6 +729,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
730 return 0; 729 return 0;
731} 730}
732 731
732EXPORT_SYMBOL(snd_pcm_new);
733
733static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 734static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
734{ 735{
735 struct snd_pcm_substream *substream, *substream_next; 736 struct snd_pcm_substream *substream, *substream_next;
@@ -829,6 +830,26 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
829 return -EINVAL; 830 return -EINVAL;
830 } 831 }
831 832
833 if (file->f_flags & O_APPEND) {
834 if (prefer_subdevice < 0) {
835 if (pstr->substream_count > 1)
836 return -EINVAL; /* must be unique */
837 substream = pstr->substream;
838 } else {
839 for (substream = pstr->substream; substream;
840 substream = substream->next)
841 if (substream->number == prefer_subdevice)
842 break;
843 }
844 if (! substream)
845 return -ENODEV;
846 if (! SUBSTREAM_BUSY(substream))
847 return -EBADFD;
848 substream->ref_count++;
849 *rsubstream = substream;
850 return 0;
851 }
852
832 if (prefer_subdevice >= 0) { 853 if (prefer_subdevice >= 0) {
833 for (substream = pstr->substream; substream; substream = substream->next) 854 for (substream = pstr->substream; substream; substream = substream->next)
834 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) 855 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
@@ -864,7 +885,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
864 memset((void*)runtime->control, 0, size); 885 memset((void*)runtime->control, 0, size);
865 886
866 init_waitqueue_head(&runtime->sleep); 887 init_waitqueue_head(&runtime->sleep);
867 atomic_set(&runtime->mmap_count, 0);
868 init_timer(&runtime->tick_timer); 888 init_timer(&runtime->tick_timer);
869 runtime->tick_timer.function = snd_pcm_tick_timer_func; 889 runtime->tick_timer.function = snd_pcm_tick_timer_func;
870 runtime->tick_timer.data = (unsigned long) substream; 890 runtime->tick_timer.data = (unsigned long) substream;
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
873 893
874 substream->runtime = runtime; 894 substream->runtime = runtime;
875 substream->private_data = pcm->private_data; 895 substream->private_data = pcm->private_data;
876 substream->ffile = file; 896 substream->ref_count = 1;
897 substream->f_flags = file->f_flags;
877 pstr->substream_opened++; 898 pstr->substream_opened++;
878 *rsubstream = substream; 899 *rsubstream = substream;
879 return 0; 900 return 0;
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
882void snd_pcm_detach_substream(struct snd_pcm_substream *substream) 903void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
883{ 904{
884 struct snd_pcm_runtime *runtime; 905 struct snd_pcm_runtime *runtime;
885 substream->file = NULL; 906
886 runtime = substream->runtime; 907 runtime = substream->runtime;
887 snd_assert(runtime != NULL, return); 908 snd_assert(runtime != NULL, return);
888 if (runtime->private_free != NULL) 909 if (runtime->private_free != NULL)
@@ -1022,6 +1043,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1022 return 0; 1043 return 0;
1023} 1044}
1024 1045
1046EXPORT_SYMBOL(snd_pcm_notify);
1047
1025#ifdef CONFIG_PROC_FS 1048#ifdef CONFIG_PROC_FS
1026/* 1049/*
1027 * Info interface 1050 * Info interface
@@ -1049,15 +1072,14 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
1049 mutex_unlock(&register_mutex); 1072 mutex_unlock(&register_mutex);
1050} 1073}
1051 1074
1052static struct snd_info_entry *snd_pcm_proc_entry = NULL; 1075static struct snd_info_entry *snd_pcm_proc_entry;
1053 1076
1054static void snd_pcm_proc_init(void) 1077static void snd_pcm_proc_init(void)
1055{ 1078{
1056 struct snd_info_entry *entry; 1079 struct snd_info_entry *entry;
1057 1080
1058 if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { 1081 if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
1059 snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, 1082 snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
1060 snd_pcm_proc_read);
1061 if (snd_info_register(entry) < 0) { 1083 if (snd_info_register(entry) < 0) {
1062 snd_info_free_entry(entry); 1084 snd_info_free_entry(entry);
1063 entry = NULL; 1085 entry = NULL;
@@ -1099,33 +1121,3 @@ static void __exit alsa_pcm_exit(void)
1099 1121
1100module_init(alsa_pcm_init) 1122module_init(alsa_pcm_init)
1101module_exit(alsa_pcm_exit) 1123module_exit(alsa_pcm_exit)
1102
1103EXPORT_SYMBOL(snd_pcm_new);
1104EXPORT_SYMBOL(snd_pcm_new_stream);
1105EXPORT_SYMBOL(snd_pcm_notify);
1106EXPORT_SYMBOL(snd_pcm_open_substream);
1107EXPORT_SYMBOL(snd_pcm_release_substream);
1108 /* pcm_native.c */
1109EXPORT_SYMBOL(snd_pcm_link_rwlock);
1110#ifdef CONFIG_PM
1111EXPORT_SYMBOL(snd_pcm_suspend);
1112EXPORT_SYMBOL(snd_pcm_suspend_all);
1113#endif
1114EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
1115EXPORT_SYMBOL(snd_pcm_mmap_data);
1116#if SNDRV_PCM_INFO_MMAP_IOMEM
1117EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
1118#endif
1119 /* pcm_misc.c */
1120EXPORT_SYMBOL(snd_pcm_format_signed);
1121EXPORT_SYMBOL(snd_pcm_format_unsigned);
1122EXPORT_SYMBOL(snd_pcm_format_linear);
1123EXPORT_SYMBOL(snd_pcm_format_little_endian);
1124EXPORT_SYMBOL(snd_pcm_format_big_endian);
1125EXPORT_SYMBOL(snd_pcm_format_width);
1126EXPORT_SYMBOL(snd_pcm_format_physical_width);
1127EXPORT_SYMBOL(snd_pcm_format_size);
1128EXPORT_SYMBOL(snd_pcm_format_silence_64);
1129EXPORT_SYMBOL(snd_pcm_format_set_silence);
1130EXPORT_SYMBOL(snd_pcm_build_linear_format);
1131EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index e5133033de5e..2b8aab6fd6cd 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -497,9 +497,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
497 case SNDRV_PCM_IOCTL_LINK: 497 case SNDRV_PCM_IOCTL_LINK:
498 case SNDRV_PCM_IOCTL_UNLINK: 498 case SNDRV_PCM_IOCTL_UNLINK:
499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
500 return snd_pcm_playback_ioctl1(substream, cmd, argp); 500 return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
501 else 501 else
502 return snd_pcm_capture_ioctl1(substream, cmd, argp); 502 return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
503 case SNDRV_PCM_IOCTL_HW_REFINE32: 503 case SNDRV_PCM_IOCTL_HW_REFINE32:
504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); 504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
505 case SNDRV_PCM_IOCTL_HW_PARAMS32: 505 case SNDRV_PCM_IOCTL_HW_PARAMS32:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index eedc6cb038bb..0bb142a28539 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -289,6 +289,7 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops
289 substream->ops = ops; 289 substream->ops = ops;
290} 290}
291 291
292EXPORT_SYMBOL(snd_pcm_set_ops);
292 293
293/** 294/**
294 * snd_pcm_sync - set the PCM sync id 295 * snd_pcm_sync - set the PCM sync id
@@ -306,13 +307,12 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream)
306 runtime->sync.id32[3] = -1; 307 runtime->sync.id32[3] = -1;
307} 308}
308 309
310EXPORT_SYMBOL(snd_pcm_set_sync);
311
309/* 312/*
310 * Standard ioctl routine 313 * Standard ioctl routine
311 */ 314 */
312 315
313/* Code taken from alsa-lib */
314#define assert(a) snd_assert((a), return -EINVAL)
315
316static inline unsigned int div32(unsigned int a, unsigned int b, 316static inline unsigned int div32(unsigned int a, unsigned int b,
317 unsigned int *r) 317 unsigned int *r)
318{ 318{
@@ -369,56 +369,6 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
369 return n; 369 return n;
370} 370}
371 371
372static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
373{
374 int changed = 0;
375 assert(!snd_interval_empty(i));
376 if (i->min < min) {
377 i->min = min;
378 i->openmin = openmin;
379 changed = 1;
380 } else if (i->min == min && !i->openmin && openmin) {
381 i->openmin = 1;
382 changed = 1;
383 }
384 if (i->integer) {
385 if (i->openmin) {
386 i->min++;
387 i->openmin = 0;
388 }
389 }
390 if (snd_interval_checkempty(i)) {
391 snd_interval_none(i);
392 return -EINVAL;
393 }
394 return changed;
395}
396
397static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
398{
399 int changed = 0;
400 assert(!snd_interval_empty(i));
401 if (i->max > max) {
402 i->max = max;
403 i->openmax = openmax;
404 changed = 1;
405 } else if (i->max == max && !i->openmax && openmax) {
406 i->openmax = 1;
407 changed = 1;
408 }
409 if (i->integer) {
410 if (i->openmax) {
411 i->max--;
412 i->openmax = 0;
413 }
414 }
415 if (snd_interval_checkempty(i)) {
416 snd_interval_none(i);
417 return -EINVAL;
418 }
419 return changed;
420}
421
422/** 372/**
423 * snd_interval_refine - refine the interval value of configurator 373 * snd_interval_refine - refine the interval value of configurator
424 * @i: the interval value to refine 374 * @i: the interval value to refine
@@ -433,7 +383,7 @@ static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int
433int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) 383int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
434{ 384{
435 int changed = 0; 385 int changed = 0;
436 assert(!snd_interval_empty(i)); 386 snd_assert(!snd_interval_empty(i), return -EINVAL);
437 if (i->min < v->min) { 387 if (i->min < v->min) {
438 i->min = v->min; 388 i->min = v->min;
439 i->openmin = v->openmin; 389 i->openmin = v->openmin;
@@ -472,9 +422,11 @@ int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
472 return changed; 422 return changed;
473} 423}
474 424
425EXPORT_SYMBOL(snd_interval_refine);
426
475static int snd_interval_refine_first(struct snd_interval *i) 427static int snd_interval_refine_first(struct snd_interval *i)
476{ 428{
477 assert(!snd_interval_empty(i)); 429 snd_assert(!snd_interval_empty(i), return -EINVAL);
478 if (snd_interval_single(i)) 430 if (snd_interval_single(i))
479 return 0; 431 return 0;
480 i->max = i->min; 432 i->max = i->min;
@@ -486,7 +438,7 @@ static int snd_interval_refine_first(struct snd_interval *i)
486 438
487static int snd_interval_refine_last(struct snd_interval *i) 439static int snd_interval_refine_last(struct snd_interval *i)
488{ 440{
489 assert(!snd_interval_empty(i)); 441 snd_assert(!snd_interval_empty(i), return -EINVAL);
490 if (snd_interval_single(i)) 442 if (snd_interval_single(i))
491 return 0; 443 return 0;
492 i->min = i->max; 444 i->min = i->max;
@@ -496,16 +448,6 @@ static int snd_interval_refine_last(struct snd_interval *i)
496 return 1; 448 return 1;
497} 449}
498 450
499static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
500{
501 struct snd_interval t;
502 t.empty = 0;
503 t.min = t.max = val;
504 t.openmin = t.openmax = 0;
505 t.integer = 1;
506 return snd_interval_refine(i, &t);
507}
508
509void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) 451void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
510{ 452{
511 if (a->empty || b->empty) { 453 if (a->empty || b->empty) {
@@ -621,7 +563,6 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
621 c->integer = 0; 563 c->integer = 0;
622} 564}
623 565
624#undef assert
625/* ---- */ 566/* ---- */
626 567
627 568
@@ -727,6 +668,8 @@ int snd_interval_ratnum(struct snd_interval *i,
727 return err; 668 return err;
728} 669}
729 670
671EXPORT_SYMBOL(snd_interval_ratnum);
672
730/** 673/**
731 * snd_interval_ratden - refine the interval value 674 * snd_interval_ratden - refine the interval value
732 * @i: interval to refine 675 * @i: interval to refine
@@ -877,6 +820,8 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *
877 return changed; 820 return changed;
878} 821}
879 822
823EXPORT_SYMBOL(snd_interval_list);
824
880static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) 825static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
881{ 826{
882 unsigned int n; 827 unsigned int n;
@@ -953,6 +898,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
953 return 0; 898 return 0;
954} 899}
955 900
901EXPORT_SYMBOL(snd_pcm_hw_rule_add);
902
956/** 903/**
957 * snd_pcm_hw_constraint_mask 904 * snd_pcm_hw_constraint_mask
958 * @runtime: PCM runtime instance 905 * @runtime: PCM runtime instance
@@ -1007,6 +954,8 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
1007 return snd_interval_setinteger(constrs_interval(constrs, var)); 954 return snd_interval_setinteger(constrs_interval(constrs, var));
1008} 955}
1009 956
957EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
958
1010/** 959/**
1011 * snd_pcm_hw_constraint_minmax 960 * snd_pcm_hw_constraint_minmax
1012 * @runtime: PCM runtime instance 961 * @runtime: PCM runtime instance
@@ -1028,6 +977,8 @@ int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
1028 return snd_interval_refine(constrs_interval(constrs, var), &t); 977 return snd_interval_refine(constrs_interval(constrs, var), &t);
1029} 978}
1030 979
980EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
981
1031static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, 982static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
1032 struct snd_pcm_hw_rule *rule) 983 struct snd_pcm_hw_rule *rule)
1033{ 984{
@@ -1055,6 +1006,8 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
1055 var, -1); 1006 var, -1);
1056} 1007}
1057 1008
1009EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
1010
1058static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, 1011static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1059 struct snd_pcm_hw_rule *rule) 1012 struct snd_pcm_hw_rule *rule)
1060{ 1013{
@@ -1087,6 +1040,8 @@ int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
1087 var, -1); 1040 var, -1);
1088} 1041}
1089 1042
1043EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
1044
1090static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, 1045static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1091 struct snd_pcm_hw_rule *rule) 1046 struct snd_pcm_hw_rule *rule)
1092{ 1047{
@@ -1118,6 +1073,8 @@ int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
1118 var, -1); 1073 var, -1);
1119} 1074}
1120 1075
1076EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
1077
1121static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, 1078static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
1122 struct snd_pcm_hw_rule *rule) 1079 struct snd_pcm_hw_rule *rule)
1123{ 1080{
@@ -1149,6 +1106,8 @@ int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
1149 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); 1106 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1150} 1107}
1151 1108
1109EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
1110
1152static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, 1111static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
1153 struct snd_pcm_hw_rule *rule) 1112 struct snd_pcm_hw_rule *rule)
1154{ 1113{
@@ -1173,6 +1132,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
1173 var, -1); 1132 var, -1);
1174} 1133}
1175 1134
1135EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
1136
1176static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 1137static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1177{ 1138{
1178 static int pow2_sizes[] = { 1139 static int pow2_sizes[] = {
@@ -1200,11 +1161,7 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1200 var, -1); 1161 var, -1);
1201} 1162}
1202 1163
1203/* To use the same code we have in alsa-lib */ 1164EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1204#define assert(i) snd_assert((i), return -EINVAL)
1205#ifndef INT_MIN
1206#define INT_MIN ((int)((unsigned int)INT_MAX+1))
1207#endif
1208 1165
1209static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, 1166static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1210 snd_pcm_hw_param_t var) 1167 snd_pcm_hw_param_t var)
@@ -1224,18 +1181,6 @@ static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1224 snd_BUG(); 1181 snd_BUG();
1225} 1182}
1226 1183
1227#if 0
1228/*
1229 * snd_pcm_hw_param_any
1230 */
1231int snd_pcm_hw_param_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1232 snd_pcm_hw_param_t var)
1233{
1234 _snd_pcm_hw_param_any(params, var);
1235 return snd_pcm_hw_refine(pcm, params);
1236}
1237#endif /* 0 */
1238
1239void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) 1184void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1240{ 1185{
1241 unsigned int k; 1186 unsigned int k;
@@ -1247,18 +1192,7 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1247 params->info = ~0U; 1192 params->info = ~0U;
1248} 1193}
1249 1194
1250#if 0 1195EXPORT_SYMBOL(_snd_pcm_hw_params_any);
1251/*
1252 * snd_pcm_hw_params_any
1253 *
1254 * Fill PARAMS with full configuration space boundaries
1255 */
1256int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params)
1257{
1258 _snd_pcm_hw_params_any(params);
1259 return snd_pcm_hw_refine(pcm, params);
1260}
1261#endif /* 0 */
1262 1196
1263/** 1197/**
1264 * snd_pcm_hw_param_value 1198 * snd_pcm_hw_param_value
@@ -1269,8 +1203,8 @@ int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1269 * Return the value for field PAR if it's fixed in configuration space 1203 * Return the value for field PAR if it's fixed in configuration space
1270 * defined by PARAMS. Return -EINVAL otherwise 1204 * defined by PARAMS. Return -EINVAL otherwise
1271 */ 1205 */
1272static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 1206int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1273 snd_pcm_hw_param_t var, int *dir) 1207 snd_pcm_hw_param_t var, int *dir)
1274{ 1208{
1275 if (hw_is_mask(var)) { 1209 if (hw_is_mask(var)) {
1276 const struct snd_mask *mask = hw_param_mask_c(params, var); 1210 const struct snd_mask *mask = hw_param_mask_c(params, var);
@@ -1288,61 +1222,10 @@ static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1288 *dir = i->openmin; 1222 *dir = i->openmin;
1289 return snd_interval_value(i); 1223 return snd_interval_value(i);
1290 } 1224 }
1291 assert(0);
1292 return -EINVAL;
1293}
1294
1295/**
1296 * snd_pcm_hw_param_value_min
1297 * @params: the hw_params instance
1298 * @var: parameter to retrieve
1299 * @dir: pointer to the direction (-1,0,1) or NULL
1300 *
1301 * Return the minimum value for field PAR.
1302 */
1303unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
1304 snd_pcm_hw_param_t var, int *dir)
1305{
1306 if (hw_is_mask(var)) {
1307 if (dir)
1308 *dir = 0;
1309 return snd_mask_min(hw_param_mask_c(params, var));
1310 }
1311 if (hw_is_interval(var)) {
1312 const struct snd_interval *i = hw_param_interval_c(params, var);
1313 if (dir)
1314 *dir = i->openmin;
1315 return snd_interval_min(i);
1316 }
1317 assert(0);
1318 return -EINVAL; 1225 return -EINVAL;
1319} 1226}
1320 1227
1321/** 1228EXPORT_SYMBOL(snd_pcm_hw_param_value);
1322 * snd_pcm_hw_param_value_max
1323 * @params: the hw_params instance
1324 * @var: parameter to retrieve
1325 * @dir: pointer to the direction (-1,0,1) or NULL
1326 *
1327 * Return the maximum value for field PAR.
1328 */
1329unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
1330 snd_pcm_hw_param_t var, int *dir)
1331{
1332 if (hw_is_mask(var)) {
1333 if (dir)
1334 *dir = 0;
1335 return snd_mask_max(hw_param_mask_c(params, var));
1336 }
1337 if (hw_is_interval(var)) {
1338 const struct snd_interval *i = hw_param_interval_c(params, var);
1339 if (dir)
1340 *dir = - (int) i->openmax;
1341 return snd_interval_max(i);
1342 }
1343 assert(0);
1344 return -EINVAL;
1345}
1346 1229
1347void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, 1230void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1348 snd_pcm_hw_param_t var) 1231 snd_pcm_hw_param_t var)
@@ -1360,42 +1243,7 @@ void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1360 } 1243 }
1361} 1244}
1362 1245
1363int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, 1246EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
1364 snd_pcm_hw_param_t var)
1365{
1366 int changed;
1367 assert(hw_is_interval(var));
1368 changed = snd_interval_setinteger(hw_param_interval(params, var));
1369 if (changed) {
1370 params->cmask |= 1 << var;
1371 params->rmask |= 1 << var;
1372 }
1373 return changed;
1374}
1375
1376#if 0
1377/*
1378 * snd_pcm_hw_param_setinteger
1379 *
1380 * Inside configuration space defined by PARAMS remove from PAR all
1381 * non integer values. Reduce configuration space accordingly.
1382 * Return -EINVAL if the configuration space is empty
1383 */
1384int snd_pcm_hw_param_setinteger(struct snd_pcm_substream *pcm,
1385 struct snd_pcm_hw_params *params,
1386 snd_pcm_hw_param_t var)
1387{
1388 int changed = _snd_pcm_hw_param_setinteger(params, var);
1389 if (changed < 0)
1390 return changed;
1391 if (params->rmask) {
1392 int err = snd_pcm_hw_refine(pcm, params);
1393 if (err < 0)
1394 return err;
1395 }
1396 return 0;
1397}
1398#endif /* 0 */
1399 1247
1400static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, 1248static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1401 snd_pcm_hw_param_t var) 1249 snd_pcm_hw_param_t var)
@@ -1405,10 +1253,8 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1405 changed = snd_mask_refine_first(hw_param_mask(params, var)); 1253 changed = snd_mask_refine_first(hw_param_mask(params, var));
1406 else if (hw_is_interval(var)) 1254 else if (hw_is_interval(var))
1407 changed = snd_interval_refine_first(hw_param_interval(params, var)); 1255 changed = snd_interval_refine_first(hw_param_interval(params, var));
1408 else { 1256 else
1409 assert(0);
1410 return -EINVAL; 1257 return -EINVAL;
1411 }
1412 if (changed) { 1258 if (changed) {
1413 params->cmask |= 1 << var; 1259 params->cmask |= 1 << var;
1414 params->rmask |= 1 << var; 1260 params->rmask |= 1 << var;
@@ -1428,20 +1274,22 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1428 * values > minimum. Reduce configuration space accordingly. 1274 * values > minimum. Reduce configuration space accordingly.
1429 * Return the minimum. 1275 * Return the minimum.
1430 */ 1276 */
1431static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 1277int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
1432 struct snd_pcm_hw_params *params, 1278 struct snd_pcm_hw_params *params,
1433 snd_pcm_hw_param_t var, int *dir) 1279 snd_pcm_hw_param_t var, int *dir)
1434{ 1280{
1435 int changed = _snd_pcm_hw_param_first(params, var); 1281 int changed = _snd_pcm_hw_param_first(params, var);
1436 if (changed < 0) 1282 if (changed < 0)
1437 return changed; 1283 return changed;
1438 if (params->rmask) { 1284 if (params->rmask) {
1439 int err = snd_pcm_hw_refine(pcm, params); 1285 int err = snd_pcm_hw_refine(pcm, params);
1440 assert(err >= 0); 1286 snd_assert(err >= 0, return err);
1441 } 1287 }
1442 return snd_pcm_hw_param_value(params, var, dir); 1288 return snd_pcm_hw_param_value(params, var, dir);
1443} 1289}
1444 1290
1291EXPORT_SYMBOL(snd_pcm_hw_param_first);
1292
1445static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, 1293static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1446 snd_pcm_hw_param_t var) 1294 snd_pcm_hw_param_t var)
1447{ 1295{
@@ -1450,10 +1298,8 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1450 changed = snd_mask_refine_last(hw_param_mask(params, var)); 1298 changed = snd_mask_refine_last(hw_param_mask(params, var));
1451 else if (hw_is_interval(var)) 1299 else if (hw_is_interval(var))
1452 changed = snd_interval_refine_last(hw_param_interval(params, var)); 1300 changed = snd_interval_refine_last(hw_param_interval(params, var));
1453 else { 1301 else
1454 assert(0);
1455 return -EINVAL; 1302 return -EINVAL;
1456 }
1457 if (changed) { 1303 if (changed) {
1458 params->cmask |= 1 << var; 1304 params->cmask |= 1 << var;
1459 params->rmask |= 1 << var; 1305 params->rmask |= 1 << var;
@@ -1473,381 +1319,21 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1473 * values < maximum. Reduce configuration space accordingly. 1319 * values < maximum. Reduce configuration space accordingly.
1474 * Return the maximum. 1320 * Return the maximum.
1475 */ 1321 */
1476static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 1322int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1477 struct snd_pcm_hw_params *params, 1323 struct snd_pcm_hw_params *params,
1478 snd_pcm_hw_param_t var, int *dir) 1324 snd_pcm_hw_param_t var, int *dir)
1479{ 1325{
1480 int changed = _snd_pcm_hw_param_last(params, var); 1326 int changed = _snd_pcm_hw_param_last(params, var);
1481 if (changed < 0) 1327 if (changed < 0)
1482 return changed; 1328 return changed;
1483 if (params->rmask) { 1329 if (params->rmask) {
1484 int err = snd_pcm_hw_refine(pcm, params); 1330 int err = snd_pcm_hw_refine(pcm, params);
1485 assert(err >= 0); 1331 snd_assert(err >= 0, return err);
1486 } 1332 }
1487 return snd_pcm_hw_param_value(params, var, dir); 1333 return snd_pcm_hw_param_value(params, var, dir);
1488} 1334}
1489 1335
1490int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 1336EXPORT_SYMBOL(snd_pcm_hw_param_last);
1491 snd_pcm_hw_param_t var, unsigned int val, int dir)
1492{
1493 int changed;
1494 int open = 0;
1495 if (dir) {
1496 if (dir > 0) {
1497 open = 1;
1498 } else if (dir < 0) {
1499 if (val > 0) {
1500 open = 1;
1501 val--;
1502 }
1503 }
1504 }
1505 if (hw_is_mask(var))
1506 changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open);
1507 else if (hw_is_interval(var))
1508 changed = snd_interval_refine_min(hw_param_interval(params, var), val, open);
1509 else {
1510 assert(0);
1511 return -EINVAL;
1512 }
1513 if (changed) {
1514 params->cmask |= 1 << var;
1515 params->rmask |= 1 << var;
1516 }
1517 return changed;
1518}
1519
1520/**
1521 * snd_pcm_hw_param_min
1522 * @pcm: PCM instance
1523 * @params: the hw_params instance
1524 * @var: parameter to retrieve
1525 * @val: minimal value
1526 * @dir: pointer to the direction (-1,0,1) or NULL
1527 *
1528 * Inside configuration space defined by PARAMS remove from PAR all
1529 * values < VAL. Reduce configuration space accordingly.
1530 * Return new minimum or -EINVAL if the configuration space is empty
1531 */
1532static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1533 snd_pcm_hw_param_t var, unsigned int val,
1534 int *dir)
1535{
1536 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
1537 if (changed < 0)
1538 return changed;
1539 if (params->rmask) {
1540 int err = snd_pcm_hw_refine(pcm, params);
1541 if (err < 0)
1542 return err;
1543 }
1544 return snd_pcm_hw_param_value_min(params, var, dir);
1545}
1546
1547static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
1548 snd_pcm_hw_param_t var, unsigned int val,
1549 int dir)
1550{
1551 int changed;
1552 int open = 0;
1553 if (dir) {
1554 if (dir < 0) {
1555 open = 1;
1556 } else if (dir > 0) {
1557 open = 1;
1558 val++;
1559 }
1560 }
1561 if (hw_is_mask(var)) {
1562 if (val == 0 && open) {
1563 snd_mask_none(hw_param_mask(params, var));
1564 changed = -EINVAL;
1565 } else
1566 changed = snd_mask_refine_max(hw_param_mask(params, var), val - !!open);
1567 } else if (hw_is_interval(var))
1568 changed = snd_interval_refine_max(hw_param_interval(params, var), val, open);
1569 else {
1570 assert(0);
1571 return -EINVAL;
1572 }
1573 if (changed) {
1574 params->cmask |= 1 << var;
1575 params->rmask |= 1 << var;
1576 }
1577 return changed;
1578}
1579
1580/**
1581 * snd_pcm_hw_param_max
1582 * @pcm: PCM instance
1583 * @params: the hw_params instance
1584 * @var: parameter to retrieve
1585 * @val: maximal value
1586 * @dir: pointer to the direction (-1,0,1) or NULL
1587 *
1588 * Inside configuration space defined by PARAMS remove from PAR all
1589 * values >= VAL + 1. Reduce configuration space accordingly.
1590 * Return new maximum or -EINVAL if the configuration space is empty
1591 */
1592static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1593 snd_pcm_hw_param_t var, unsigned int val,
1594 int *dir)
1595{
1596 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
1597 if (changed < 0)
1598 return changed;
1599 if (params->rmask) {
1600 int err = snd_pcm_hw_refine(pcm, params);
1601 if (err < 0)
1602 return err;
1603 }
1604 return snd_pcm_hw_param_value_max(params, var, dir);
1605}
1606
1607int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
1608 snd_pcm_hw_param_t var, unsigned int val, int dir)
1609{
1610 int changed;
1611 if (hw_is_mask(var)) {
1612 struct snd_mask *m = hw_param_mask(params, var);
1613 if (val == 0 && dir < 0) {
1614 changed = -EINVAL;
1615 snd_mask_none(m);
1616 } else {
1617 if (dir > 0)
1618 val++;
1619 else if (dir < 0)
1620 val--;
1621 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
1622 }
1623 } else if (hw_is_interval(var)) {
1624 struct snd_interval *i = hw_param_interval(params, var);
1625 if (val == 0 && dir < 0) {
1626 changed = -EINVAL;
1627 snd_interval_none(i);
1628 } else if (dir == 0)
1629 changed = snd_interval_refine_set(i, val);
1630 else {
1631 struct snd_interval t;
1632 t.openmin = 1;
1633 t.openmax = 1;
1634 t.empty = 0;
1635 t.integer = 0;
1636 if (dir < 0) {
1637 t.min = val - 1;
1638 t.max = val;
1639 } else {
1640 t.min = val;
1641 t.max = val+1;
1642 }
1643 changed = snd_interval_refine(i, &t);
1644 }
1645 } else {
1646 assert(0);
1647 return -EINVAL;
1648 }
1649 if (changed) {
1650 params->cmask |= 1 << var;
1651 params->rmask |= 1 << var;
1652 }
1653 return changed;
1654}
1655
1656/**
1657 * snd_pcm_hw_param_set
1658 * @pcm: PCM instance
1659 * @params: the hw_params instance
1660 * @var: parameter to retrieve
1661 * @val: value to set
1662 * @dir: pointer to the direction (-1,0,1) or NULL
1663 *
1664 * Inside configuration space defined by PARAMS remove from PAR all
1665 * values != VAL. Reduce configuration space accordingly.
1666 * Return VAL or -EINVAL if the configuration space is empty
1667 */
1668int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1669 snd_pcm_hw_param_t var, unsigned int val, int dir)
1670{
1671 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
1672 if (changed < 0)
1673 return changed;
1674 if (params->rmask) {
1675 int err = snd_pcm_hw_refine(pcm, params);
1676 if (err < 0)
1677 return err;
1678 }
1679 return snd_pcm_hw_param_value(params, var, NULL);
1680}
1681
1682static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
1683 snd_pcm_hw_param_t var, const struct snd_mask *val)
1684{
1685 int changed;
1686 assert(hw_is_mask(var));
1687 changed = snd_mask_refine(hw_param_mask(params, var), val);
1688 if (changed) {
1689 params->cmask |= 1 << var;
1690 params->rmask |= 1 << var;
1691 }
1692 return changed;
1693}
1694
1695/**
1696 * snd_pcm_hw_param_mask
1697 * @pcm: PCM instance
1698 * @params: the hw_params instance
1699 * @var: parameter to retrieve
1700 * @val: mask to apply
1701 *
1702 * Inside configuration space defined by PARAMS remove from PAR all values
1703 * not contained in MASK. Reduce configuration space accordingly.
1704 * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS,
1705 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1706 * Return 0 on success or -EINVAL
1707 * if the configuration space is empty
1708 */
1709int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1710 snd_pcm_hw_param_t var, const struct snd_mask *val)
1711{
1712 int changed = _snd_pcm_hw_param_mask(params, var, val);
1713 if (changed < 0)
1714 return changed;
1715 if (params->rmask) {
1716 int err = snd_pcm_hw_refine(pcm, params);
1717 if (err < 0)
1718 return err;
1719 }
1720 return 0;
1721}
1722
1723static int boundary_sub(int a, int adir,
1724 int b, int bdir,
1725 int *c, int *cdir)
1726{
1727 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
1728 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
1729 *c = a - b;
1730 *cdir = adir - bdir;
1731 if (*cdir == -2) {
1732 assert(*c > INT_MIN);
1733 (*c)--;
1734 } else if (*cdir == 2) {
1735 assert(*c < INT_MAX);
1736 (*c)++;
1737 }
1738 return 0;
1739}
1740
1741static int boundary_lt(unsigned int a, int adir,
1742 unsigned int b, int bdir)
1743{
1744 assert(a > 0 || adir >= 0);
1745 assert(b > 0 || bdir >= 0);
1746 if (adir < 0) {
1747 a--;
1748 adir = 1;
1749 } else if (adir > 0)
1750 adir = 1;
1751 if (bdir < 0) {
1752 b--;
1753 bdir = 1;
1754 } else if (bdir > 0)
1755 bdir = 1;
1756 return a < b || (a == b && adir < bdir);
1757}
1758
1759/* Return 1 if min is nearer to best than max */
1760static int boundary_nearer(int min, int mindir,
1761 int best, int bestdir,
1762 int max, int maxdir)
1763{
1764 int dmin, dmindir;
1765 int dmax, dmaxdir;
1766 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
1767 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
1768 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
1769}
1770
1771/**
1772 * snd_pcm_hw_param_near
1773 * @pcm: PCM instance
1774 * @params: the hw_params instance
1775 * @var: parameter to retrieve
1776 * @best: value to set
1777 * @dir: pointer to the direction (-1,0,1) or NULL
1778 *
1779 * Inside configuration space defined by PARAMS set PAR to the available value
1780 * nearest to VAL. Reduce configuration space accordingly.
1781 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
1782 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1783 * Return the value found.
1784 */
1785int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1786 snd_pcm_hw_param_t var, unsigned int best, int *dir)
1787{
1788 struct snd_pcm_hw_params *save = NULL;
1789 int v;
1790 unsigned int saved_min;
1791 int last = 0;
1792 int min, max;
1793 int mindir, maxdir;
1794 int valdir = dir ? *dir : 0;
1795 /* FIXME */
1796 if (best > INT_MAX)
1797 best = INT_MAX;
1798 min = max = best;
1799 mindir = maxdir = valdir;
1800 if (maxdir > 0)
1801 maxdir = 0;
1802 else if (maxdir == 0)
1803 maxdir = -1;
1804 else {
1805 maxdir = 1;
1806 max--;
1807 }
1808 save = kmalloc(sizeof(*save), GFP_KERNEL);
1809 if (save == NULL)
1810 return -ENOMEM;
1811 *save = *params;
1812 saved_min = min;
1813 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
1814 if (min >= 0) {
1815 struct snd_pcm_hw_params *params1;
1816 if (max < 0)
1817 goto _end;
1818 if ((unsigned int)min == saved_min && mindir == valdir)
1819 goto _end;
1820 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
1821 if (params1 == NULL) {
1822 kfree(save);
1823 return -ENOMEM;
1824 }
1825 *params1 = *save;
1826 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
1827 if (max < 0) {
1828 kfree(params1);
1829 goto _end;
1830 }
1831 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
1832 *params = *params1;
1833 last = 1;
1834 }
1835 kfree(params1);
1836 } else {
1837 *params = *save;
1838 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
1839 assert(max >= 0);
1840 last = 1;
1841 }
1842 _end:
1843 kfree(save);
1844 if (last)
1845 v = snd_pcm_hw_param_last(pcm, params, var, dir);
1846 else
1847 v = snd_pcm_hw_param_first(pcm, params, var, dir);
1848 assert(v >= 0);
1849 return v;
1850}
1851 1337
1852/** 1338/**
1853 * snd_pcm_hw_param_choose 1339 * snd_pcm_hw_param_choose
@@ -1859,39 +1345,32 @@ int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1859 * first access, first format, first subformat, min channels, 1345 * first access, first format, first subformat, min channels,
1860 * min rate, min period time, max buffer size, min tick time 1346 * min rate, min period time, max buffer size, min tick time
1861 */ 1347 */
1862int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params) 1348int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
1863{ 1349 struct snd_pcm_hw_params *params)
1864 int err; 1350{
1865 1351 static int vars[] = {
1866 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_ACCESS, NULL); 1352 SNDRV_PCM_HW_PARAM_ACCESS,
1867 assert(err >= 0); 1353 SNDRV_PCM_HW_PARAM_FORMAT,
1868 1354 SNDRV_PCM_HW_PARAM_SUBFORMAT,
1869 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_FORMAT, NULL); 1355 SNDRV_PCM_HW_PARAM_CHANNELS,
1870 assert(err >= 0); 1356 SNDRV_PCM_HW_PARAM_RATE,
1871 1357 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1872 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_SUBFORMAT, NULL); 1358 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
1873 assert(err >= 0); 1359 SNDRV_PCM_HW_PARAM_TICK_TIME,
1874 1360 -1
1875 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_CHANNELS, NULL); 1361 };
1876 assert(err >= 0); 1362 int err, *v;
1877
1878 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_RATE, NULL);
1879 assert(err >= 0);
1880
1881 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, NULL);
1882 assert(err >= 0);
1883
1884 err = snd_pcm_hw_param_last(pcm, params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL);
1885 assert(err >= 0);
1886
1887 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_TICK_TIME, NULL);
1888 assert(err >= 0);
1889 1363
1364 for (v = vars; *v != -1; v++) {
1365 if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE)
1366 err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
1367 else
1368 err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
1369 snd_assert(err >= 0, return err);
1370 }
1890 return 0; 1371 return 0;
1891} 1372}
1892 1373
1893#undef assert
1894
1895static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, 1374static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
1896 void *arg) 1375 void *arg)
1897{ 1376{
@@ -1967,6 +1446,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1967 return -ENXIO; 1446 return -ENXIO;
1968} 1447}
1969 1448
1449EXPORT_SYMBOL(snd_pcm_lib_ioctl);
1450
1970/* 1451/*
1971 * Conditions 1452 * Conditions
1972 */ 1453 */
@@ -2101,6 +1582,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
2101 kill_fasync(&runtime->fasync, SIGIO, POLL_IN); 1582 kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
2102} 1583}
2103 1584
1585EXPORT_SYMBOL(snd_pcm_period_elapsed);
1586
2104static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, 1587static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
2105 unsigned int hwoff, 1588 unsigned int hwoff,
2106 unsigned long data, unsigned int off, 1589 unsigned long data, unsigned int off,
@@ -2299,7 +1782,7 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2299 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1782 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2300 return -EBADFD; 1783 return -EBADFD;
2301 1784
2302 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1785 nonblock = !!(substream->f_flags & O_NONBLOCK);
2303 1786
2304 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 1787 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
2305 runtime->channels > 1) 1788 runtime->channels > 1)
@@ -2308,6 +1791,8 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2308 snd_pcm_lib_write_transfer); 1791 snd_pcm_lib_write_transfer);
2309} 1792}
2310 1793
1794EXPORT_SYMBOL(snd_pcm_lib_write);
1795
2311static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, 1796static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
2312 unsigned int hwoff, 1797 unsigned int hwoff,
2313 unsigned long data, unsigned int off, 1798 unsigned long data, unsigned int off,
@@ -2362,7 +1847,7 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2362 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1847 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2363 return -EBADFD; 1848 return -EBADFD;
2364 1849
2365 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1850 nonblock = !!(substream->f_flags & O_NONBLOCK);
2366 1851
2367 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 1852 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2368 return -EINVAL; 1853 return -EINVAL;
@@ -2370,6 +1855,8 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2370 nonblock, snd_pcm_lib_writev_transfer); 1855 nonblock, snd_pcm_lib_writev_transfer);
2371} 1856}
2372 1857
1858EXPORT_SYMBOL(snd_pcm_lib_writev);
1859
2373static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, 1860static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
2374 unsigned int hwoff, 1861 unsigned int hwoff,
2375 unsigned long data, unsigned int off, 1862 unsigned long data, unsigned int off,
@@ -2572,12 +2059,14 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
2572 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2059 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2573 return -EBADFD; 2060 return -EBADFD;
2574 2061
2575 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2062 nonblock = !!(substream->f_flags & O_NONBLOCK);
2576 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 2063 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
2577 return -EINVAL; 2064 return -EINVAL;
2578 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2065 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
2579} 2066}
2580 2067
2068EXPORT_SYMBOL(snd_pcm_lib_read);
2069
2581static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, 2070static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
2582 unsigned int hwoff, 2071 unsigned int hwoff,
2583 unsigned long data, unsigned int off, 2072 unsigned long data, unsigned int off,
@@ -2629,58 +2118,10 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
2629 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2118 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2630 return -EBADFD; 2119 return -EBADFD;
2631 2120
2632 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2121 nonblock = !!(substream->f_flags & O_NONBLOCK);
2633 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2122 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2634 return -EINVAL; 2123 return -EINVAL;
2635 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2124 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
2636} 2125}
2637 2126
2638/*
2639 * Exported symbols
2640 */
2641
2642EXPORT_SYMBOL(snd_interval_refine);
2643EXPORT_SYMBOL(snd_interval_list);
2644EXPORT_SYMBOL(snd_interval_ratnum);
2645EXPORT_SYMBOL(_snd_pcm_hw_params_any);
2646EXPORT_SYMBOL(_snd_pcm_hw_param_min);
2647EXPORT_SYMBOL(_snd_pcm_hw_param_set);
2648EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
2649EXPORT_SYMBOL(_snd_pcm_hw_param_setinteger);
2650EXPORT_SYMBOL(snd_pcm_hw_param_value_min);
2651EXPORT_SYMBOL(snd_pcm_hw_param_value_max);
2652EXPORT_SYMBOL(snd_pcm_hw_param_mask);
2653EXPORT_SYMBOL(snd_pcm_hw_param_first);
2654EXPORT_SYMBOL(snd_pcm_hw_param_last);
2655EXPORT_SYMBOL(snd_pcm_hw_param_near);
2656EXPORT_SYMBOL(snd_pcm_hw_param_set);
2657EXPORT_SYMBOL(snd_pcm_hw_refine);
2658EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
2659EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
2660EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
2661EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
2662EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
2663EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
2664EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
2665EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
2666EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
2667EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
2668EXPORT_SYMBOL(snd_pcm_hw_rule_add);
2669EXPORT_SYMBOL(snd_pcm_set_ops);
2670EXPORT_SYMBOL(snd_pcm_set_sync);
2671EXPORT_SYMBOL(snd_pcm_lib_ioctl);
2672EXPORT_SYMBOL(snd_pcm_stop);
2673EXPORT_SYMBOL(snd_pcm_period_elapsed);
2674EXPORT_SYMBOL(snd_pcm_lib_write);
2675EXPORT_SYMBOL(snd_pcm_lib_read);
2676EXPORT_SYMBOL(snd_pcm_lib_writev);
2677EXPORT_SYMBOL(snd_pcm_lib_readv); 2127EXPORT_SYMBOL(snd_pcm_lib_readv);
2678EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes);
2679EXPORT_SYMBOL(snd_pcm_lib_period_bytes);
2680/* pcm_memory.c */
2681EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
2682EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
2683EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
2684EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
2685EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
2686EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 428f8c169ee1..067d2056db9a 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -126,6 +126,8 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
126 return 0; 126 return 0;
127} 127}
128 128
129EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
130
129#ifdef CONFIG_SND_VERBOSE_PROCFS 131#ifdef CONFIG_SND_VERBOSE_PROCFS
130/* 132/*
131 * read callback for prealloc proc file 133 * read callback for prealloc proc file
@@ -191,9 +193,7 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
191 struct snd_info_entry *entry; 193 struct snd_info_entry *entry;
192 194
193 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { 195 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
194 entry->c.text.read_size = 64;
195 entry->c.text.read = snd_pcm_lib_preallocate_proc_read; 196 entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
196 entry->c.text.write_size = 64;
197 entry->c.text.write = snd_pcm_lib_preallocate_proc_write; 197 entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
198 entry->mode |= S_IWUSR; 198 entry->mode |= S_IWUSR;
199 entry->private_data = substream; 199 entry->private_data = substream;
@@ -253,6 +253,8 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
253 return snd_pcm_lib_preallocate_pages1(substream, size, max); 253 return snd_pcm_lib_preallocate_pages1(substream, size, max);
254} 254}
255 255
256EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
257
256/** 258/**
257 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) 259 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
258 * @pcm: the pcm instance 260 * @pcm: the pcm instance
@@ -280,6 +282,8 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
280 return 0; 282 return 0;
281} 283}
282 284
285EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
286
283/** 287/**
284 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 288 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
285 * @substream: the pcm substream instance 289 * @substream: the pcm substream instance
@@ -298,6 +302,8 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
298 return sgbuf->page_table[idx]; 302 return sgbuf->page_table[idx];
299} 303}
300 304
305EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
306
301/** 307/**
302 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 308 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
303 * @substream: the substream to allocate the DMA buffer to 309 * @substream: the substream to allocate the DMA buffer to
@@ -349,6 +355,8 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
349 return 1; /* area was changed */ 355 return 1; /* area was changed */
350} 356}
351 357
358EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
359
352/** 360/**
353 * snd_pcm_lib_free_pages - release the allocated DMA buffer. 361 * snd_pcm_lib_free_pages - release the allocated DMA buffer.
354 * @substream: the substream to release the DMA buffer 362 * @substream: the substream to release the DMA buffer
@@ -374,3 +382,5 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
374 snd_pcm_set_runtime_buffer(substream, NULL); 382 snd_pcm_set_runtime_buffer(substream, NULL);
375 return 0; 383 return 0;
376} 384}
385
386EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 593c77f4d181..0019c59a779d 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -207,6 +207,8 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
207 return val; 207 return val;
208} 208}
209 209
210EXPORT_SYMBOL(snd_pcm_format_signed);
211
210/** 212/**
211 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear 213 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
212 * @format: the format to check 214 * @format: the format to check
@@ -224,6 +226,8 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format)
224 return !val; 226 return !val;
225} 227}
226 228
229EXPORT_SYMBOL(snd_pcm_format_unsigned);
230
227/** 231/**
228 * snd_pcm_format_linear - Check the PCM format is linear 232 * snd_pcm_format_linear - Check the PCM format is linear
229 * @format: the format to check 233 * @format: the format to check
@@ -235,6 +239,8 @@ int snd_pcm_format_linear(snd_pcm_format_t format)
235 return snd_pcm_format_signed(format) >= 0; 239 return snd_pcm_format_signed(format) >= 0;
236} 240}
237 241
242EXPORT_SYMBOL(snd_pcm_format_linear);
243
238/** 244/**
239 * snd_pcm_format_little_endian - Check the PCM format is little-endian 245 * snd_pcm_format_little_endian - Check the PCM format is little-endian
240 * @format: the format to check 246 * @format: the format to check
@@ -252,6 +258,8 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
252 return val; 258 return val;
253} 259}
254 260
261EXPORT_SYMBOL(snd_pcm_format_little_endian);
262
255/** 263/**
256 * snd_pcm_format_big_endian - Check the PCM format is big-endian 264 * snd_pcm_format_big_endian - Check the PCM format is big-endian
257 * @format: the format to check 265 * @format: the format to check
@@ -269,6 +277,8 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format)
269 return !val; 277 return !val;
270} 278}
271 279
280EXPORT_SYMBOL(snd_pcm_format_big_endian);
281
272/** 282/**
273 * snd_pcm_format_width - return the bit-width of the format 283 * snd_pcm_format_width - return the bit-width of the format
274 * @format: the format to check 284 * @format: the format to check
@@ -286,6 +296,8 @@ int snd_pcm_format_width(snd_pcm_format_t format)
286 return val; 296 return val;
287} 297}
288 298
299EXPORT_SYMBOL(snd_pcm_format_width);
300
289/** 301/**
290 * snd_pcm_format_physical_width - return the physical bit-width of the format 302 * snd_pcm_format_physical_width - return the physical bit-width of the format
291 * @format: the format to check 303 * @format: the format to check
@@ -303,6 +315,8 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
303 return val; 315 return val;
304} 316}
305 317
318EXPORT_SYMBOL(snd_pcm_format_physical_width);
319
306/** 320/**
307 * snd_pcm_format_size - return the byte size of samples on the given format 321 * snd_pcm_format_size - return the byte size of samples on the given format
308 * @format: the format to check 322 * @format: the format to check
@@ -318,6 +332,8 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
318 return samples * phys_width / 8; 332 return samples * phys_width / 8;
319} 333}
320 334
335EXPORT_SYMBOL(snd_pcm_format_size);
336
321/** 337/**
322 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array 338 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
323 * @format: the format to check 339 * @format: the format to check
@@ -333,6 +349,8 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
333 return pcm_formats[format].silence; 349 return pcm_formats[format].silence;
334} 350}
335 351
352EXPORT_SYMBOL(snd_pcm_format_silence_64);
353
336/** 354/**
337 * snd_pcm_format_set_silence - set the silence data on the buffer 355 * snd_pcm_format_set_silence - set the silence data on the buffer
338 * @format: the PCM format 356 * @format: the PCM format
@@ -402,6 +420,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
402 return 0; 420 return 0;
403} 421}
404 422
423EXPORT_SYMBOL(snd_pcm_format_set_silence);
424
405/* [width][unsigned][bigendian] */ 425/* [width][unsigned][bigendian] */
406static int linear_formats[4][2][2] = { 426static int linear_formats[4][2][2] = {
407 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, 427 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8},
@@ -432,6 +452,8 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_end
432 return linear_formats[width][!!unsignd][!!big_endian]; 452 return linear_formats[width][!!unsignd][!!big_endian];
433} 453}
434 454
455EXPORT_SYMBOL(snd_pcm_build_linear_format);
456
435/** 457/**
436 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields 458 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
437 * @runtime: the runtime instance 459 * @runtime: the runtime instance
@@ -463,3 +485,5 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
463 } 485 }
464 return 0; 486 return 0;
465} 487}
488
489EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 0860c5a84502..439f047929e1 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -71,8 +71,9 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
71 */ 71 */
72 72
73DEFINE_RWLOCK(snd_pcm_link_rwlock); 73DEFINE_RWLOCK(snd_pcm_link_rwlock);
74static DECLARE_RWSEM(snd_pcm_link_rwsem); 74EXPORT_SYMBOL(snd_pcm_link_rwlock);
75 75
76static DECLARE_RWSEM(snd_pcm_link_rwsem);
76 77
77static inline mm_segment_t snd_enter_user(void) 78static inline mm_segment_t snd_enter_user(void)
78{ 79{
@@ -319,6 +320,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
319 return 0; 320 return 0;
320} 321}
321 322
323EXPORT_SYMBOL(snd_pcm_hw_refine);
324
322static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, 325static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_params __user * _params) 326 struct snd_pcm_hw_params __user * _params)
324{ 327{
@@ -369,7 +372,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
369#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 372#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
370 if (!substream->oss.oss) 373 if (!substream->oss.oss)
371#endif 374#endif
372 if (atomic_read(&runtime->mmap_count)) 375 if (atomic_read(&substream->mmap_count))
373 return -EBADFD; 376 return -EBADFD;
374 377
375 params->rmask = ~0U; 378 params->rmask = ~0U;
@@ -482,7 +485,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
482 return -EBADFD; 485 return -EBADFD;
483 } 486 }
484 snd_pcm_stream_unlock_irq(substream); 487 snd_pcm_stream_unlock_irq(substream);
485 if (atomic_read(&runtime->mmap_count)) 488 if (atomic_read(&substream->mmap_count))
486 return -EBADFD; 489 return -EBADFD;
487 if (substream->ops->hw_free) 490 if (substream->ops->hw_free)
488 result = substream->ops->hw_free(substream); 491 result = substream->ops->hw_free(substream);
@@ -936,6 +939,8 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
936 return snd_pcm_action(&snd_pcm_action_stop, substream, state); 939 return snd_pcm_action(&snd_pcm_action_stop, substream, state);
937} 940}
938 941
942EXPORT_SYMBOL(snd_pcm_stop);
943
939/** 944/**
940 * snd_pcm_drain_done 945 * snd_pcm_drain_done
941 * @substream: the PCM substream 946 * @substream: the PCM substream
@@ -1085,6 +1090,8 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream)
1085 return err; 1090 return err;
1086} 1091}
1087 1092
1093EXPORT_SYMBOL(snd_pcm_suspend);
1094
1088/** 1095/**
1089 * snd_pcm_suspend_all 1096 * snd_pcm_suspend_all
1090 * @pcm: the PCM instance 1097 * @pcm: the PCM instance
@@ -1114,6 +1121,8 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
1114 return 0; 1121 return 0;
1115} 1122}
1116 1123
1124EXPORT_SYMBOL(snd_pcm_suspend_all);
1125
1117/* resume */ 1126/* resume */
1118 1127
1119static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) 1128static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
@@ -1275,13 +1284,16 @@ static int snd_pcm_reset(struct snd_pcm_substream *substream)
1275/* 1284/*
1276 * prepare ioctl 1285 * prepare ioctl
1277 */ 1286 */
1278static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state) 1287/* we use the second argument for updating f_flags */
1288static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1289 int f_flags)
1279{ 1290{
1280 struct snd_pcm_runtime *runtime = substream->runtime; 1291 struct snd_pcm_runtime *runtime = substream->runtime;
1281 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1292 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1282 return -EBADFD; 1293 return -EBADFD;
1283 if (snd_pcm_running(substream)) 1294 if (snd_pcm_running(substream))
1284 return -EBUSY; 1295 return -EBUSY;
1296 substream->f_flags = f_flags;
1285 return 0; 1297 return 0;
1286} 1298}
1287 1299
@@ -1310,17 +1322,26 @@ static struct action_ops snd_pcm_action_prepare = {
1310/** 1322/**
1311 * snd_pcm_prepare 1323 * snd_pcm_prepare
1312 * @substream: the PCM substream instance 1324 * @substream: the PCM substream instance
1325 * @file: file to refer f_flags
1313 * 1326 *
1314 * Prepare the PCM substream to be triggerable. 1327 * Prepare the PCM substream to be triggerable.
1315 */ 1328 */
1316static int snd_pcm_prepare(struct snd_pcm_substream *substream) 1329static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1330 struct file *file)
1317{ 1331{
1318 int res; 1332 int res;
1319 struct snd_card *card = substream->pcm->card; 1333 struct snd_card *card = substream->pcm->card;
1334 int f_flags;
1335
1336 if (file)
1337 f_flags = file->f_flags;
1338 else
1339 f_flags = substream->f_flags;
1320 1340
1321 snd_power_lock(card); 1341 snd_power_lock(card);
1322 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) 1342 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1323 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); 1343 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1344 substream, f_flags);
1324 snd_power_unlock(card); 1345 snd_power_unlock(card);
1325 return res; 1346 return res;
1326} 1347}
@@ -1331,7 +1352,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream)
1331 1352
1332static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) 1353static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1333{ 1354{
1334 if (substream->ffile->f_flags & O_NONBLOCK) 1355 if (substream->f_flags & O_NONBLOCK)
1335 return -EAGAIN; 1356 return -EAGAIN;
1336 substream->runtime->trigger_master = substream; 1357 substream->runtime->trigger_master = substream;
1337 return 0; 1358 return 0;
@@ -1448,8 +1469,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1448 } 1469 }
1449 } 1470 }
1450 up_read(&snd_pcm_link_rwsem); 1471 up_read(&snd_pcm_link_rwsem);
1451 if (! num_drecs)
1452 goto _error;
1453 1472
1454 snd_pcm_stream_lock_irq(substream); 1473 snd_pcm_stream_lock_irq(substream);
1455 /* resume pause */ 1474 /* resume pause */
@@ -2006,6 +2025,10 @@ static void pcm_release_private(struct snd_pcm_substream *substream)
2006 2025
2007void snd_pcm_release_substream(struct snd_pcm_substream *substream) 2026void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2008{ 2027{
2028 substream->ref_count--;
2029 if (substream->ref_count > 0)
2030 return;
2031
2009 snd_pcm_drop(substream); 2032 snd_pcm_drop(substream);
2010 if (substream->hw_opened) { 2033 if (substream->hw_opened) {
2011 if (substream->ops->hw_free != NULL) 2034 if (substream->ops->hw_free != NULL)
@@ -2020,6 +2043,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2020 snd_pcm_detach_substream(substream); 2043 snd_pcm_detach_substream(substream);
2021} 2044}
2022 2045
2046EXPORT_SYMBOL(snd_pcm_release_substream);
2047
2023int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, 2048int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2024 struct file *file, 2049 struct file *file,
2025 struct snd_pcm_substream **rsubstream) 2050 struct snd_pcm_substream **rsubstream)
@@ -2030,6 +2055,11 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2030 err = snd_pcm_attach_substream(pcm, stream, file, &substream); 2055 err = snd_pcm_attach_substream(pcm, stream, file, &substream);
2031 if (err < 0) 2056 if (err < 0)
2032 return err; 2057 return err;
2058 if (substream->ref_count > 1) {
2059 *rsubstream = substream;
2060 return 0;
2061 }
2062
2033 substream->no_mmap_ctrl = 0; 2063 substream->no_mmap_ctrl = 0;
2034 err = snd_pcm_hw_constraints_init(substream); 2064 err = snd_pcm_hw_constraints_init(substream);
2035 if (err < 0) { 2065 if (err < 0) {
@@ -2056,6 +2086,8 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2056 return err; 2086 return err;
2057} 2087}
2058 2088
2089EXPORT_SYMBOL(snd_pcm_open_substream);
2090
2059static int snd_pcm_open_file(struct file *file, 2091static int snd_pcm_open_file(struct file *file,
2060 struct snd_pcm *pcm, 2092 struct snd_pcm *pcm,
2061 int stream, 2093 int stream,
@@ -2073,17 +2105,20 @@ static int snd_pcm_open_file(struct file *file,
2073 if (err < 0) 2105 if (err < 0)
2074 return err; 2106 return err;
2075 2107
2076 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); 2108 if (substream->ref_count > 1)
2077 if (pcm_file == NULL) { 2109 pcm_file = substream->file;
2078 snd_pcm_release_substream(substream); 2110 else {
2079 return -ENOMEM; 2111 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2112 if (pcm_file == NULL) {
2113 snd_pcm_release_substream(substream);
2114 return -ENOMEM;
2115 }
2116 str = substream->pstr;
2117 substream->file = pcm_file;
2118 substream->pcm_release = pcm_release_private;
2119 pcm_file->substream = substream;
2120 snd_pcm_add_file(str, pcm_file);
2080 } 2121 }
2081 str = substream->pstr;
2082 substream->file = pcm_file;
2083 substream->pcm_release = pcm_release_private;
2084 pcm_file->substream = substream;
2085 snd_pcm_add_file(str, pcm_file);
2086
2087 file->private_data = pcm_file; 2122 file->private_data = pcm_file;
2088 *rpcm_file = pcm_file; 2123 *rpcm_file = pcm_file;
2089 return 0; 2124 return 0;
@@ -2170,7 +2205,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2170 pcm_file = file->private_data; 2205 pcm_file = file->private_data;
2171 substream = pcm_file->substream; 2206 substream = pcm_file->substream;
2172 snd_assert(substream != NULL, return -ENXIO); 2207 snd_assert(substream != NULL, return -ENXIO);
2173 snd_assert(!atomic_read(&substream->runtime->mmap_count), );
2174 pcm = substream->pcm; 2208 pcm = substream->pcm;
2175 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2209 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2176 mutex_lock(&pcm->open_mutex); 2210 mutex_lock(&pcm->open_mutex);
@@ -2493,7 +2527,8 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2493 return 0; 2527 return 0;
2494} 2528}
2495 2529
2496static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, 2530static int snd_pcm_common_ioctl1(struct file *file,
2531 struct snd_pcm_substream *substream,
2497 unsigned int cmd, void __user *arg) 2532 unsigned int cmd, void __user *arg)
2498{ 2533{
2499 snd_assert(substream != NULL, return -ENXIO); 2534 snd_assert(substream != NULL, return -ENXIO);
@@ -2518,7 +2553,7 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2518 case SNDRV_PCM_IOCTL_CHANNEL_INFO: 2553 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
2519 return snd_pcm_channel_info_user(substream, arg); 2554 return snd_pcm_channel_info_user(substream, arg);
2520 case SNDRV_PCM_IOCTL_PREPARE: 2555 case SNDRV_PCM_IOCTL_PREPARE:
2521 return snd_pcm_prepare(substream); 2556 return snd_pcm_prepare(substream, file);
2522 case SNDRV_PCM_IOCTL_RESET: 2557 case SNDRV_PCM_IOCTL_RESET:
2523 return snd_pcm_reset(substream); 2558 return snd_pcm_reset(substream);
2524 case SNDRV_PCM_IOCTL_START: 2559 case SNDRV_PCM_IOCTL_START:
@@ -2560,7 +2595,8 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2560 return -ENOTTY; 2595 return -ENOTTY;
2561} 2596}
2562 2597
2563static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, 2598static int snd_pcm_playback_ioctl1(struct file *file,
2599 struct snd_pcm_substream *substream,
2564 unsigned int cmd, void __user *arg) 2600 unsigned int cmd, void __user *arg)
2565{ 2601{
2566 snd_assert(substream != NULL, return -ENXIO); 2602 snd_assert(substream != NULL, return -ENXIO);
@@ -2636,10 +2672,11 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2636 return result < 0 ? result : 0; 2672 return result < 0 ? result : 0;
2637 } 2673 }
2638 } 2674 }
2639 return snd_pcm_common_ioctl1(substream, cmd, arg); 2675 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2640} 2676}
2641 2677
2642static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, 2678static int snd_pcm_capture_ioctl1(struct file *file,
2679 struct snd_pcm_substream *substream,
2643 unsigned int cmd, void __user *arg) 2680 unsigned int cmd, void __user *arg)
2644{ 2681{
2645 snd_assert(substream != NULL, return -ENXIO); 2682 snd_assert(substream != NULL, return -ENXIO);
@@ -2715,7 +2752,7 @@ static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
2715 return result < 0 ? result : 0; 2752 return result < 0 ? result : 0;
2716 } 2753 }
2717 } 2754 }
2718 return snd_pcm_common_ioctl1(substream, cmd, arg); 2755 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2719} 2756}
2720 2757
2721static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, 2758static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
@@ -2728,7 +2765,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
2728 if (((cmd >> 8) & 0xff) != 'A') 2765 if (((cmd >> 8) & 0xff) != 'A')
2729 return -ENOTTY; 2766 return -ENOTTY;
2730 2767
2731 return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2768 return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
2769 (void __user *)arg);
2732} 2770}
2733 2771
2734static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, 2772static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
@@ -2741,7 +2779,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
2741 if (((cmd >> 8) & 0xff) != 'A') 2779 if (((cmd >> 8) & 0xff) != 'A')
2742 return -ENOTTY; 2780 return -ENOTTY;
2743 2781
2744 return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2782 return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
2783 (void __user *)arg);
2745} 2784}
2746 2785
2747int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, 2786int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
@@ -2753,12 +2792,12 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2753 fs = snd_enter_user(); 2792 fs = snd_enter_user();
2754 switch (substream->stream) { 2793 switch (substream->stream) {
2755 case SNDRV_PCM_STREAM_PLAYBACK: 2794 case SNDRV_PCM_STREAM_PLAYBACK:
2756 result = snd_pcm_playback_ioctl1(substream, 2795 result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
2757 cmd, (void __user *)arg); 2796 (void __user *)arg);
2758 break; 2797 break;
2759 case SNDRV_PCM_STREAM_CAPTURE: 2798 case SNDRV_PCM_STREAM_CAPTURE:
2760 result = snd_pcm_capture_ioctl1(substream, 2799 result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
2761 cmd, (void __user *)arg); 2800 (void __user *)arg);
2762 break; 2801 break;
2763 default: 2802 default:
2764 result = -EINVAL; 2803 result = -EINVAL;
@@ -2768,6 +2807,8 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2768 return result; 2807 return result;
2769} 2808}
2770 2809
2810EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
2811
2771static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, 2812static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
2772 loff_t * offset) 2813 loff_t * offset)
2773{ 2814{
@@ -3134,7 +3175,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3134 area->vm_ops = &snd_pcm_vm_ops_data; 3175 area->vm_ops = &snd_pcm_vm_ops_data;
3135 area->vm_private_data = substream; 3176 area->vm_private_data = substream;
3136 area->vm_flags |= VM_RESERVED; 3177 area->vm_flags |= VM_RESERVED;
3137 atomic_inc(&substream->runtime->mmap_count); 3178 atomic_inc(&substream->mmap_count);
3138 return 0; 3179 return 0;
3139} 3180}
3140 3181
@@ -3166,9 +3207,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3166 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, 3207 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
3167 size, area->vm_page_prot)) 3208 size, area->vm_page_prot))
3168 return -EAGAIN; 3209 return -EAGAIN;
3169 atomic_inc(&substream->runtime->mmap_count); 3210 atomic_inc(&substream->mmap_count);
3170 return 0; 3211 return 0;
3171} 3212}
3213
3214EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3172#endif /* SNDRV_PCM_INFO_MMAP */ 3215#endif /* SNDRV_PCM_INFO_MMAP */
3173 3216
3174/* 3217/*
@@ -3212,6 +3255,8 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3212 return snd_pcm_default_mmap(substream, area); 3255 return snd_pcm_default_mmap(substream, area);
3213} 3256}
3214 3257
3258EXPORT_SYMBOL(snd_pcm_mmap_data);
3259
3215static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) 3260static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3216{ 3261{
3217 struct snd_pcm_file * pcm_file; 3262 struct snd_pcm_file * pcm_file;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 87b47c9564f7..8c15c66eb4aa 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -43,7 +43,7 @@ MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
43MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
44 44
45#ifdef CONFIG_SND_OSSEMUL 45#ifdef CONFIG_SND_OSSEMUL
46static int midi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; 46static int midi_map[SNDRV_CARDS];
47static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; 47static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
48module_param_array(midi_map, int, NULL, 0444); 48module_param_array(midi_map, int, NULL, 0444);
49MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device."); 49MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
@@ -1561,7 +1561,6 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1561 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); 1561 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
1562 if (entry) { 1562 if (entry) {
1563 entry->private_data = rmidi; 1563 entry->private_data = rmidi;
1564 entry->c.text.read_size = 1024;
1565 entry->c.text.read = snd_rawmidi_proc_info_read; 1564 entry->c.text.read = snd_rawmidi_proc_info_read;
1566 if (snd_info_register(entry) < 0) { 1565 if (snd_info_register(entry) < 0) {
1567 snd_info_free_entry(entry); 1566 snd_info_free_entry(entry);
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index b9919785180b..e7234135641c 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -291,7 +291,6 @@ register_proc(void)
291 291
292 entry->content = SNDRV_INFO_CONTENT_TEXT; 292 entry->content = SNDRV_INFO_CONTENT_TEXT;
293 entry->private_data = NULL; 293 entry->private_data = NULL;
294 entry->c.text.read_size = 1024;
295 entry->c.text.read = info_read; 294 entry->c.text.read = info_read;
296 if (snd_info_register(entry) < 0) { 295 if (snd_info_register(entry) < 0) {
297 snd_info_free_entry(entry); 296 snd_info_free_entry(entry);
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 20f954bc7aa0..2f0d8773ac6b 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -129,25 +129,3 @@ static void __exit alsa_seq_exit(void)
129 129
130module_init(alsa_seq_init) 130module_init(alsa_seq_init)
131module_exit(alsa_seq_exit) 131module_exit(alsa_seq_exit)
132
133 /* seq_clientmgr.c */
134EXPORT_SYMBOL(snd_seq_create_kernel_client);
135EXPORT_SYMBOL(snd_seq_delete_kernel_client);
136EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
137EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
138EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
139EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
140EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
141EXPORT_SYMBOL(snd_seq_set_queue_tempo);
142 /* seq_memory.c */
143EXPORT_SYMBOL(snd_seq_expand_var_event);
144EXPORT_SYMBOL(snd_seq_dump_var_event);
145 /* seq_ports.c */
146EXPORT_SYMBOL(snd_seq_event_port_attach);
147EXPORT_SYMBOL(snd_seq_event_port_detach);
148 /* seq_lock.c */
149#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
150/*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/
151/*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/
152EXPORT_SYMBOL(snd_use_lock_sync_helper);
153#endif
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index bb15d9ee8842..532a660df51d 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1714,6 +1714,8 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
1714 return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); 1714 return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
1715} 1715}
1716 1716
1717EXPORT_SYMBOL(snd_seq_set_queue_tempo);
1718
1717static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, 1719static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
1718 void __user *arg) 1720 void __user *arg)
1719{ 1721{
@@ -2264,6 +2266,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2264 return client->number; 2266 return client->number;
2265} 2267}
2266 2268
2269EXPORT_SYMBOL(snd_seq_create_kernel_client);
2270
2267/* exported to kernel modules */ 2271/* exported to kernel modules */
2268int snd_seq_delete_kernel_client(int client) 2272int snd_seq_delete_kernel_client(int client)
2269{ 2273{
@@ -2280,6 +2284,7 @@ int snd_seq_delete_kernel_client(int client)
2280 return 0; 2284 return 0;
2281} 2285}
2282 2286
2287EXPORT_SYMBOL(snd_seq_delete_kernel_client);
2283 2288
2284/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue 2289/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue
2285 * and snd_seq_kernel_client_enqueue_blocking 2290 * and snd_seq_kernel_client_enqueue_blocking
@@ -2328,6 +2333,8 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev,
2328 return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); 2333 return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop);
2329} 2334}
2330 2335
2336EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
2337
2331/* 2338/*
2332 * exported, called by kernel clients to enqueue events (with blocking) 2339 * exported, called by kernel clients to enqueue events (with blocking)
2333 * 2340 *
@@ -2340,6 +2347,7 @@ int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev
2340 return kernel_client_enqueue(client, ev, file, 1, atomic, hop); 2347 return kernel_client_enqueue(client, ev, file, 1, atomic, hop);
2341} 2348}
2342 2349
2350EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
2343 2351
2344/* 2352/*
2345 * exported, called by kernel clients to dispatch events directly to other 2353 * exported, called by kernel clients to dispatch events directly to other
@@ -2376,6 +2384,7 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
2376 return result; 2384 return result;
2377} 2385}
2378 2386
2387EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
2379 2388
2380/* 2389/*
2381 * exported, called by kernel clients to perform same functions as with 2390 * exported, called by kernel clients to perform same functions as with
@@ -2396,6 +2405,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
2396 return result; 2405 return result;
2397} 2406}
2398 2407
2408EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
2399 2409
2400/* exported (for OSS emulator) */ 2410/* exported (for OSS emulator) */
2401int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) 2411int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
@@ -2413,6 +2423,8 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table
2413 return 0; 2423 return 0;
2414} 2424}
2415 2425
2426EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
2427
2416/*---------------------------------------------------------------------------*/ 2428/*---------------------------------------------------------------------------*/
2417 2429
2418#ifdef CONFIG_PROC_FS 2430#ifdef CONFIG_PROC_FS
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index d9a3e5a18d6a..d812dc886360 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -80,7 +80,7 @@ static LIST_HEAD(opslist);
80static int num_ops; 80static int num_ops;
81static DEFINE_MUTEX(ops_mutex); 81static DEFINE_MUTEX(ops_mutex);
82#ifdef CONFIG_PROC_FS 82#ifdef CONFIG_PROC_FS
83static struct snd_info_entry *info_entry = NULL; 83static struct snd_info_entry *info_entry;
84#endif 84#endif
85 85
86/* 86/*
@@ -555,7 +555,6 @@ static int __init alsa_seq_device_init(void)
555 if (info_entry == NULL) 555 if (info_entry == NULL)
556 return -ENOMEM; 556 return -ENOMEM;
557 info_entry->content = SNDRV_INFO_CONTENT_TEXT; 557 info_entry->content = SNDRV_INFO_CONTENT_TEXT;
558 info_entry->c.text.read_size = 2048;
559 info_entry->c.text.read = snd_seq_device_info; 558 info_entry->c.text.read = snd_seq_device_info;
560 if (snd_info_register(info_entry) < 0) { 559 if (snd_info_register(info_entry) < 0) {
561 snd_info_free_entry(info_entry); 560 snd_info_free_entry(info_entry);
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index 2a283a59ea4d..e55488d1237c 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL");
66MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); 66MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY));
67 67
68static int ports = 1; 68static int ports = 1;
69static int duplex = 0; 69static int duplex;
70 70
71module_param(ports, int, 0444); 71module_param(ports, int, 0444);
72MODULE_PARM_DESC(ports, "number of ports to be created"); 72MODULE_PARM_DESC(ports, "number of ports to be created");
@@ -171,7 +171,9 @@ create_port(int idx, int type)
171 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 171 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
172 if (duplex) 172 if (duplex)
173 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 173 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
174 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 174 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
175 | SNDRV_SEQ_PORT_TYPE_SOFTWARE
176 | SNDRV_SEQ_PORT_TYPE_PORT;
175 memset(&pcb, 0, sizeof(pcb)); 177 memset(&pcb, 0, sizeof(pcb));
176 pcb.owner = THIS_MODULE; 178 pcb.owner = THIS_MODULE;
177 pcb.unuse = dummy_unuse; 179 pcb.unuse = dummy_unuse;
diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c
index acce21afdaa4..142e9e6882c9 100644
--- a/sound/core/seq/seq_info.c
+++ b/sound/core/seq/seq_info.c
@@ -34,8 +34,8 @@ static struct snd_info_entry *timer_entry;
34 34
35 35
36static struct snd_info_entry * __init 36static struct snd_info_entry * __init
37create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, 37create_info_entry(char *name, void (*read)(struct snd_info_entry *,
38 struct snd_info_buffer *)) 38 struct snd_info_buffer *))
39{ 39{
40 struct snd_info_entry *entry; 40 struct snd_info_entry *entry;
41 41
@@ -43,7 +43,6 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
43 if (entry == NULL) 43 if (entry == NULL)
44 return NULL; 44 return NULL;
45 entry->content = SNDRV_INFO_CONTENT_TEXT; 45 entry->content = SNDRV_INFO_CONTENT_TEXT;
46 entry->c.text.read_size = size;
47 entry->c.text.read = read; 46 entry->c.text.read = read;
48 if (snd_info_register(entry) < 0) { 47 if (snd_info_register(entry) < 0) {
49 snd_info_free_entry(entry); 48 snd_info_free_entry(entry);
@@ -55,11 +54,11 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
55/* create all our /proc entries */ 54/* create all our /proc entries */
56int __init snd_seq_info_init(void) 55int __init snd_seq_info_init(void)
57{ 56{
58 queues_entry = create_info_entry("queues", 512 + (256 * SNDRV_SEQ_MAX_QUEUES), 57 queues_entry = create_info_entry("queues",
59 snd_seq_info_queues_read); 58 snd_seq_info_queues_read);
60 clients_entry = create_info_entry("clients", 512 + (256 * SNDRV_SEQ_MAX_CLIENTS), 59 clients_entry = create_info_entry("clients",
61 snd_seq_info_clients_read); 60 snd_seq_info_clients_read);
62 timer_entry = create_info_entry("timer", 1024, snd_seq_info_timer_read); 61 timer_entry = create_info_entry("timer", snd_seq_info_timer_read);
63 return 0; 62 return 0;
64} 63}
65 64
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index a837a94b2d2a..1a34941d4217 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -44,4 +44,6 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
44 } 44 }
45} 45}
46 46
47EXPORT_SYMBOL(snd_use_lock_sync_helper);
48
47#endif 49#endif
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 40b4f679c80e..4bffe509f719 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -118,6 +118,8 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
118 return 0; 118 return 0;
119} 119}
120 120
121EXPORT_SYMBOL(snd_seq_dump_var_event);
122
121 123
122/* 124/*
123 * exported: 125 * exported:
@@ -167,6 +169,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
167 return err < 0 ? err : newlen; 169 return err < 0 ? err : newlen;
168} 170}
169 171
172EXPORT_SYMBOL(snd_seq_expand_var_event);
170 173
171/* 174/*
172 * release this cell, free extended data if available 175 * release this cell, free extended data if available
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 9caa1372bece..1daa5b069c79 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -278,6 +278,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
278 struct seq_midisynth *msynth, *ms; 278 struct seq_midisynth *msynth, *ms;
279 struct snd_seq_port_info *port; 279 struct snd_seq_port_info *port;
280 struct snd_rawmidi_info *info; 280 struct snd_rawmidi_info *info;
281 struct snd_rawmidi *rmidi = dev->private_data;
281 int newclient = 0; 282 int newclient = 0;
282 unsigned int p, ports; 283 unsigned int p, ports;
283 struct snd_seq_port_callback pcallbacks; 284 struct snd_seq_port_callback pcallbacks;
@@ -320,8 +321,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
320 } 321 }
321 client->seq_client = 322 client->seq_client =
322 snd_seq_create_kernel_client( 323 snd_seq_create_kernel_client(
323 card, 0, "%s", info->name[0] ? 324 card, 0, "%s", card->shortname[0] ?
324 (const char *)info->name : "External MIDI"); 325 (const char *)card->shortname : "External MIDI");
325 if (client->seq_client < 0) { 326 if (client->seq_client < 0) {
326 kfree(client); 327 kfree(client);
327 mutex_unlock(&register_mutex); 328 mutex_unlock(&register_mutex);
@@ -376,7 +377,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
376 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && 377 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
377 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) 378 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX)
378 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 379 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
379 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 380 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
381 | SNDRV_SEQ_PORT_TYPE_HARDWARE
382 | SNDRV_SEQ_PORT_TYPE_PORT;
380 port->midi_channels = 16; 383 port->midi_channels = 16;
381 memset(&pcallbacks, 0, sizeof(pcallbacks)); 384 memset(&pcallbacks, 0, sizeof(pcallbacks));
382 pcallbacks.owner = THIS_MODULE; 385 pcallbacks.owner = THIS_MODULE;
@@ -387,6 +390,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
387 pcallbacks.unuse = midisynth_unuse; 390 pcallbacks.unuse = midisynth_unuse;
388 pcallbacks.event_input = event_process_midi; 391 pcallbacks.event_input = event_process_midi;
389 port->kernel = &pcallbacks; 392 port->kernel = &pcallbacks;
393 if (rmidi->ops && rmidi->ops->get_port_info)
394 rmidi->ops->get_port_info(rmidi, p, port);
390 if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0) 395 if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0)
391 goto __nomem; 396 goto __nomem;
392 ms->seq_client = client->seq_client; 397 ms->seq_client = client->seq_client;
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 41e078c938cd..334579a9f268 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -221,7 +221,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
221{ 221{
222 struct list_head *p, *n; 222 struct list_head *p, *n;
223 223
224 down_write(&grp->list_mutex);
225 list_for_each_safe(p, n, &grp->list_head) { 224 list_for_each_safe(p, n, &grp->list_head) {
226 struct snd_seq_subscribers *subs; 225 struct snd_seq_subscribers *subs;
227 struct snd_seq_client *c; 226 struct snd_seq_client *c;
@@ -259,7 +258,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
259 snd_seq_client_unlock(c); 258 snd_seq_client_unlock(c);
260 } 259 }
261 } 260 }
262 up_write(&grp->list_mutex);
263} 261}
264 262
265/* delete port data */ 263/* delete port data */
@@ -677,6 +675,7 @@ int snd_seq_event_port_attach(int client,
677 return ret; 675 return ret;
678} 676}
679 677
678EXPORT_SYMBOL(snd_seq_event_port_attach);
680 679
681/* 680/*
682 * Detach the driver from a port. 681 * Detach the driver from a port.
@@ -696,3 +695,5 @@ int snd_seq_event_port_detach(int client, int port)
696 695
697 return err; 696 return err;
698} 697}
698
699EXPORT_SYMBOL(snd_seq_event_port_detach);
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index f4edec603b8f..0cfa06c6b81f 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -390,7 +390,9 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev)
390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; 391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
393 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 393 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
394 | SNDRV_SEQ_PORT_TYPE_SOFTWARE
395 | SNDRV_SEQ_PORT_TYPE_PORT;
394 pinfo->midi_channels = 16; 396 pinfo->midi_channels = 16;
395 memset(&pcallbacks, 0, sizeof(pcallbacks)); 397 memset(&pcallbacks, 0, sizeof(pcallbacks));
396 pcallbacks.owner = THIS_MODULE; 398 pcallbacks.owner = THIS_MODULE;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 108e430b5036..cd862728346c 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -39,6 +39,8 @@
39 39
40static int major = CONFIG_SND_MAJOR; 40static int major = CONFIG_SND_MAJOR;
41int snd_major; 41int snd_major;
42EXPORT_SYMBOL(snd_major);
43
42static int cards_limit = 1; 44static int cards_limit = 1;
43static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO; 45static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO;
44 46
@@ -60,6 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
60 * modules are loaded manually, this limit number increases, too. 62 * modules are loaded manually, this limit number increases, too.
61 */ 63 */
62int snd_ecards_limit; 64int snd_ecards_limit;
65EXPORT_SYMBOL(snd_ecards_limit);
63 66
64static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; 67static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
65static DEFINE_MUTEX(sound_mutex); 68static DEFINE_MUTEX(sound_mutex);
@@ -78,20 +81,17 @@ extern struct class *sound_class;
78 */ 81 */
79void snd_request_card(int card) 82void snd_request_card(int card)
80{ 83{
81 int locked;
82
83 if (! current->fs->root) 84 if (! current->fs->root)
84 return; 85 return;
85 read_lock(&snd_card_rwlock); 86 if (snd_card_locked(card))
86 locked = snd_cards_lock & (1 << card);
87 read_unlock(&snd_card_rwlock);
88 if (locked)
89 return; 87 return;
90 if (card < 0 || card >= cards_limit) 88 if (card < 0 || card >= cards_limit)
91 return; 89 return;
92 request_module("snd-card-%i", card); 90 request_module("snd-card-%i", card);
93} 91}
94 92
93EXPORT_SYMBOL(snd_request_card);
94
95static void snd_request_other(int minor) 95static void snd_request_other(int minor)
96{ 96{
97 char *str; 97 char *str;
@@ -133,6 +133,8 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
133 return private_data; 133 return private_data;
134} 134}
135 135
136EXPORT_SYMBOL(snd_lookup_minor_data);
137
136static int snd_open(struct inode *inode, struct file *file) 138static int snd_open(struct inode *inode, struct file *file)
137{ 139{
138 unsigned int minor = iminor(inode); 140 unsigned int minor = iminor(inode);
@@ -281,6 +283,8 @@ int snd_register_device(int type, struct snd_card *card, int dev,
281 return 0; 283 return 0;
282} 284}
283 285
286EXPORT_SYMBOL(snd_register_device);
287
284/** 288/**
285 * snd_unregister_device - unregister the device on the given card 289 * snd_unregister_device - unregister the device on the given card
286 * @type: the device type, SNDRV_DEVICE_TYPE_XXX 290 * @type: the device type, SNDRV_DEVICE_TYPE_XXX
@@ -321,12 +325,14 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
321 return 0; 325 return 0;
322} 326}
323 327
328EXPORT_SYMBOL(snd_unregister_device);
329
324#ifdef CONFIG_PROC_FS 330#ifdef CONFIG_PROC_FS
325/* 331/*
326 * INFO PART 332 * INFO PART
327 */ 333 */
328 334
329static struct snd_info_entry *snd_minor_info_entry = NULL; 335static struct snd_info_entry *snd_minor_info_entry;
330 336
331static const char *snd_device_type_name(int type) 337static const char *snd_device_type_name(int type)
332{ 338{
@@ -381,7 +387,6 @@ int __init snd_minor_info_init(void)
381 387
382 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); 388 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL);
383 if (entry) { 389 if (entry) {
384 entry->c.text.read_size = PAGE_SIZE;
385 entry->c.text.read = snd_minor_info_read; 390 entry->c.text.read = snd_minor_info_read;
386 if (snd_info_register(entry) < 0) { 391 if (snd_info_register(entry) < 0) {
387 snd_info_free_entry(entry); 392 snd_info_free_entry(entry);
@@ -446,91 +451,3 @@ static void __exit alsa_sound_exit(void)
446 451
447module_init(alsa_sound_init) 452module_init(alsa_sound_init)
448module_exit(alsa_sound_exit) 453module_exit(alsa_sound_exit)
449
450 /* sound.c */
451EXPORT_SYMBOL(snd_major);
452EXPORT_SYMBOL(snd_ecards_limit);
453#if defined(CONFIG_KMOD)
454EXPORT_SYMBOL(snd_request_card);
455#endif
456EXPORT_SYMBOL(snd_register_device);
457EXPORT_SYMBOL(snd_unregister_device);
458EXPORT_SYMBOL(snd_lookup_minor_data);
459#if defined(CONFIG_SND_OSSEMUL)
460EXPORT_SYMBOL(snd_register_oss_device);
461EXPORT_SYMBOL(snd_unregister_oss_device);
462EXPORT_SYMBOL(snd_lookup_oss_minor_data);
463#endif
464 /* memory.c */
465EXPORT_SYMBOL(copy_to_user_fromio);
466EXPORT_SYMBOL(copy_from_user_toio);
467 /* init.c */
468EXPORT_SYMBOL(snd_cards);
469#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
470EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
471#endif
472EXPORT_SYMBOL(snd_card_new);
473EXPORT_SYMBOL(snd_card_disconnect);
474EXPORT_SYMBOL(snd_card_free);
475EXPORT_SYMBOL(snd_card_free_in_thread);
476EXPORT_SYMBOL(snd_card_register);
477EXPORT_SYMBOL(snd_component_add);
478EXPORT_SYMBOL(snd_card_file_add);
479EXPORT_SYMBOL(snd_card_file_remove);
480#ifdef CONFIG_PM
481EXPORT_SYMBOL(snd_power_wait);
482#endif
483 /* device.c */
484EXPORT_SYMBOL(snd_device_new);
485EXPORT_SYMBOL(snd_device_register);
486EXPORT_SYMBOL(snd_device_free);
487 /* isadma.c */
488#ifdef CONFIG_ISA_DMA_API
489EXPORT_SYMBOL(snd_dma_program);
490EXPORT_SYMBOL(snd_dma_disable);
491EXPORT_SYMBOL(snd_dma_pointer);
492#endif
493 /* info.c */
494#ifdef CONFIG_PROC_FS
495EXPORT_SYMBOL(snd_seq_root);
496EXPORT_SYMBOL(snd_iprintf);
497EXPORT_SYMBOL(snd_info_get_line);
498EXPORT_SYMBOL(snd_info_get_str);
499EXPORT_SYMBOL(snd_info_create_module_entry);
500EXPORT_SYMBOL(snd_info_create_card_entry);
501EXPORT_SYMBOL(snd_info_free_entry);
502EXPORT_SYMBOL(snd_info_register);
503EXPORT_SYMBOL(snd_info_unregister);
504EXPORT_SYMBOL(snd_card_proc_new);
505#endif
506 /* info_oss.c */
507#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
508EXPORT_SYMBOL(snd_oss_info_register);
509#endif
510 /* control.c */
511EXPORT_SYMBOL(snd_ctl_new);
512EXPORT_SYMBOL(snd_ctl_new1);
513EXPORT_SYMBOL(snd_ctl_free_one);
514EXPORT_SYMBOL(snd_ctl_add);
515EXPORT_SYMBOL(snd_ctl_remove);
516EXPORT_SYMBOL(snd_ctl_remove_id);
517EXPORT_SYMBOL(snd_ctl_rename_id);
518EXPORT_SYMBOL(snd_ctl_find_numid);
519EXPORT_SYMBOL(snd_ctl_find_id);
520EXPORT_SYMBOL(snd_ctl_notify);
521EXPORT_SYMBOL(snd_ctl_register_ioctl);
522EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
523#ifdef CONFIG_COMPAT
524EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
525EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
526#endif
527EXPORT_SYMBOL(snd_ctl_elem_read);
528EXPORT_SYMBOL(snd_ctl_elem_write);
529 /* misc.c */
530EXPORT_SYMBOL(release_and_free_resource);
531#ifdef CONFIG_SND_VERBOSE_PRINTK
532EXPORT_SYMBOL(snd_verbose_printk);
533#endif
534#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
535EXPORT_SYMBOL(snd_verbose_printd);
536#endif
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 9055c6de9587..74f0fe5a1ba0 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -58,6 +58,8 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
58 return private_data; 58 return private_data;
59} 59}
60 60
61EXPORT_SYMBOL(snd_lookup_oss_minor_data);
62
61static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) 63static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
62{ 64{
63 int minor; 65 int minor;
@@ -158,6 +160,8 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
158 return -EBUSY; 160 return -EBUSY;
159} 161}
160 162
163EXPORT_SYMBOL(snd_register_oss_device);
164
161int snd_unregister_oss_device(int type, struct snd_card *card, int dev) 165int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
162{ 166{
163 int minor = snd_oss_kernel_minor(type, card, dev); 167 int minor = snd_oss_kernel_minor(type, card, dev);
@@ -197,13 +201,15 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
197 return 0; 201 return 0;
198} 202}
199 203
204EXPORT_SYMBOL(snd_unregister_oss_device);
205
200/* 206/*
201 * INFO PART 207 * INFO PART
202 */ 208 */
203 209
204#ifdef CONFIG_PROC_FS 210#ifdef CONFIG_PROC_FS
205 211
206static struct snd_info_entry *snd_minor_info_oss_entry = NULL; 212static struct snd_info_entry *snd_minor_info_oss_entry;
207 213
208static const char *snd_oss_device_type_name(int type) 214static const char *snd_oss_device_type_name(int type)
209{ 215{
@@ -252,7 +258,6 @@ int __init snd_minor_info_oss_init(void)
252 258
253 entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); 259 entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
254 if (entry) { 260 if (entry) {
255 entry->c.text.read_size = PAGE_SIZE;
256 entry->c.text.read = snd_minor_info_oss_read; 261 entry->c.text.read = snd_minor_info_oss_read;
257 if (snd_info_register(entry) < 0) { 262 if (snd_info_register(entry) < 0) {
258 snd_info_free_entry(entry); 263 snd_info_free_entry(entry);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index cdeeb639b675..78199f58b93a 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1061,7 +1061,6 @@ static int snd_timer_register_system(void)
1061static void snd_timer_proc_read(struct snd_info_entry *entry, 1061static void snd_timer_proc_read(struct snd_info_entry *entry,
1062 struct snd_info_buffer *buffer) 1062 struct snd_info_buffer *buffer)
1063{ 1063{
1064 unsigned long flags;
1065 struct snd_timer *timer; 1064 struct snd_timer *timer;
1066 struct snd_timer_instance *ti; 1065 struct snd_timer_instance *ti;
1067 struct list_head *p, *q; 1066 struct list_head *p, *q;
@@ -1095,7 +1094,6 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1095 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) 1094 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
1096 snd_iprintf(buffer, " SLAVE"); 1095 snd_iprintf(buffer, " SLAVE");
1097 snd_iprintf(buffer, "\n"); 1096 snd_iprintf(buffer, "\n");
1098 spin_lock_irqsave(&timer->lock, flags);
1099 list_for_each(q, &timer->open_list_head) { 1097 list_for_each(q, &timer->open_list_head) {
1100 ti = list_entry(q, struct snd_timer_instance, open_list); 1098 ti = list_entry(q, struct snd_timer_instance, open_list);
1101 snd_iprintf(buffer, " Client %s : %s\n", 1099 snd_iprintf(buffer, " Client %s : %s\n",
@@ -1104,12 +1102,11 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1104 SNDRV_TIMER_IFLG_RUNNING) 1102 SNDRV_TIMER_IFLG_RUNNING)
1105 ? "running" : "stopped"); 1103 ? "running" : "stopped");
1106 } 1104 }
1107 spin_unlock_irqrestore(&timer->lock, flags);
1108 } 1105 }
1109 mutex_unlock(&register_mutex); 1106 mutex_unlock(&register_mutex);
1110} 1107}
1111 1108
1112static struct snd_info_entry *snd_timer_proc_entry = NULL; 1109static struct snd_info_entry *snd_timer_proc_entry;
1113 1110
1114static void __init snd_timer_proc_init(void) 1111static void __init snd_timer_proc_init(void)
1115{ 1112{
@@ -1117,7 +1114,6 @@ static void __init snd_timer_proc_init(void)
1117 1114
1118 entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); 1115 entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
1119 if (entry != NULL) { 1116 if (entry != NULL) {
1120 entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
1121 entry->c.text.read = snd_timer_proc_read; 1117 entry->c.text.read = snd_timer_proc_read;
1122 if (snd_info_register(entry) < 0) { 1118 if (snd_info_register(entry) < 0) {
1123 snd_info_free_entry(entry); 1119 snd_info_free_entry(entry);