aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-23 23:44:19 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-23 23:44:19 -0500
commit1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch)
treef5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /sound/core
parentac58c9059da8886b5e8cde012a80266b18ca146e (diff)
parent674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff)
Merge branch 'linus'
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/Kconfig18
-rw-r--r--sound/core/control.c39
-rw-r--r--sound/core/control_compat.c33
-rw-r--r--sound/core/hwdep.c43
-rw-r--r--sound/core/info.c27
-rw-r--r--sound/core/info_oss.c13
-rw-r--r--sound/core/init.c44
-rw-r--r--sound/core/memalloc.c56
-rw-r--r--sound/core/oss/copy.c5
-rw-r--r--sound/core/oss/io.c5
-rw-r--r--sound/core/oss/linear.c7
-rw-r--r--sound/core/oss/mixer_oss.c14
-rw-r--r--sound/core/oss/mulaw.c24
-rw-r--r--sound/core/oss/pcm_oss.c50
-rw-r--r--sound/core/oss/pcm_plugin.c272
-rw-r--r--sound/core/oss/pcm_plugin.h28
-rw-r--r--sound/core/oss/plugin_ops.h166
-rw-r--r--sound/core/oss/rate.c85
-rw-r--r--sound/core/oss/route.c489
-rw-r--r--sound/core/pcm.c45
-rw-r--r--sound/core/pcm_native.c28
-rw-r--r--sound/core/rawmidi.c57
-rw-r--r--sound/core/seq/oss/seq_oss.c27
-rw-r--r--sound/core/seq/seq_clientmgr.c43
-rw-r--r--sound/core/seq/seq_clientmgr.h2
-rw-r--r--sound/core/seq/seq_device.c53
-rw-r--r--sound/core/seq/seq_instr.c6
-rw-r--r--sound/core/seq/seq_midi.c20
-rw-r--r--sound/core/seq/seq_ports.c12
-rw-r--r--sound/core/seq/seq_queue.c6
-rw-r--r--sound/core/seq/seq_queue.h2
-rw-r--r--sound/core/seq/seq_virmidi.c4
-rw-r--r--sound/core/sound.c27
-rw-r--r--sound/core/sound_oss.c25
-rw-r--r--sound/core/timer.c77
35 files changed, 593 insertions, 1259 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index f79755f77a81..9dd121bb5638 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -73,6 +73,15 @@ config SND_PCM_OSS
73 To compile this driver as a module, choose M here: the module 73 To compile this driver as a module, choose M here: the module
74 will be called snd-pcm-oss. 74 will be called snd-pcm-oss.
75 75
76config SND_PCM_OSS_PLUGINS
77 bool "OSS PCM (digital audio) API - Include plugin system"
78 depends on SND_PCM_OSS
79 default y
80 help
81 If you disable this option, the ALSA's OSS PCM API will not
82 support conversion of channels, formats and rates. It will
83 behave like most of new OSS/Free drivers in 2.4/2.6 kernels.
84
76config SND_SEQUENCER_OSS 85config SND_SEQUENCER_OSS
77 bool "OSS Sequencer API" 86 bool "OSS Sequencer API"
78 depends on SND && SND_SEQUENCER 87 depends on SND && SND_SEQUENCER
@@ -130,6 +139,15 @@ config SND_SUPPORT_OLD_API
130 Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 139 Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3
131 or older). 140 or older).
132 141
142config SND_VERBOSE_PROCFS
143 bool "Verbose procfs contents"
144 depends on SND
145 default y
146 help
147 Say Y here to include code for verbose procfs contents (provides
148 usefull information to developers when a problem occurs). On the
149 other side, it makes the ALSA subsystem larger.
150
133config SND_VERBOSE_PRINTK 151config SND_VERBOSE_PRINTK
134 bool "Verbose printk" 152 bool "Verbose printk"
135 depends on SND 153 depends on SND
diff --git a/sound/core/control.c b/sound/core/control.c
index 0c29679a8576..574745314e70 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
309{ 309{
310 struct snd_ctl_elem_id id; 310 struct snd_ctl_elem_id id;
311 unsigned int idx; 311 unsigned int idx;
312 int err = -EINVAL;
312 313
313 snd_assert(card != NULL, return -EINVAL);
314 if (! kcontrol) 314 if (! kcontrol)
315 return -EINVAL; 315 return err;
316 snd_assert(kcontrol->info != NULL, return -EINVAL); 316 snd_assert(card != NULL, goto error);
317 snd_assert(kcontrol->info != NULL, goto error);
317 id = kcontrol->id; 318 id = kcontrol->id;
318 down_write(&card->controls_rwsem); 319 down_write(&card->controls_rwsem);
319 if (snd_ctl_find_id(card, &id)) { 320 if (snd_ctl_find_id(card, &id)) {
320 up_write(&card->controls_rwsem); 321 up_write(&card->controls_rwsem);
321 snd_ctl_free_one(kcontrol);
322 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", 322 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
323 id.iface, 323 id.iface,
324 id.device, 324 id.device,
325 id.subdevice, 325 id.subdevice,
326 id.name, 326 id.name,
327 id.index); 327 id.index);
328 return -EBUSY; 328 err = -EBUSY;
329 goto error;
329 } 330 }
330 if (snd_ctl_find_hole(card, kcontrol->count) < 0) { 331 if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
331 up_write(&card->controls_rwsem); 332 up_write(&card->controls_rwsem);
332 snd_ctl_free_one(kcontrol); 333 err = -ENOMEM;
333 return -ENOMEM; 334 goto error;
334 } 335 }
335 list_add_tail(&kcontrol->list, &card->controls); 336 list_add_tail(&kcontrol->list, &card->controls);
336 card->controls_count += kcontrol->count; 337 card->controls_count += kcontrol->count;
@@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
340 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) 341 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
341 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); 342 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
342 return 0; 343 return 0;
344
345 error:
346 snd_ctl_free_one(kcontrol);
347 return err;
343} 348}
344 349
345/** 350/**
@@ -658,7 +663,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
658 663
659 if (copy_from_user(&info, _info, sizeof(info))) 664 if (copy_from_user(&info, _info, sizeof(info)))
660 return -EFAULT; 665 return -EFAULT;
661 result = snd_ctl_elem_info(ctl, &info); 666 snd_power_lock(ctl->card);
667 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
668 if (result >= 0)
669 result = snd_ctl_elem_info(ctl, &info);
670 snd_power_unlock(ctl->card);
662 if (result >= 0) 671 if (result >= 0)
663 if (copy_to_user(_info, &info, sizeof(info))) 672 if (copy_to_user(_info, &info, sizeof(info)))
664 return -EFAULT; 673 return -EFAULT;
@@ -708,7 +717,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
708 kfree(control); 717 kfree(control);
709 return -EFAULT; 718 return -EFAULT;
710 } 719 }
711 result = snd_ctl_elem_read(card, control); 720 snd_power_lock(card);
721 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
722 if (result >= 0)
723 result = snd_ctl_elem_read(card, control);
724 snd_power_unlock(card);
712 if (result >= 0) 725 if (result >= 0)
713 if (copy_to_user(_control, control, sizeof(*control))) 726 if (copy_to_user(_control, control, sizeof(*control)))
714 result = -EFAULT; 727 result = -EFAULT;
@@ -758,6 +771,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
758 struct snd_ctl_elem_value __user *_control) 771 struct snd_ctl_elem_value __user *_control)
759{ 772{
760 struct snd_ctl_elem_value *control; 773 struct snd_ctl_elem_value *control;
774 struct snd_card *card;
761 int result; 775 int result;
762 776
763 control = kmalloc(sizeof(*control), GFP_KERNEL); 777 control = kmalloc(sizeof(*control), GFP_KERNEL);
@@ -767,7 +781,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
767 kfree(control); 781 kfree(control);
768 return -EFAULT; 782 return -EFAULT;
769 } 783 }
770 result = snd_ctl_elem_write(file->card, file, control); 784 card = file->card;
785 snd_power_lock(card);
786 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
787 if (result >= 0)
788 result = snd_ctl_elem_write(card, file, control);
789 snd_power_unlock(card);
771 if (result >= 0) 790 if (result >= 0)
772 if (copy_to_user(_control, control, sizeof(*control))) 791 if (copy_to_user(_control, control, sizeof(*control)))
773 result = -EFAULT; 792 result = -EFAULT;
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index a529b62972b4..84fef5084e17 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -107,7 +107,13 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
107 */ 107 */
108 if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) 108 if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
109 goto error; 109 goto error;
110 err = snd_ctl_elem_info(ctl, data); 110
111 snd_power_lock(ctl->card);
112 err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
113 if (err >= 0)
114 err = snd_ctl_elem_info(ctl, data);
115 snd_power_unlock(ctl->card);
116
111 if (err < 0) 117 if (err < 0)
112 goto error; 118 goto error;
113 /* restore info to 32bit */ 119 /* restore info to 32bit */
@@ -286,9 +292,14 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
286 292
287 if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) 293 if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
288 goto error; 294 goto error;
289 if ((err = snd_ctl_elem_read(card, data)) < 0) 295
290 goto error; 296 snd_power_lock(card);
291 err = copy_ctl_value_to_user(data32, data, type, count); 297 err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
298 if (err >= 0)
299 err = snd_ctl_elem_read(card, data);
300 snd_power_unlock(card);
301 if (err >= 0)
302 err = copy_ctl_value_to_user(data32, data, type, count);
292 error: 303 error:
293 kfree(data); 304 kfree(data);
294 return err; 305 return err;
@@ -298,17 +309,23 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
298 struct snd_ctl_elem_value32 __user *data32) 309 struct snd_ctl_elem_value32 __user *data32)
299{ 310{
300 struct snd_ctl_elem_value *data; 311 struct snd_ctl_elem_value *data;
312 struct snd_card *card = file->card;
301 int err, type, count; 313 int err, type, count;
302 314
303 data = kzalloc(sizeof(*data), GFP_KERNEL); 315 data = kzalloc(sizeof(*data), GFP_KERNEL);
304 if (data == NULL) 316 if (data == NULL)
305 return -ENOMEM; 317 return -ENOMEM;
306 318
307 if ((err = copy_ctl_value_from_user(file->card, data, data32, &type, &count)) < 0) 319 if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
308 goto error;
309 if ((err = snd_ctl_elem_write(file->card, file, data)) < 0)
310 goto error; 320 goto error;
311 err = copy_ctl_value_to_user(data32, data, type, count); 321
322 snd_power_lock(card);
323 err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
324 if (err >= 0)
325 err = snd_ctl_elem_write(card, file, data);
326 snd_power_unlock(card);
327 if (err >= 0)
328 err = copy_ctl_value_to_user(data32, data, type, count);
312 error: 329 error:
313 kfree(data); 330 kfree(data);
314 return err; 331 return err;
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 618c43be0bc3..2524e66eccdd 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -25,6 +25,7 @@
25#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/time.h> 27#include <linux/time.h>
28#include <linux/mutex.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/control.h> 30#include <sound/control.h>
30#include <sound/minors.h> 31#include <sound/minors.h>
@@ -36,7 +37,7 @@ MODULE_DESCRIPTION("Hardware dependent layer");
36MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
37 38
38static LIST_HEAD(snd_hwdep_devices); 39static LIST_HEAD(snd_hwdep_devices);
39static DECLARE_MUTEX(register_mutex); 40static DEFINE_MUTEX(register_mutex);
40 41
41static int snd_hwdep_free(struct snd_hwdep *hwdep); 42static int snd_hwdep_free(struct snd_hwdep *hwdep);
42static int snd_hwdep_dev_free(struct snd_device *device); 43static int snd_hwdep_dev_free(struct snd_device *device);
@@ -111,7 +112,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
111 112
112 init_waitqueue_entry(&wait, current); 113 init_waitqueue_entry(&wait, current);
113 add_wait_queue(&hw->open_wait, &wait); 114 add_wait_queue(&hw->open_wait, &wait);
114 down(&hw->open_mutex); 115 mutex_lock(&hw->open_mutex);
115 while (1) { 116 while (1) {
116 if (hw->exclusive && hw->used > 0) { 117 if (hw->exclusive && hw->used > 0) {
117 err = -EBUSY; 118 err = -EBUSY;
@@ -128,9 +129,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
128 } else 129 } else
129 break; 130 break;
130 set_current_state(TASK_INTERRUPTIBLE); 131 set_current_state(TASK_INTERRUPTIBLE);
131 up(&hw->open_mutex); 132 mutex_unlock(&hw->open_mutex);
132 schedule(); 133 schedule();
133 down(&hw->open_mutex); 134 mutex_lock(&hw->open_mutex);
134 if (signal_pending(current)) { 135 if (signal_pending(current)) {
135 err = -ERESTARTSYS; 136 err = -ERESTARTSYS;
136 break; 137 break;
@@ -147,7 +148,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
147 hw->ops.release(hw, file); 148 hw->ops.release(hw, file);
148 } 149 }
149 } 150 }
150 up(&hw->open_mutex); 151 mutex_unlock(&hw->open_mutex);
151 if (err < 0) 152 if (err < 0)
152 module_put(hw->card->module); 153 module_put(hw->card->module);
153 return err; 154 return err;
@@ -157,7 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
157{ 158{
158 int err = -ENXIO; 159 int err = -ENXIO;
159 struct snd_hwdep *hw = file->private_data; 160 struct snd_hwdep *hw = file->private_data;
160 down(&hw->open_mutex); 161 mutex_lock(&hw->open_mutex);
161 if (hw->ops.release) { 162 if (hw->ops.release) {
162 err = hw->ops.release(hw, file); 163 err = hw->ops.release(hw, file);
163 wake_up(&hw->open_wait); 164 wake_up(&hw->open_wait);
@@ -165,7 +166,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
165 if (hw->used > 0) 166 if (hw->used > 0)
166 hw->used--; 167 hw->used--;
167 snd_card_file_remove(hw->card, file); 168 snd_card_file_remove(hw->card, file);
168 up(&hw->open_mutex); 169 mutex_unlock(&hw->open_mutex);
169 module_put(hw->card->module); 170 module_put(hw->card->module);
170 return err; 171 return err;
171} 172}
@@ -272,7 +273,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
272 273
273 if (get_user(device, (int __user *)arg)) 274 if (get_user(device, (int __user *)arg))
274 return -EFAULT; 275 return -EFAULT;
275 down(&register_mutex); 276 mutex_lock(&register_mutex);
276 device = device < 0 ? 0 : device + 1; 277 device = device < 0 ? 0 : device + 1;
277 while (device < SNDRV_MINOR_HWDEPS) { 278 while (device < SNDRV_MINOR_HWDEPS) {
278 if (snd_hwdep_search(card, device)) 279 if (snd_hwdep_search(card, device))
@@ -281,7 +282,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
281 } 282 }
282 if (device >= SNDRV_MINOR_HWDEPS) 283 if (device >= SNDRV_MINOR_HWDEPS)
283 device = -1; 284 device = -1;
284 up(&register_mutex); 285 mutex_unlock(&register_mutex);
285 if (put_user(device, (int __user *)arg)) 286 if (put_user(device, (int __user *)arg))
286 return -EFAULT; 287 return -EFAULT;
287 return 0; 288 return 0;
@@ -294,13 +295,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
294 295
295 if (get_user(device, &info->device)) 296 if (get_user(device, &info->device))
296 return -EFAULT; 297 return -EFAULT;
297 down(&register_mutex); 298 mutex_lock(&register_mutex);
298 hwdep = snd_hwdep_search(card, device); 299 hwdep = snd_hwdep_search(card, device);
299 if (hwdep) 300 if (hwdep)
300 err = snd_hwdep_info(hwdep, info); 301 err = snd_hwdep_info(hwdep, info);
301 else 302 else
302 err = -ENXIO; 303 err = -ENXIO;
303 up(&register_mutex); 304 mutex_unlock(&register_mutex);
304 return err; 305 return err;
305 } 306 }
306 } 307 }
@@ -375,7 +376,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
375 return err; 376 return err;
376 } 377 }
377 init_waitqueue_head(&hwdep->open_wait); 378 init_waitqueue_head(&hwdep->open_wait);
378 init_MUTEX(&hwdep->open_mutex); 379 mutex_init(&hwdep->open_mutex);
379 *rhwdep = hwdep; 380 *rhwdep = hwdep;
380 return 0; 381 return 0;
381} 382}
@@ -401,9 +402,9 @@ static int snd_hwdep_dev_register(struct snd_device *device)
401 int err; 402 int err;
402 char name[32]; 403 char name[32];
403 404
404 down(&register_mutex); 405 mutex_lock(&register_mutex);
405 if (snd_hwdep_search(hwdep->card, hwdep->device)) { 406 if (snd_hwdep_search(hwdep->card, hwdep->device)) {
406 up(&register_mutex); 407 mutex_unlock(&register_mutex);
407 return -EBUSY; 408 return -EBUSY;
408 } 409 }
409 list_add_tail(&hwdep->list, &snd_hwdep_devices); 410 list_add_tail(&hwdep->list, &snd_hwdep_devices);
@@ -414,7 +415,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
414 snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", 415 snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
415 hwdep->card->number, hwdep->device); 416 hwdep->card->number, hwdep->device);
416 list_del(&hwdep->list); 417 list_del(&hwdep->list);
417 up(&register_mutex); 418 mutex_unlock(&register_mutex);
418 return err; 419 return err;
419 } 420 }
420#ifdef CONFIG_SND_OSSEMUL 421#ifdef CONFIG_SND_OSSEMUL
@@ -434,7 +435,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
434 } 435 }
435 } 436 }
436#endif 437#endif
437 up(&register_mutex); 438 mutex_unlock(&register_mutex);
438 return 0; 439 return 0;
439} 440}
440 441
@@ -443,9 +444,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
443 struct snd_hwdep *hwdep = device->device_data; 444 struct snd_hwdep *hwdep = device->device_data;
444 445
445 snd_assert(hwdep != NULL, return -ENXIO); 446 snd_assert(hwdep != NULL, return -ENXIO);
446 down(&register_mutex); 447 mutex_lock(&register_mutex);
447 if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { 448 if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
448 up(&register_mutex); 449 mutex_unlock(&register_mutex);
449 return -EINVAL; 450 return -EINVAL;
450 } 451 }
451#ifdef CONFIG_SND_OSSEMUL 452#ifdef CONFIG_SND_OSSEMUL
@@ -454,7 +455,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
454#endif 455#endif
455 snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); 456 snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
456 list_del(&hwdep->list); 457 list_del(&hwdep->list);
457 up(&register_mutex); 458 mutex_unlock(&register_mutex);
458 return snd_hwdep_free(hwdep); 459 return snd_hwdep_free(hwdep);
459} 460}
460 461
@@ -469,13 +470,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry,
469 struct list_head *p; 470 struct list_head *p;
470 struct snd_hwdep *hwdep; 471 struct snd_hwdep *hwdep;
471 472
472 down(&register_mutex); 473 mutex_lock(&register_mutex);
473 list_for_each(p, &snd_hwdep_devices) { 474 list_for_each(p, &snd_hwdep_devices) {
474 hwdep = list_entry(p, struct snd_hwdep, list); 475 hwdep = list_entry(p, struct snd_hwdep, list);
475 snd_iprintf(buffer, "%02i-%02i: %s\n", 476 snd_iprintf(buffer, "%02i-%02i: %s\n",
476 hwdep->card->number, hwdep->device, hwdep->name); 477 hwdep->card->number, hwdep->device, hwdep->name);
477 } 478 }
478 up(&register_mutex); 479 mutex_unlock(&register_mutex);
479} 480}
480 481
481static struct snd_info_entry *snd_hwdep_proc_entry; 482static struct snd_info_entry *snd_hwdep_proc_entry;
diff --git a/sound/core/info.c b/sound/core/info.c
index af123e3bdb24..2582b74d3199 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -31,6 +31,7 @@
31#include <sound/version.h> 31#include <sound/version.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/devfs_fs_kernel.h> 33#include <linux/devfs_fs_kernel.h>
34#include <linux/mutex.h>
34#include <stdarg.h> 35#include <stdarg.h>
35 36
36/* 37/*
@@ -68,7 +69,7 @@ int snd_info_check_reserved_words(const char *str)
68 return 1; 69 return 1;
69} 70}
70 71
71static DECLARE_MUTEX(info_mutex); 72static DEFINE_MUTEX(info_mutex);
72 73
73struct snd_info_private_data { 74struct snd_info_private_data {
74 struct snd_info_buffer *rbuffer; 75 struct snd_info_buffer *rbuffer;
@@ -265,11 +266,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
265 struct proc_dir_entry *p; 266 struct proc_dir_entry *p;
266 int mode, err; 267 int mode, err;
267 268
268 down(&info_mutex); 269 mutex_lock(&info_mutex);
269 p = PDE(inode); 270 p = PDE(inode);
270 entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; 271 entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
271 if (entry == NULL || entry->disconnected) { 272 if (entry == NULL || entry->disconnected) {
272 up(&info_mutex); 273 mutex_unlock(&info_mutex);
273 return -ENODEV; 274 return -ENODEV;
274 } 275 }
275 if (!try_module_get(entry->module)) { 276 if (!try_module_get(entry->module)) {
@@ -361,13 +362,13 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
361 break; 362 break;
362 } 363 }
363 file->private_data = data; 364 file->private_data = data;
364 up(&info_mutex); 365 mutex_unlock(&info_mutex);
365 if (entry->content == SNDRV_INFO_CONTENT_TEXT && 366 if (entry->content == SNDRV_INFO_CONTENT_TEXT &&
366 (mode == O_RDONLY || mode == O_RDWR)) { 367 (mode == O_RDONLY || mode == O_RDWR)) {
367 if (entry->c.text.read) { 368 if (entry->c.text.read) {
368 down(&entry->access); 369 mutex_lock(&entry->access);
369 entry->c.text.read(entry, data->rbuffer); 370 entry->c.text.read(entry, data->rbuffer);
370 up(&entry->access); 371 mutex_unlock(&entry->access);
371 } 372 }
372 } 373 }
373 return 0; 374 return 0;
@@ -375,7 +376,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
375 __error: 376 __error:
376 module_put(entry->module); 377 module_put(entry->module);
377 __error1: 378 __error1:
378 up(&info_mutex); 379 mutex_unlock(&info_mutex);
379 return err; 380 return err;
380} 381}
381 382
@@ -747,7 +748,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name)
747 } 748 }
748 entry->mode = S_IFREG | S_IRUGO; 749 entry->mode = S_IFREG | S_IRUGO;
749 entry->content = SNDRV_INFO_CONTENT_TEXT; 750 entry->content = SNDRV_INFO_CONTENT_TEXT;
750 init_MUTEX(&entry->access); 751 mutex_init(&entry->access);
751 return entry; 752 return entry;
752} 753}
753 754
@@ -896,10 +897,10 @@ int snd_info_register(struct snd_info_entry * entry)
896 897
897 snd_assert(entry != NULL, return -ENXIO); 898 snd_assert(entry != NULL, return -ENXIO);
898 root = entry->parent == NULL ? snd_proc_root : entry->parent->p; 899 root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
899 down(&info_mutex); 900 mutex_lock(&info_mutex);
900 p = snd_create_proc_entry(entry->name, entry->mode, root); 901 p = snd_create_proc_entry(entry->name, entry->mode, root);
901 if (!p) { 902 if (!p) {
902 up(&info_mutex); 903 mutex_unlock(&info_mutex);
903 return -ENOMEM; 904 return -ENOMEM;
904 } 905 }
905 p->owner = entry->module; 906 p->owner = entry->module;
@@ -908,7 +909,7 @@ int snd_info_register(struct snd_info_entry * entry)
908 p->size = entry->size; 909 p->size = entry->size;
909 p->data = entry; 910 p->data = entry;
910 entry->p = p; 911 entry->p = p;
911 up(&info_mutex); 912 mutex_unlock(&info_mutex);
912 return 0; 913 return 0;
913} 914}
914 915
@@ -929,9 +930,9 @@ int snd_info_unregister(struct snd_info_entry * entry)
929 snd_assert(entry->p != NULL, return -ENXIO); 930 snd_assert(entry->p != NULL, return -ENXIO);
930 root = entry->parent == NULL ? snd_proc_root : entry->parent->p; 931 root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
931 snd_assert(root, return -ENXIO); 932 snd_assert(root, return -ENXIO);
932 down(&info_mutex); 933 mutex_lock(&info_mutex);
933 snd_remove_proc_entry(root, entry->p); 934 snd_remove_proc_entry(root, entry->p);
934 up(&info_mutex); 935 mutex_unlock(&info_mutex);
935 snd_info_free_entry(entry); 936 snd_info_free_entry(entry);
936 return 0; 937 return 0;
937} 938}
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index 820f4772e44a..f9ce854b3d11 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -28,6 +28,7 @@
28#include <sound/info.h> 28#include <sound/info.h>
29#include <sound/version.h> 29#include <sound/version.h>
30#include <linux/utsname.h> 30#include <linux/utsname.h>
31#include <linux/mutex.h>
31 32
32#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) 33#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
33 34
@@ -35,7 +36,7 @@
35 * OSS compatible part 36 * OSS compatible part
36 */ 37 */
37 38
38static DECLARE_MUTEX(strings); 39static DEFINE_MUTEX(strings);
39static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT]; 40static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT];
40static struct snd_info_entry *snd_sndstat_proc_entry; 41static struct snd_info_entry *snd_sndstat_proc_entry;
41 42
@@ -45,7 +46,7 @@ int snd_oss_info_register(int dev, int num, char *string)
45 46
46 snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); 47 snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO);
47 snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); 48 snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO);
48 down(&strings); 49 mutex_lock(&strings);
49 if (string == NULL) { 50 if (string == NULL) {
50 if ((x = snd_sndstat_strings[num][dev]) != NULL) { 51 if ((x = snd_sndstat_strings[num][dev]) != NULL) {
51 kfree(x); 52 kfree(x);
@@ -54,12 +55,12 @@ int snd_oss_info_register(int dev, int num, char *string)
54 } else { 55 } else {
55 x = kstrdup(string, GFP_KERNEL); 56 x = kstrdup(string, GFP_KERNEL);
56 if (x == NULL) { 57 if (x == NULL) {
57 up(&strings); 58 mutex_unlock(&strings);
58 return -ENOMEM; 59 return -ENOMEM;
59 } 60 }
60 } 61 }
61 snd_sndstat_strings[num][dev] = x; 62 snd_sndstat_strings[num][dev] = x;
62 up(&strings); 63 mutex_unlock(&strings);
63 return 0; 64 return 0;
64} 65}
65 66
@@ -71,7 +72,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
71 char *str; 72 char *str;
72 73
73 snd_iprintf(buf, "\n%s:", id); 74 snd_iprintf(buf, "\n%s:", id);
74 down(&strings); 75 mutex_lock(&strings);
75 for (idx = 0; idx < SNDRV_CARDS; idx++) { 76 for (idx = 0; idx < SNDRV_CARDS; idx++) {
76 str = snd_sndstat_strings[idx][dev]; 77 str = snd_sndstat_strings[idx][dev];
77 if (str) { 78 if (str) {
@@ -82,7 +83,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
82 snd_iprintf(buf, "%i: %s\n", idx, str); 83 snd_iprintf(buf, "%i: %s\n", idx, str);
83 } 84 }
84 } 85 }
85 up(&strings); 86 mutex_unlock(&strings);
86 if (ok < 0) 87 if (ok < 0)
87 snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); 88 snd_iprintf(buf, " NOT ENABLED IN CONFIG\n");
88 return ok; 89 return ok;
diff --git a/sound/core/init.c b/sound/core/init.c
index 75816688607c..ad68761abba1 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -145,7 +145,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
145 init_waitqueue_head(&card->shutdown_sleep); 145 init_waitqueue_head(&card->shutdown_sleep);
146 INIT_WORK(&card->free_workq, snd_card_free_thread, card); 146 INIT_WORK(&card->free_workq, snd_card_free_thread, card);
147#ifdef CONFIG_PM 147#ifdef CONFIG_PM
148 init_MUTEX(&card->power_lock); 148 mutex_init(&card->power_lock);
149 init_waitqueue_head(&card->power_sleep); 149 init_waitqueue_head(&card->power_sleep);
150#endif 150#endif
151 /* the control interface cannot be accessed from the user space until */ 151 /* the control interface cannot be accessed from the user space until */
@@ -169,11 +169,44 @@ struct snd_card *snd_card_new(int idx, const char *xid,
169 return NULL; 169 return NULL;
170} 170}
171 171
172static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
173{
174 return -ENODEV;
175}
176
177static ssize_t snd_disconnect_read(struct file *file, char __user *buf,
178 size_t count, loff_t *offset)
179{
180 return -ENODEV;
181}
182
183static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
184 size_t count, loff_t *offset)
185{
186 return -ENODEV;
187}
188
172static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) 189static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
173{ 190{
174 return POLLERR | POLLNVAL; 191 return POLLERR | POLLNVAL;
175} 192}
176 193
194static long snd_disconnect_ioctl(struct file *file,
195 unsigned int cmd, unsigned long arg)
196{
197 return -ENODEV;
198}
199
200static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma)
201{
202 return -ENODEV;
203}
204
205static int snd_disconnect_fasync(int fd, struct file *file, int on)
206{
207 return -ENODEV;
208}
209
177/** 210/**
178 * snd_card_disconnect - disconnect all APIs from the file-operations (user space) 211 * snd_card_disconnect - disconnect all APIs from the file-operations (user space)
179 * @card: soundcard structure 212 * @card: soundcard structure
@@ -224,7 +257,16 @@ int snd_card_disconnect(struct snd_card *card)
224 memset(f_ops, 0, sizeof(*f_ops)); 257 memset(f_ops, 0, sizeof(*f_ops));
225 f_ops->owner = file->f_op->owner; 258 f_ops->owner = file->f_op->owner;
226 f_ops->release = file->f_op->release; 259 f_ops->release = file->f_op->release;
260 f_ops->llseek = snd_disconnect_llseek;
261 f_ops->read = snd_disconnect_read;
262 f_ops->write = snd_disconnect_write;
227 f_ops->poll = snd_disconnect_poll; 263 f_ops->poll = snd_disconnect_poll;
264 f_ops->unlocked_ioctl = snd_disconnect_ioctl;
265#ifdef CONFIG_COMPAT
266 f_ops->compat_ioctl = snd_disconnect_ioctl;
267#endif
268 f_ops->mmap = snd_disconnect_mmap;
269 f_ops->fasync = snd_disconnect_fasync;
228 270
229 s_f_ops->next = card->s_f_ops; 271 s_f_ops->next = card->s_f_ops;
230 card->s_f_ops = s_f_ops; 272 card->s_f_ops = s_f_ops;
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 19b3dcbb09c2..3fc6f97075ed 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -31,7 +31,7 @@
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <asm/semaphore.h> 34#include <linux/mutex.h>
35#include <sound/memalloc.h> 35#include <sound/memalloc.h>
36#ifdef CONFIG_SBUS 36#ifdef CONFIG_SBUS
37#include <asm/sbus.h> 37#include <asm/sbus.h>
@@ -54,7 +54,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
54/* 54/*
55 */ 55 */
56 56
57static DECLARE_MUTEX(list_mutex); 57static DEFINE_MUTEX(list_mutex);
58static LIST_HEAD(mem_list_head); 58static LIST_HEAD(mem_list_head);
59 59
60/* buffer preservation list */ 60/* buffer preservation list */
@@ -83,7 +83,7 @@ struct snd_mem_list {
83 * Hacks 83 * Hacks
84 */ 84 */
85 85
86#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__) 86#if defined(__i386__)
87/* 87/*
88 * A hack to allocate large buffers via dma_alloc_coherent() 88 * A hack to allocate large buffers via dma_alloc_coherent()
89 * 89 *
@@ -141,10 +141,6 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
141 141
142#endif /* arch */ 142#endif /* arch */
143 143
144#if ! defined(__arm__)
145#define NEED_RESERVE_PAGES
146#endif
147
148/* 144/*
149 * 145 *
150 * Generic memory allocators 146 * Generic memory allocators
@@ -163,20 +159,6 @@ static inline void dec_snd_pages(int order)
163 snd_allocated_pages -= 1 << order; 159 snd_allocated_pages -= 1 << order;
164} 160}
165 161
166static void mark_pages(struct page *page, int order)
167{
168 struct page *last_page = page + (1 << order);
169 while (page < last_page)
170 SetPageReserved(page++);
171}
172
173static void unmark_pages(struct page *page, int order)
174{
175 struct page *last_page = page + (1 << order);
176 while (page < last_page)
177 ClearPageReserved(page++);
178}
179
180/** 162/**
181 * snd_malloc_pages - allocate pages with the given size 163 * snd_malloc_pages - allocate pages with the given size
182 * @size: the size to allocate in bytes 164 * @size: the size to allocate in bytes
@@ -195,10 +177,8 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
195 snd_assert(gfp_flags != 0, return NULL); 177 snd_assert(gfp_flags != 0, return NULL);
196 gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ 178 gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
197 pg = get_order(size); 179 pg = get_order(size);
198 if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) { 180 if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
199 mark_pages(virt_to_page(res), pg);
200 inc_snd_pages(pg); 181 inc_snd_pages(pg);
201 }
202 return res; 182 return res;
203} 183}
204 184
@@ -217,7 +197,6 @@ void snd_free_pages(void *ptr, size_t size)
217 return; 197 return;
218 pg = get_order(size); 198 pg = get_order(size);
219 dec_snd_pages(pg); 199 dec_snd_pages(pg);
220 unmark_pages(virt_to_page(ptr), pg);
221 free_pages((unsigned long) ptr, pg); 200 free_pages((unsigned long) ptr, pg);
222} 201}
223 202
@@ -242,12 +221,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
242 | __GFP_NORETRY /* don't trigger OOM-killer */ 221 | __GFP_NORETRY /* don't trigger OOM-killer */
243 | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ 222 | __GFP_NOWARN; /* no stack trace print - this call is non-critical */
244 res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); 223 res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
245 if (res != NULL) { 224 if (res != NULL)
246#ifdef NEED_RESERVE_PAGES
247 mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */
248#endif
249 inc_snd_pages(pg); 225 inc_snd_pages(pg);
250 }
251 226
252 return res; 227 return res;
253} 228}
@@ -262,9 +237,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
262 return; 237 return;
263 pg = get_order(size); 238 pg = get_order(size);
264 dec_snd_pages(pg); 239 dec_snd_pages(pg);
265#ifdef NEED_RESERVE_PAGES
266 unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */
267#endif
268 dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma); 240 dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
269} 241}
270 242
@@ -440,7 +412,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
440 412
441 snd_assert(dmab, return 0); 413 snd_assert(dmab, return 0);
442 414
443 down(&list_mutex); 415 mutex_lock(&list_mutex);
444 list_for_each(p, &mem_list_head) { 416 list_for_each(p, &mem_list_head) {
445 mem = list_entry(p, struct snd_mem_list, list); 417 mem = list_entry(p, struct snd_mem_list, list);
446 if (mem->id == id && 418 if (mem->id == id &&
@@ -452,11 +424,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
452 if (dmab->dev.dev == NULL) 424 if (dmab->dev.dev == NULL)
453 dmab->dev.dev = dev; 425 dmab->dev.dev = dev;
454 kfree(mem); 426 kfree(mem);
455 up(&list_mutex); 427 mutex_unlock(&list_mutex);
456 return dmab->bytes; 428 return dmab->bytes;
457 } 429 }
458 } 430 }
459 up(&list_mutex); 431 mutex_unlock(&list_mutex);
460 return 0; 432 return 0;
461} 433}
462 434
@@ -477,11 +449,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
477 mem = kmalloc(sizeof(*mem), GFP_KERNEL); 449 mem = kmalloc(sizeof(*mem), GFP_KERNEL);
478 if (! mem) 450 if (! mem)
479 return -ENOMEM; 451 return -ENOMEM;
480 down(&list_mutex); 452 mutex_lock(&list_mutex);
481 mem->buffer = *dmab; 453 mem->buffer = *dmab;
482 mem->id = id; 454 mem->id = id;
483 list_add_tail(&mem->list, &mem_list_head); 455 list_add_tail(&mem->list, &mem_list_head);
484 up(&list_mutex); 456 mutex_unlock(&list_mutex);
485 return 0; 457 return 0;
486} 458}
487 459
@@ -493,7 +465,7 @@ static void free_all_reserved_pages(void)
493 struct list_head *p; 465 struct list_head *p;
494 struct snd_mem_list *mem; 466 struct snd_mem_list *mem;
495 467
496 down(&list_mutex); 468 mutex_lock(&list_mutex);
497 while (! list_empty(&mem_list_head)) { 469 while (! list_empty(&mem_list_head)) {
498 p = mem_list_head.next; 470 p = mem_list_head.next;
499 mem = list_entry(p, struct snd_mem_list, list); 471 mem = list_entry(p, struct snd_mem_list, list);
@@ -501,7 +473,7 @@ static void free_all_reserved_pages(void)
501 snd_dma_free_pages(&mem->buffer); 473 snd_dma_free_pages(&mem->buffer);
502 kfree(mem); 474 kfree(mem);
503 } 475 }
504 up(&list_mutex); 476 mutex_unlock(&list_mutex);
505} 477}
506 478
507 479
@@ -522,7 +494,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
522 int devno; 494 int devno;
523 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; 495 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
524 496
525 down(&list_mutex); 497 mutex_lock(&list_mutex);
526 len += snprintf(page + len, count - len, 498 len += snprintf(page + len, count - len,
527 "pages : %li bytes (%li pages per %likB)\n", 499 "pages : %li bytes (%li pages per %likB)\n",
528 pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); 500 pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
@@ -537,7 +509,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
537 " addr = 0x%lx, size = %d bytes\n", 509 " addr = 0x%lx, size = %d bytes\n",
538 (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes); 510 (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes);
539 } 511 }
540 up(&list_mutex); 512 mutex_unlock(&list_mutex);
541 return len; 513 return len;
542} 514}
543 515
diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c
index d6a04c2d5a75..6658facc5cda 100644
--- a/sound/core/oss/copy.c
+++ b/sound/core/oss/copy.c
@@ -20,6 +20,9 @@
20 */ 20 */
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23
24#ifdef CONFIG_SND_PCM_OSS_PLUGINS
25
23#include <linux/time.h> 26#include <linux/time.h>
24#include <sound/core.h> 27#include <sound/core.h>
25#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -85,3 +88,5 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
85 *r_plugin = plugin; 88 *r_plugin = plugin;
86 return 0; 89 return 0;
87} 90}
91
92#endif
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c
index 322702e05f3e..b6e7ce30e5a3 100644
--- a/sound/core/oss/io.c
+++ b/sound/core/oss/io.c
@@ -20,6 +20,9 @@
20 */ 20 */
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23
24#ifdef CONFIG_SND_PCM_OSS_PLUGINS
25
23#include <linux/time.h> 26#include <linux/time.h>
24#include <sound/core.h> 27#include <sound/core.h>
25#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -132,3 +135,5 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
132 *r_plugin = plugin; 135 *r_plugin = plugin;
133 return 0; 136 return 0;
134} 137}
138
139#endif
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index 8cbfa415ce40..5b1bcdc64779 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -21,6 +21,9 @@
21 */ 21 */
22 22
23#include <sound/driver.h> 23#include <sound/driver.h>
24
25#ifdef CONFIG_SND_PCM_OSS_PLUGINS
26
24#include <linux/time.h> 27#include <linux/time.h>
25#include <sound/core.h> 28#include <sound/core.h>
26#include <sound/pcm.h> 29#include <sound/pcm.h>
@@ -103,7 +106,7 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
103 return frames; 106 return frames;
104} 107}
105 108
106int conv_index(int src_format, int dst_format) 109static int conv_index(int src_format, int dst_format)
107{ 110{
108 int src_endian, dst_endian, sign, src_width, dst_width; 111 int src_endian, dst_endian, sign, src_width, dst_width;
109 112
@@ -156,3 +159,5 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
156 *r_plugin = plugin; 159 *r_plugin = plugin;
157 return 0; 160 return 0;
158} 161}
162
163#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index f08e65a2bffe..9c68bc3f97aa 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1095,7 +1095,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
1095 struct snd_mixer_oss *mixer = entry->private_data; 1095 struct snd_mixer_oss *mixer = entry->private_data;
1096 int i; 1096 int i;
1097 1097
1098 down(&mixer->reg_mutex); 1098 mutex_lock(&mixer->reg_mutex);
1099 for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) { 1099 for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) {
1100 struct slot *p; 1100 struct slot *p;
1101 1101
@@ -1110,7 +1110,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
1110 else 1110 else
1111 snd_iprintf(buffer, "\"\" 0\n"); 1111 snd_iprintf(buffer, "\"\" 0\n");
1112 } 1112 }
1113 up(&mixer->reg_mutex); 1113 mutex_unlock(&mixer->reg_mutex);
1114} 1114}
1115 1115
1116static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, 1116static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
@@ -1134,9 +1134,9 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
1134 cptr = snd_info_get_str(str, cptr, sizeof(str)); 1134 cptr = snd_info_get_str(str, cptr, sizeof(str));
1135 if (! *str) { 1135 if (! *str) {
1136 /* remove the entry */ 1136 /* remove the entry */
1137 down(&mixer->reg_mutex); 1137 mutex_lock(&mixer->reg_mutex);
1138 mixer_slot_clear(&mixer->slots[ch]); 1138 mixer_slot_clear(&mixer->slots[ch]);
1139 up(&mixer->reg_mutex); 1139 mutex_unlock(&mixer->reg_mutex);
1140 continue; 1140 continue;
1141 } 1141 }
1142 snd_info_get_str(idxstr, cptr, sizeof(idxstr)); 1142 snd_info_get_str(idxstr, cptr, sizeof(idxstr));
@@ -1145,7 +1145,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
1145 snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx); 1145 snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx);
1146 continue; 1146 continue;
1147 } 1147 }
1148 down(&mixer->reg_mutex); 1148 mutex_lock(&mixer->reg_mutex);
1149 slot = (struct slot *)mixer->slots[ch].private_data; 1149 slot = (struct slot *)mixer->slots[ch].private_data;
1150 if (slot && slot->assigned && 1150 if (slot && slot->assigned &&
1151 slot->assigned->index == idx && ! strcmp(slot->assigned->name, str)) 1151 slot->assigned->index == idx && ! strcmp(slot->assigned->name, str))
@@ -1168,7 +1168,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
1168 kfree(tbl); 1168 kfree(tbl);
1169 } 1169 }
1170 __unlock: 1170 __unlock:
1171 up(&mixer->reg_mutex); 1171 mutex_unlock(&mixer->reg_mutex);
1172 } 1172 }
1173} 1173}
1174 1174
@@ -1288,7 +1288,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
1288 mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL); 1288 mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL);
1289 if (mixer == NULL) 1289 if (mixer == NULL)
1290 return -ENOMEM; 1290 return -ENOMEM;
1291 init_MUTEX(&mixer->reg_mutex); 1291 mutex_init(&mixer->reg_mutex);
1292 sprintf(name, "mixer%i%i", card->number, 0); 1292 sprintf(name, "mixer%i%i", card->number, 0);
1293 if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, 1293 if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
1294 card, 0, 1294 card, 0,
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
index 14f5578ec7a7..2eb18807e6d0 100644
--- a/sound/core/oss/mulaw.c
+++ b/sound/core/oss/mulaw.c
@@ -22,6 +22,9 @@
22 */ 22 */
23 23
24#include <sound/driver.h> 24#include <sound/driver.h>
25
26#ifdef CONFIG_SND_PCM_OSS_PLUGINS
27
25#include <linux/time.h> 28#include <linux/time.h>
26#include <sound/core.h> 29#include <sound/core.h>
27#include <sound/pcm.h> 30#include <sound/pcm.h>
@@ -262,6 +265,25 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
262 return frames; 265 return frames;
263} 266}
264 267
268static int getput_index(int format)
269{
270 int sign, width, endian;
271 sign = !snd_pcm_format_signed(format);
272 width = snd_pcm_format_width(format) / 8 - 1;
273 if (width < 0 || width > 3) {
274 snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
275 width = 0;
276 }
277#ifdef SNDRV_LITTLE_ENDIAN
278 endian = snd_pcm_format_big_endian(format);
279#else
280 endian = snd_pcm_format_little_endian(format);
281#endif
282 if (endian < 0)
283 endian = 0;
284 return width * 4 + endian * 2 + sign;
285}
286
265int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, 287int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
266 struct snd_pcm_plugin_format *src_format, 288 struct snd_pcm_plugin_format *src_format,
267 struct snd_pcm_plugin_format *dst_format, 289 struct snd_pcm_plugin_format *dst_format,
@@ -306,3 +328,5 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
306 *r_plugin = plugin; 328 *r_plugin = plugin;
307 return 0; 329 return 0;
308} 330}
331
332#endif
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 7fd072392c7e..f8302b703a30 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -78,6 +78,7 @@ static inline void snd_leave_user(mm_segment_t fs)
78 set_fs(fs); 78 set_fs(fs);
79} 79}
80 80
81#ifdef CONFIG_SND_PCM_OSS_PLUGINS
81static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) 82static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
82{ 83{
83 struct snd_pcm_runtime *runtime = substream->runtime; 84 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -122,6 +123,7 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin)
122 } 123 }
123 return 0; 124 return 0;
124} 125}
126#endif /* CONFIG_SND_PCM_OSS_PLUGINS */
125 127
126static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames) 128static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
127{ 129{
@@ -412,6 +414,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
412 oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * 414 oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
413 params_channels(params) / 8; 415 params_channels(params) / 8;
414 416
417#ifdef CONFIG_SND_PCM_OSS_PLUGINS
415 snd_pcm_oss_plugin_clear(substream); 418 snd_pcm_oss_plugin_clear(substream);
416 if (!direct) { 419 if (!direct) {
417 /* add necessary plugins */ 420 /* add necessary plugins */
@@ -441,6 +444,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
441 } 444 }
442 } 445 }
443 } 446 }
447#endif
444 448
445 err = snd_pcm_oss_period_size(substream, params, sparams); 449 err = snd_pcm_oss_period_size(substream, params, sparams);
446 if (err < 0) 450 if (err < 0)
@@ -498,11 +502,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
498 runtime->oss.periods = params_periods(sparams); 502 runtime->oss.periods = params_periods(sparams);
499 oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); 503 oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
500 snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); 504 snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure);
505#ifdef CONFIG_SND_PCM_OSS_PLUGINS
501 if (runtime->oss.plugin_first) { 506 if (runtime->oss.plugin_first) {
502 err = snd_pcm_plug_alloc(substream, oss_period_size); 507 err = snd_pcm_plug_alloc(substream, oss_period_size);
503 if (err < 0) 508 if (err < 0)
504 goto failure; 509 goto failure;
505 } 510 }
511#endif
506 oss_period_size *= oss_frame_size; 512 oss_period_size *= oss_frame_size;
507 513
508 oss_buffer_size = oss_period_size * runtime->oss.periods; 514 oss_buffer_size = oss_period_size * runtime->oss.periods;
@@ -784,6 +790,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
784{ 790{
785 struct snd_pcm_runtime *runtime = substream->runtime; 791 struct snd_pcm_runtime *runtime = substream->runtime;
786 snd_pcm_sframes_t frames, frames1; 792 snd_pcm_sframes_t frames, frames1;
793#ifdef CONFIG_SND_PCM_OSS_PLUGINS
787 if (runtime->oss.plugin_first) { 794 if (runtime->oss.plugin_first) {
788 struct snd_pcm_plugin_channel *channels; 795 struct snd_pcm_plugin_channel *channels;
789 size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; 796 size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
@@ -800,7 +807,9 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
800 if (frames1 <= 0) 807 if (frames1 <= 0)
801 return frames1; 808 return frames1;
802 bytes = frames1 * oss_frame_bytes; 809 bytes = frames1 * oss_frame_bytes;
803 } else { 810 } else
811#endif
812 {
804 frames = bytes_to_frames(runtime, bytes); 813 frames = bytes_to_frames(runtime, bytes);
805 frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel); 814 frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel);
806 if (frames1 <= 0) 815 if (frames1 <= 0)
@@ -871,6 +880,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
871{ 880{
872 struct snd_pcm_runtime *runtime = substream->runtime; 881 struct snd_pcm_runtime *runtime = substream->runtime;
873 snd_pcm_sframes_t frames, frames1; 882 snd_pcm_sframes_t frames, frames1;
883#ifdef CONFIG_SND_PCM_OSS_PLUGINS
874 char __user *final_dst = (char __user *)buf; 884 char __user *final_dst = (char __user *)buf;
875 if (runtime->oss.plugin_first) { 885 if (runtime->oss.plugin_first) {
876 struct snd_pcm_plugin_channel *channels; 886 struct snd_pcm_plugin_channel *channels;
@@ -887,7 +897,9 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
887 bytes = frames1 * oss_frame_bytes; 897 bytes = frames1 * oss_frame_bytes;
888 if (!in_kernel && copy_to_user(final_dst, buf, bytes)) 898 if (!in_kernel && copy_to_user(final_dst, buf, bytes))
889 return -EFAULT; 899 return -EFAULT;
890 } else { 900 } else
901#endif
902 {
891 frames = bytes_to_frames(runtime, bytes); 903 frames = bytes_to_frames(runtime, bytes);
892 frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel); 904 frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel);
893 if (frames1 <= 0) 905 if (frames1 <= 0)
@@ -1631,10 +1643,10 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm,
1631 const char *ptr, *ptrl; 1643 const char *ptr, *ptrl;
1632 struct snd_pcm_oss_setup *setup; 1644 struct snd_pcm_oss_setup *setup;
1633 1645
1634 down(&pcm->streams[stream].oss.setup_mutex); 1646 mutex_lock(&pcm->streams[stream].oss.setup_mutex);
1635 for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { 1647 for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
1636 if (!strcmp(setup->task_name, task_name)) { 1648 if (!strcmp(setup->task_name, task_name)) {
1637 up(&pcm->streams[stream].oss.setup_mutex); 1649 mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
1638 return setup; 1650 return setup;
1639 } 1651 }
1640 } 1652 }
@@ -1650,12 +1662,12 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm,
1650 } 1662 }
1651 for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { 1663 for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
1652 if (!strcmp(setup->task_name, ptrl)) { 1664 if (!strcmp(setup->task_name, ptrl)) {
1653 up(&pcm->streams[stream].oss.setup_mutex); 1665 mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
1654 return setup; 1666 return setup;
1655 } 1667 }
1656 } 1668 }
1657 __not_found: 1669 __not_found:
1658 up(&pcm->streams[stream].oss.setup_mutex); 1670 mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
1659 return NULL; 1671 return NULL;
1660} 1672}
1661 1673
@@ -1692,7 +1704,9 @@ static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
1692 struct snd_pcm_runtime *runtime; 1704 struct snd_pcm_runtime *runtime;
1693 runtime = substream->runtime; 1705 runtime = substream->runtime;
1694 vfree(runtime->oss.buffer); 1706 vfree(runtime->oss.buffer);
1707#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1695 snd_pcm_oss_plugin_clear(substream); 1708 snd_pcm_oss_plugin_clear(substream);
1709#endif
1696 substream->oss.file = NULL; 1710 substream->oss.file = NULL;
1697 substream->oss.oss = 0; 1711 substream->oss.oss = 0;
1698} 1712}
@@ -1881,7 +1895,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
1881 1895
1882 init_waitqueue_entry(&wait, current); 1896 init_waitqueue_entry(&wait, current);
1883 add_wait_queue(&pcm->open_wait, &wait); 1897 add_wait_queue(&pcm->open_wait, &wait);
1884 down(&pcm->open_mutex); 1898 mutex_lock(&pcm->open_mutex);
1885 while (1) { 1899 while (1) {
1886 err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, 1900 err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
1887 iminor(inode), psetup, csetup); 1901 iminor(inode), psetup, csetup);
@@ -1895,16 +1909,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
1895 } else 1909 } else
1896 break; 1910 break;
1897 set_current_state(TASK_INTERRUPTIBLE); 1911 set_current_state(TASK_INTERRUPTIBLE);
1898 up(&pcm->open_mutex); 1912 mutex_unlock(&pcm->open_mutex);
1899 schedule(); 1913 schedule();
1900 down(&pcm->open_mutex); 1914 mutex_lock(&pcm->open_mutex);
1901 if (signal_pending(current)) { 1915 if (signal_pending(current)) {
1902 err = -ERESTARTSYS; 1916 err = -ERESTARTSYS;
1903 break; 1917 break;
1904 } 1918 }
1905 } 1919 }
1906 remove_wait_queue(&pcm->open_wait, &wait); 1920 remove_wait_queue(&pcm->open_wait, &wait);
1907 up(&pcm->open_mutex); 1921 mutex_unlock(&pcm->open_mutex);
1908 if (err < 0) 1922 if (err < 0)
1909 goto __error; 1923 goto __error;
1910 return err; 1924 return err;
@@ -1930,9 +1944,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
1930 snd_assert(substream != NULL, return -ENXIO); 1944 snd_assert(substream != NULL, return -ENXIO);
1931 pcm = substream->pcm; 1945 pcm = substream->pcm;
1932 snd_pcm_oss_sync(pcm_oss_file); 1946 snd_pcm_oss_sync(pcm_oss_file);
1933 down(&pcm->open_mutex); 1947 mutex_lock(&pcm->open_mutex);
1934 snd_pcm_oss_release_file(pcm_oss_file); 1948 snd_pcm_oss_release_file(pcm_oss_file);
1935 up(&pcm->open_mutex); 1949 mutex_unlock(&pcm->open_mutex);
1936 wake_up(&pcm->open_wait); 1950 wake_up(&pcm->open_wait);
1937 module_put(pcm->card->module); 1951 module_put(pcm->card->module);
1938 snd_card_file_remove(pcm->card, file); 1952 snd_card_file_remove(pcm->card, file);
@@ -2246,8 +2260,10 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
2246 if ((err = snd_pcm_oss_change_params(substream)) < 0) 2260 if ((err = snd_pcm_oss_change_params(substream)) < 0)
2247 return err; 2261 return err;
2248 } 2262 }
2263#ifdef CONFIG_SND_PCM_OSS_PLUGINS
2249 if (runtime->oss.plugin_first != NULL) 2264 if (runtime->oss.plugin_first != NULL)
2250 return -EIO; 2265 return -EIO;
2266#endif
2251 2267
2252 if (area->vm_pgoff != 0) 2268 if (area->vm_pgoff != 0)
2253 return -EINVAL; 2269 return -EINVAL;
@@ -2277,7 +2293,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
2277{ 2293{
2278 struct snd_pcm_str *pstr = entry->private_data; 2294 struct snd_pcm_str *pstr = entry->private_data;
2279 struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; 2295 struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
2280 down(&pstr->oss.setup_mutex); 2296 mutex_lock(&pstr->oss.setup_mutex);
2281 while (setup) { 2297 while (setup) {
2282 snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", 2298 snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
2283 setup->task_name, 2299 setup->task_name,
@@ -2291,7 +2307,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
2291 setup->nosilence ? " no-silence" : ""); 2307 setup->nosilence ? " no-silence" : "");
2292 setup = setup->next; 2308 setup = setup->next;
2293 } 2309 }
2294 up(&pstr->oss.setup_mutex); 2310 mutex_unlock(&pstr->oss.setup_mutex);
2295} 2311}
2296 2312
2297static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) 2313static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
@@ -2321,12 +2337,12 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
2321 struct snd_pcm_oss_setup *setup, *setup1, template; 2337 struct snd_pcm_oss_setup *setup, *setup1, template;
2322 2338
2323 while (!snd_info_get_line(buffer, line, sizeof(line))) { 2339 while (!snd_info_get_line(buffer, line, sizeof(line))) {
2324 down(&pstr->oss.setup_mutex); 2340 mutex_lock(&pstr->oss.setup_mutex);
2325 memset(&template, 0, sizeof(template)); 2341 memset(&template, 0, sizeof(template));
2326 ptr = snd_info_get_str(task_name, line, sizeof(task_name)); 2342 ptr = snd_info_get_str(task_name, line, sizeof(task_name));
2327 if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { 2343 if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) {
2328 snd_pcm_oss_proc_free_setup_list(pstr); 2344 snd_pcm_oss_proc_free_setup_list(pstr);
2329 up(&pstr->oss.setup_mutex); 2345 mutex_unlock(&pstr->oss.setup_mutex);
2330 continue; 2346 continue;
2331 } 2347 }
2332 for (setup = pstr->oss.setup_list; setup; setup = setup->next) { 2348 for (setup = pstr->oss.setup_list; setup; setup = setup->next) {
@@ -2378,7 +2394,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
2378 } 2394 }
2379 if (setup) 2395 if (setup)
2380 *setup = template; 2396 *setup = template;
2381 up(&pstr->oss.setup_mutex); 2397 mutex_unlock(&pstr->oss.setup_mutex);
2382 } 2398 }
2383} 2399}
2384 2400
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 7e8676880dde..0e67dd280a5d 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -25,6 +25,9 @@
25#endif 25#endif
26 26
27#include <sound/driver.h> 27#include <sound/driver.h>
28
29#ifdef CONFIG_SND_PCM_OSS_PLUGINS
30
28#include <linux/slab.h> 31#include <linux/slab.h>
29#include <linux/time.h> 32#include <linux/time.h>
30#include <linux/vmalloc.h> 33#include <linux/vmalloc.h>
@@ -36,26 +39,6 @@
36#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first) 39#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
37#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last) 40#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)
38 41
39static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin,
40 unsigned long *dst_vmask,
41 unsigned long **src_vmask)
42{
43 unsigned long *vmask = plugin->src_vmask;
44 bitmap_copy(vmask, dst_vmask, plugin->src_format.channels);
45 *src_vmask = vmask;
46 return 0;
47}
48
49static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin,
50 unsigned long *src_vmask,
51 unsigned long **dst_vmask)
52{
53 unsigned long *vmask = plugin->dst_vmask;
54 bitmap_copy(vmask, src_vmask, plugin->dst_format.channels);
55 *dst_vmask = vmask;
56 return 0;
57}
58
59/* 42/*
60 * because some cards might have rates "very close", we ignore 43 * because some cards might have rates "very close", we ignore
61 * all "resampling" requests within +-5% 44 * all "resampling" requests within +-5%
@@ -193,19 +176,7 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
193 snd_pcm_plugin_free(plugin); 176 snd_pcm_plugin_free(plugin);
194 return -ENOMEM; 177 return -ENOMEM;
195 } 178 }
196 plugin->src_vmask = bitmap_alloc(src_format->channels);
197 if (plugin->src_vmask == NULL) {
198 snd_pcm_plugin_free(plugin);
199 return -ENOMEM;
200 }
201 plugin->dst_vmask = bitmap_alloc(dst_format->channels);
202 if (plugin->dst_vmask == NULL) {
203 snd_pcm_plugin_free(plugin);
204 return -ENOMEM;
205 }
206 plugin->client_channels = snd_pcm_plugin_client_channels; 179 plugin->client_channels = snd_pcm_plugin_client_channels;
207 plugin->src_channels_mask = snd_pcm_plugin_src_channels_mask;
208 plugin->dst_channels_mask = snd_pcm_plugin_dst_channels_mask;
209 *ret = plugin; 180 *ret = plugin;
210 return 0; 181 return 0;
211} 182}
@@ -218,8 +189,6 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
218 plugin->private_free(plugin); 189 plugin->private_free(plugin);
219 kfree(plugin->buf_channels); 190 kfree(plugin->buf_channels);
220 vfree(plugin->buf); 191 vfree(plugin->buf);
221 kfree(plugin->src_vmask);
222 kfree(plugin->dst_vmask);
223 kfree(plugin); 192 kfree(plugin);
224 return 0; 193 return 0;
225} 194}
@@ -429,24 +398,14 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
429 dstformat.channels); 398 dstformat.channels);
430 399
431 /* Format change (linearization) */ 400 /* Format change (linearization) */
432 if ((srcformat.format != dstformat.format || 401 if (! rate_match(srcformat.rate, dstformat.rate) &&
433 !rate_match(srcformat.rate, dstformat.rate) || 402 ! snd_pcm_format_linear(srcformat.format)) {
434 srcformat.channels != dstformat.channels) && 403 if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW)
435 !snd_pcm_format_linear(srcformat.format)) {
436 if (snd_pcm_format_linear(dstformat.format))
437 tmpformat.format = dstformat.format;
438 else
439 tmpformat.format = SNDRV_PCM_FORMAT_S16;
440 switch (srcformat.format) {
441 case SNDRV_PCM_FORMAT_MU_LAW:
442 err = snd_pcm_plugin_build_mulaw(plug,
443 &srcformat, &tmpformat,
444 &plugin);
445 break;
446 default:
447 return -EINVAL; 404 return -EINVAL;
448 } 405 tmpformat.format = SNDRV_PCM_FORMAT_S16;
449 pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err); 406 err = snd_pcm_plugin_build_mulaw(plug,
407 &srcformat, &tmpformat,
408 &plugin);
450 if (err < 0) 409 if (err < 0)
451 return err; 410 return err;
452 err = snd_pcm_plugin_append(plugin); 411 err = snd_pcm_plugin_append(plugin);
@@ -460,35 +419,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
460 419
461 /* channels reduction */ 420 /* channels reduction */
462 if (srcformat.channels > dstformat.channels) { 421 if (srcformat.channels > dstformat.channels) {
463 int sv = srcformat.channels;
464 int dv = dstformat.channels;
465 int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
466 if (ttable == NULL)
467 return -ENOMEM;
468#if 1
469 if (sv == 2 && dv == 1) {
470 ttable[0] = HALF;
471 ttable[1] = HALF;
472 } else
473#endif
474 {
475 int v;
476 for (v = 0; v < dv; ++v)
477 ttable[v * sv + v] = FULL;
478 }
479 tmpformat.channels = dstformat.channels; 422 tmpformat.channels = dstformat.channels;
480 if (rate_match(srcformat.rate, dstformat.rate) && 423 err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
481 snd_pcm_format_linear(dstformat.format))
482 tmpformat.format = dstformat.format;
483 err = snd_pcm_plugin_build_route(plug,
484 &srcformat, &tmpformat,
485 ttable, &plugin);
486 kfree(ttable);
487 pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); 424 pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
488 if (err < 0) { 425 if (err < 0)
489 snd_pcm_plugin_free(plugin);
490 return err; 426 return err;
491 }
492 err = snd_pcm_plugin_append(plugin); 427 err = snd_pcm_plugin_append(plugin);
493 if (err < 0) { 428 if (err < 0) {
494 snd_pcm_plugin_free(plugin); 429 snd_pcm_plugin_free(plugin);
@@ -500,18 +435,29 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
500 435
501 /* rate resampling */ 436 /* rate resampling */
502 if (!rate_match(srcformat.rate, dstformat.rate)) { 437 if (!rate_match(srcformat.rate, dstformat.rate)) {
438 if (srcformat.format != SNDRV_PCM_FORMAT_S16) {
439 /* convert to S16 for resampling */
440 tmpformat.format = SNDRV_PCM_FORMAT_S16;
441 err = snd_pcm_plugin_build_linear(plug,
442 &srcformat, &tmpformat,
443 &plugin);
444 if (err < 0)
445 return err;
446 err = snd_pcm_plugin_append(plugin);
447 if (err < 0) {
448 snd_pcm_plugin_free(plugin);
449 return err;
450 }
451 srcformat = tmpformat;
452 src_access = dst_access;
453 }
503 tmpformat.rate = dstformat.rate; 454 tmpformat.rate = dstformat.rate;
504 if (srcformat.channels == dstformat.channels &&
505 snd_pcm_format_linear(dstformat.format))
506 tmpformat.format = dstformat.format;
507 err = snd_pcm_plugin_build_rate(plug, 455 err = snd_pcm_plugin_build_rate(plug,
508 &srcformat, &tmpformat, 456 &srcformat, &tmpformat,
509 &plugin); 457 &plugin);
510 pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err); 458 pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err);
511 if (err < 0) { 459 if (err < 0)
512 snd_pcm_plugin_free(plugin);
513 return err; 460 return err;
514 }
515 err = snd_pcm_plugin_append(plugin); 461 err = snd_pcm_plugin_append(plugin);
516 if (err < 0) { 462 if (err < 0) {
517 snd_pcm_plugin_free(plugin); 463 snd_pcm_plugin_free(plugin);
@@ -521,56 +467,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
521 src_access = dst_access; 467 src_access = dst_access;
522 } 468 }
523 469
524 /* channels extension */
525 if (srcformat.channels < dstformat.channels) {
526 int sv = srcformat.channels;
527 int dv = dstformat.channels;
528 int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
529 if (ttable == NULL)
530 return -ENOMEM;
531#if 0
532 {
533 int v;
534 for (v = 0; v < sv; ++v)
535 ttable[v * sv + v] = FULL;
536 }
537#else
538 {
539 /* Playback is spreaded on all channels */
540 int vd, vs;
541 for (vd = 0, vs = 0; vd < dv; ++vd) {
542 ttable[vd * sv + vs] = FULL;
543 vs++;
544 if (vs == sv)
545 vs = 0;
546 }
547 }
548#endif
549 tmpformat.channels = dstformat.channels;
550 if (snd_pcm_format_linear(dstformat.format))
551 tmpformat.format = dstformat.format;
552 err = snd_pcm_plugin_build_route(plug,
553 &srcformat, &tmpformat,
554 ttable, &plugin);
555 kfree(ttable);
556 pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
557 if (err < 0) {
558 snd_pcm_plugin_free(plugin);
559 return err;
560 }
561 err = snd_pcm_plugin_append(plugin);
562 if (err < 0) {
563 snd_pcm_plugin_free(plugin);
564 return err;
565 }
566 srcformat = tmpformat;
567 src_access = dst_access;
568 }
569
570 /* format change */ 470 /* format change */
571 if (srcformat.format != dstformat.format) { 471 if (srcformat.format != dstformat.format) {
572 tmpformat.format = dstformat.format; 472 tmpformat.format = dstformat.format;
573 if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { 473 if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW ||
474 tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {
574 err = snd_pcm_plugin_build_mulaw(plug, 475 err = snd_pcm_plugin_build_mulaw(plug,
575 &srcformat, &tmpformat, 476 &srcformat, &tmpformat,
576 &plugin); 477 &plugin);
@@ -595,6 +496,22 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
595 src_access = dst_access; 496 src_access = dst_access;
596 } 497 }
597 498
499 /* channels extension */
500 if (srcformat.channels < dstformat.channels) {
501 tmpformat.channels = dstformat.channels;
502 err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
503 pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
504 if (err < 0)
505 return err;
506 err = snd_pcm_plugin_append(plugin);
507 if (err < 0) {
508 snd_pcm_plugin_free(plugin);
509 return err;
510 }
511 srcformat = tmpformat;
512 src_access = dst_access;
513 }
514
598 /* de-interleave */ 515 /* de-interleave */
599 if (src_access != dst_access) { 516 if (src_access != dst_access) {
600 err = snd_pcm_plugin_build_copy(plug, 517 err = snd_pcm_plugin_build_copy(plug,
@@ -650,92 +567,6 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
650 return count; 567 return count;
651} 568}
652 569
653static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug,
654 unsigned long *client_vmask)
655{
656 struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
657 if (plugin == NULL) {
658 return 0;
659 } else {
660 int schannels = plugin->dst_format.channels;
661 DECLARE_BITMAP(bs, schannels);
662 unsigned long *srcmask;
663 unsigned long *dstmask = bs;
664 int err;
665 bitmap_fill(dstmask, schannels);
666
667 while (1) {
668 err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
669 if (err < 0)
670 return err;
671 dstmask = srcmask;
672 if (plugin->prev == NULL)
673 break;
674 plugin = plugin->prev;
675 }
676 bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels);
677 return 0;
678 }
679}
680
681static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug,
682 struct snd_pcm_plugin_channel *src_channels)
683{
684 struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
685 unsigned int nchannels = plugin->src_format.channels;
686 DECLARE_BITMAP(bs, nchannels);
687 unsigned long *srcmask = bs;
688 int err;
689 unsigned int channel;
690 for (channel = 0; channel < nchannels; channel++) {
691 if (src_channels[channel].enabled)
692 set_bit(channel, srcmask);
693 else
694 clear_bit(channel, srcmask);
695 }
696 err = snd_pcm_plug_playback_channels_mask(plug, srcmask);
697 if (err < 0)
698 return err;
699 for (channel = 0; channel < nchannels; channel++) {
700 if (!test_bit(channel, srcmask))
701 src_channels[channel].enabled = 0;
702 }
703 return 0;
704}
705
706static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug,
707 struct snd_pcm_plugin_channel *src_channels,
708 struct snd_pcm_plugin_channel *client_channels)
709{
710 struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
711 unsigned int nchannels = plugin->dst_format.channels;
712 DECLARE_BITMAP(bs, nchannels);
713 unsigned long *dstmask = bs;
714 unsigned long *srcmask;
715 int err;
716 unsigned int channel;
717 for (channel = 0; channel < nchannels; channel++) {
718 if (client_channels[channel].enabled)
719 set_bit(channel, dstmask);
720 else
721 clear_bit(channel, dstmask);
722 }
723 while (plugin) {
724 err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
725 if (err < 0)
726 return err;
727 dstmask = srcmask;
728 plugin = plugin->prev;
729 }
730 plugin = snd_pcm_plug_first(plug);
731 nchannels = plugin->src_format.channels;
732 for (channel = 0; channel < nchannels; channel++) {
733 if (!test_bit(channel, dstmask))
734 src_channels[channel].enabled = 0;
735 }
736 return 0;
737}
738
739snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size) 570snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size)
740{ 571{
741 struct snd_pcm_plugin *plugin, *next; 572 struct snd_pcm_plugin *plugin, *next;
@@ -743,9 +574,6 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st
743 int err; 574 int err;
744 snd_pcm_sframes_t frames = size; 575 snd_pcm_sframes_t frames = size;
745 576
746 if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0)
747 return err;
748
749 plugin = snd_pcm_plug_first(plug); 577 plugin = snd_pcm_plug_first(plug);
750 while (plugin && frames > 0) { 578 while (plugin && frames > 0) {
751 if ((next = plugin->next) != NULL) { 579 if ((next = plugin->next) != NULL) {
@@ -790,10 +618,6 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str
790 return err; 618 return err;
791 } 619 }
792 frames = err; 620 frames = err;
793 if (!plugin->prev) {
794 if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0)
795 return err;
796 }
797 } else { 621 } else {
798 dst_channels = dst_channels_final; 622 dst_channels = dst_channels_final;
799 } 623 }
@@ -916,3 +740,5 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of
916 } 740 }
917 return 0; 741 return 0;
918} 742}
743
744#endif
diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
index 29198da615cd..3be91b3d5377 100644
--- a/sound/core/oss/pcm_plugin.h
+++ b/sound/core/oss/pcm_plugin.h
@@ -22,12 +22,7 @@
22 * 22 *
23 */ 23 */
24 24
25#include <linux/bitmap.h> 25#ifdef CONFIG_SND_PCM_OSS_PLUGINS
26
27static inline unsigned long *bitmap_alloc(unsigned int nbits)
28{
29 return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL);
30}
31 26
32#define snd_pcm_plug_stream(plug) ((plug)->stream) 27#define snd_pcm_plug_stream(plug) ((plug)->stream)
33 28
@@ -69,12 +64,6 @@ struct snd_pcm_plugin {
69 snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin, 64 snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
70 snd_pcm_uframes_t frames, 65 snd_pcm_uframes_t frames,
71 struct snd_pcm_plugin_channel **channels); 66 struct snd_pcm_plugin_channel **channels);
72 int (*src_channels_mask)(struct snd_pcm_plugin *plugin,
73 unsigned long *dst_vmask,
74 unsigned long **src_vmask);
75 int (*dst_channels_mask)(struct snd_pcm_plugin *plugin,
76 unsigned long *src_vmask,
77 unsigned long **dst_vmask);
78 snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin, 67 snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin,
79 const struct snd_pcm_plugin_channel *src_channels, 68 const struct snd_pcm_plugin_channel *src_channels,
80 struct snd_pcm_plugin_channel *dst_channels, 69 struct snd_pcm_plugin_channel *dst_channels,
@@ -90,8 +79,6 @@ struct snd_pcm_plugin {
90 char *buf; 79 char *buf;
91 snd_pcm_uframes_t buf_frames; 80 snd_pcm_uframes_t buf_frames;
92 struct snd_pcm_plugin_channel *buf_channels; 81 struct snd_pcm_plugin_channel *buf_channels;
93 unsigned long *src_vmask;
94 unsigned long *dst_vmask;
95 char extra_data[0]; 82 char extra_data[0];
96}; 83};
97 84
@@ -128,7 +115,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle,
128int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle, 115int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle,
129 struct snd_pcm_plugin_format *src_format, 116 struct snd_pcm_plugin_format *src_format,
130 struct snd_pcm_plugin_format *dst_format, 117 struct snd_pcm_plugin_format *dst_format,
131 int *ttable,
132 struct snd_pcm_plugin **r_plugin); 118 struct snd_pcm_plugin **r_plugin);
133int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle, 119int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle,
134 struct snd_pcm_plugin_format *src_format, 120 struct snd_pcm_plugin_format *src_format,
@@ -181,15 +167,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
181 void **bufs, snd_pcm_uframes_t frames, 167 void **bufs, snd_pcm_uframes_t frames,
182 int in_kernel); 168 int in_kernel);
183 169
184#define ROUTE_PLUGIN_RESOLUTION 16 170#else
185 171
186int getput_index(int format); 172static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
187int copy_index(int format); 173static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
188int conv_index(int src_format, int dst_format); 174static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; }
189 175
190void zero_channel(struct snd_pcm_plugin *plugin, 176#endif
191 const struct snd_pcm_plugin_channel *dst_channel,
192 size_t samples);
193 177
194#ifdef PLUGIN_DEBUG 178#ifdef PLUGIN_DEBUG
195#define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args) 179#define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args)
diff --git a/sound/core/oss/plugin_ops.h b/sound/core/oss/plugin_ops.h
index 0607e9566084..1f5bde4631f1 100644
--- a/sound/core/oss/plugin_ops.h
+++ b/sound/core/oss/plugin_ops.h
@@ -362,172 +362,6 @@ put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_
362} 362}
363#endif 363#endif
364 364
365#if 0
366#ifdef GET32_LABELS
367/* src_wid src_endswap unsigned */
368static void *get32_labels[4 * 2 * 2] = {
369 &&get32_xxx1_1000, /* 8h -> 32h */
370 &&get32_xxx1_9000, /* 8h ^> 32h */
371 &&get32_xxx1_1000, /* 8s -> 32h */
372 &&get32_xxx1_9000, /* 8s ^> 32h */
373 &&get32_xx12_1200, /* 16h -> 32h */
374 &&get32_xx12_9200, /* 16h ^> 32h */
375 &&get32_xx12_2100, /* 16s -> 32h */
376 &&get32_xx12_A100, /* 16s ^> 32h */
377 &&get32_x123_1230, /* 24h -> 32h */
378 &&get32_x123_9230, /* 24h ^> 32h */
379 &&get32_123x_3210, /* 24s -> 32h */
380 &&get32_123x_B210, /* 24s ^> 32h */
381 &&get32_1234_1234, /* 32h -> 32h */
382 &&get32_1234_9234, /* 32h ^> 32h */
383 &&get32_1234_4321, /* 32s -> 32h */
384 &&get32_1234_C321, /* 32s ^> 32h */
385};
386#endif
387
388#ifdef GET32_END
389while (0) {
390get32_xxx1_1000: sample = (u_int32_t)as_u8(src) << 24; goto GET32_END;
391get32_xxx1_9000: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto GET32_END;
392get32_xx12_1200: sample = (u_int32_t)as_u16(src) << 16; goto GET32_END;
393get32_xx12_9200: sample = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto GET32_END;
394get32_xx12_2100: sample = (u_int32_t)swab16(as_u16(src)) << 16; goto GET32_END;
395get32_xx12_A100: sample = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto GET32_END;
396get32_x123_1230: sample = as_u32(src) << 8; goto GET32_END;
397get32_x123_9230: sample = (as_u32(src) << 8) ^ 0x80000000; goto GET32_END;
398get32_123x_3210: sample = swab32(as_u32(src) >> 8); goto GET32_END;
399get32_123x_B210: sample = swab32((as_u32(src) >> 8) ^ 0x80); goto GET32_END;
400get32_1234_1234: sample = as_u32(src); goto GET32_END;
401get32_1234_9234: sample = as_u32(src) ^ 0x80000000; goto GET32_END;
402get32_1234_4321: sample = swab32(as_u32(src)); goto GET32_END;
403get32_1234_C321: sample = swab32(as_u32(src) ^ 0x80); goto GET32_END;
404}
405#endif
406#endif
407
408#ifdef PUT_U32_LABELS
409/* dst_wid dst_endswap unsigned */
410static void *put_u32_labels[4 * 2 * 2] = {
411 &&put_u32_1234_xxx9, /* u32h -> s8h */
412 &&put_u32_1234_xxx1, /* u32h -> u8h */
413 &&put_u32_1234_xxx9, /* u32h -> s8s */
414 &&put_u32_1234_xxx1, /* u32h -> u8s */
415 &&put_u32_1234_xx92, /* u32h -> s16h */
416 &&put_u32_1234_xx12, /* u32h -> u16h */
417 &&put_u32_1234_xx29, /* u32h -> s16s */
418 &&put_u32_1234_xx21, /* u32h -> u16s */
419 &&put_u32_1234_x923, /* u32h -> s24h */
420 &&put_u32_1234_x123, /* u32h -> u24h */
421 &&put_u32_1234_329x, /* u32h -> s24s */
422 &&put_u32_1234_321x, /* u32h -> u24s */
423 &&put_u32_1234_9234, /* u32h -> s32h */
424 &&put_u32_1234_1234, /* u32h -> u32h */
425 &&put_u32_1234_4329, /* u32h -> s32s */
426 &&put_u32_1234_4321, /* u32h -> u32s */
427};
428#endif
429
430#ifdef PUT_U32_END
431while (0) {
432put_u32_1234_xxx1: as_u8(dst) = sample >> 24; goto PUT_U32_END;
433put_u32_1234_xxx9: as_u8(dst) = (sample >> 24) ^ 0x80; goto PUT_U32_END;
434put_u32_1234_xx12: as_u16(dst) = sample >> 16; goto PUT_U32_END;
435put_u32_1234_xx92: as_u16(dst) = (sample >> 16) ^ 0x8000; goto PUT_U32_END;
436put_u32_1234_xx21: as_u16(dst) = swab16(sample >> 16); goto PUT_U32_END;
437put_u32_1234_xx29: as_u16(dst) = swab16(sample >> 16) ^ 0x80; goto PUT_U32_END;
438put_u32_1234_x123: as_u32(dst) = sample >> 8; goto PUT_U32_END;
439put_u32_1234_x923: as_u32(dst) = (sample >> 8) ^ 0x800000; goto PUT_U32_END;
440put_u32_1234_321x: as_u32(dst) = swab32(sample) << 8; goto PUT_U32_END;
441put_u32_1234_329x: as_u32(dst) = (swab32(sample) ^ 0x80) << 8; goto PUT_U32_END;
442put_u32_1234_1234: as_u32(dst) = sample; goto PUT_U32_END;
443put_u32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_U32_END;
444put_u32_1234_4321: as_u32(dst) = swab32(sample); goto PUT_U32_END;
445put_u32_1234_4329: as_u32(dst) = swab32(sample) ^ 0x80; goto PUT_U32_END;
446}
447#endif
448
449#ifdef GET_U_LABELS
450/* width endswap unsigned*/
451static void *get_u_labels[4 * 2 * 2] = {
452 &&get_u_s8, /* s8 -> u8 */
453 &&get_u_u8, /* u8 -> u8 */
454 &&get_u_s8, /* s8 -> u8 */
455 &&get_u_u8, /* u8 -> u8 */
456 &&get_u_s16h, /* s16h -> u16h */
457 &&get_u_u16h, /* u16h -> u16h */
458 &&get_u_s16s, /* s16s -> u16h */
459 &&get_u_u16s, /* u16s -> u16h */
460 &&get_u_s24h, /* s24h -> u32h */
461 &&get_u_u24h, /* u24h -> u32h */
462 &&get_u_s24s, /* s24s -> u32h */
463 &&get_u_u24s, /* u24s -> u32h */
464 &&get_u_s32h, /* s32h -> u32h */
465 &&get_u_u32h, /* u32h -> u32h */
466 &&get_u_s32s, /* s32s -> u32h */
467 &&get_u_u32s, /* u32s -> u32h */
468};
469#endif
470
471#ifdef GET_U_END
472while (0) {
473get_u_s8: sample = as_u8(src) ^ 0x80; goto GET_U_END;
474get_u_u8: sample = as_u8(src); goto GET_U_END;
475get_u_s16h: sample = as_u16(src) ^ 0x8000; goto GET_U_END;
476get_u_u16h: sample = as_u16(src); goto GET_U_END;
477get_u_s16s: sample = swab16(as_u16(src) ^ 0x80); goto GET_U_END;
478get_u_u16s: sample = swab16(as_u16(src)); goto GET_U_END;
479get_u_s24h: sample = (as_u32(src) ^ 0x800000); goto GET_U_END;
480get_u_u24h: sample = as_u32(src); goto GET_U_END;
481get_u_s24s: sample = swab32(as_u32(src) ^ 0x800000); goto GET_U_END;
482get_u_u24s: sample = swab32(as_u32(src)); goto GET_U_END;
483get_u_s32h: sample = as_u32(src) ^ 0x80000000; goto GET_U_END;
484get_u_u32h: sample = as_u32(src); goto GET_U_END;
485get_u_s32s: sample = swab32(as_u32(src) ^ 0x80); goto GET_U_END;
486get_u_u32s: sample = swab32(as_u32(src)); goto GET_U_END;
487}
488#endif
489
490#if 0
491#ifdef PUT_LABELS
492/* width endswap unsigned */
493static void *put_labels[4 * 2 * 2] = {
494 &&put_s8, /* s8 -> s8 */
495 &&put_u8, /* u8 -> s8 */
496 &&put_s8, /* s8 -> s8 */
497 &&put_u8, /* u8 -> s8 */
498 &&put_s16h, /* s16h -> s16h */
499 &&put_u16h, /* u16h -> s16h */
500 &&put_s16s, /* s16s -> s16h */
501 &&put_u16s, /* u16s -> s16h */
502 &&put_s24h, /* s24h -> s32h */
503 &&put_u24h, /* u24h -> s32h */
504 &&put_s24s, /* s24s -> s32h */
505 &&put_u24s, /* u24s -> s32h */
506 &&put_s32h, /* s32h -> s32h */
507 &&put_u32h, /* u32h -> s32h */
508 &&put_s32s, /* s32s -> s32h */
509 &&put_u32s, /* u32s -> s32h */
510};
511#endif
512
513#ifdef PUT_END
514put_s8: as_s8(dst) = sample; goto PUT_END;
515put_u8: as_u8(dst) = sample ^ 0x80; goto PUT_END;
516put_s16h: as_s16(dst) = sample; goto PUT_END;
517put_u16h: as_u16(dst) = sample ^ 0x8000; goto PUT_END;
518put_s16s: as_s16(dst) = swab16(sample); goto PUT_END;
519put_u16s: as_u16(dst) = swab16(sample ^ 0x80); goto PUT_END;
520put_s24h: as_s24(dst) = sample & 0xffffff; goto PUT_END;
521put_u24h: as_u24(dst) = sample ^ 0x80000000; goto PUT_END;
522put_s24s: as_s24(dst) = swab32(sample & 0xffffff); goto PUT_END;
523put_u24s: as_u24(dst) = swab32(sample ^ 0x80); goto PUT_END;
524put_s32h: as_s32(dst) = sample; goto PUT_END;
525put_u32h: as_u32(dst) = sample ^ 0x80000000; goto PUT_END;
526put_s32s: as_s32(dst) = swab32(sample); goto PUT_END;
527put_u32s: as_u32(dst) = swab32(sample ^ 0x80); goto PUT_END;
528#endif
529#endif
530
531#undef as_u8 365#undef as_u8
532#undef as_u16 366#undef as_u16
533#undef as_u32 367#undef as_u32
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c
index 4854cef6fb4f..18d8a0f4e816 100644
--- a/sound/core/oss/rate.c
+++ b/sound/core/oss/rate.c
@@ -20,6 +20,9 @@
20 */ 20 */
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23
24#ifdef CONFIG_SND_PCM_OSS_PLUGINS
25
23#include <linux/time.h> 26#include <linux/time.h>
24#include <sound/core.h> 27#include <sound/core.h>
25#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -47,7 +50,6 @@ struct rate_priv {
47 unsigned int pitch; 50 unsigned int pitch;
48 unsigned int pos; 51 unsigned int pos;
49 rate_f func; 52 rate_f func;
50 int get, put;
51 snd_pcm_sframes_t old_src_frames, old_dst_frames; 53 snd_pcm_sframes_t old_src_frames, old_dst_frames;
52 struct rate_channel channels[0]; 54 struct rate_channel channels[0];
53}; 55};
@@ -71,21 +73,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
71 unsigned int pos = 0; 73 unsigned int pos = 0;
72 signed int val; 74 signed int val;
73 signed short S1, S2; 75 signed short S1, S2;
74 char *src, *dst; 76 signed short *src, *dst;
75 unsigned int channel; 77 unsigned int channel;
76 int src_step, dst_step; 78 int src_step, dst_step;
77 int src_frames1, dst_frames1; 79 int src_frames1, dst_frames1;
78 struct rate_priv *data = (struct rate_priv *)plugin->extra_data; 80 struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
79 struct rate_channel *rchannels = data->channels; 81 struct rate_channel *rchannels = data->channels;
80
81#define GET_S16_LABELS
82#define PUT_S16_LABELS
83#include "plugin_ops.h"
84#undef GET_S16_LABELS
85#undef PUT_S16_LABELS
86 void *get = get_s16_labels[data->get];
87 void *put = put_s16_labels[data->put];
88 signed short sample = 0;
89 82
90 for (channel = 0; channel < plugin->src_format.channels; channel++) { 83 for (channel = 0; channel < plugin->src_format.channels; channel++) {
91 pos = data->pos; 84 pos = data->pos;
@@ -98,10 +91,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
98 continue; 91 continue;
99 } 92 }
100 dst_channels[channel].enabled = 1; 93 dst_channels[channel].enabled = 1;
101 src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; 94 src = (signed short *)src_channels[channel].area.addr +
102 dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; 95 src_channels[channel].area.first / 8 / 2;
103 src_step = src_channels[channel].area.step / 8; 96 dst = (signed short *)dst_channels[channel].area.addr +
104 dst_step = dst_channels[channel].area.step / 8; 97 dst_channels[channel].area.first / 8 / 2;
98 src_step = src_channels[channel].area.step / 8 / 2;
99 dst_step = dst_channels[channel].area.step / 8 / 2;
105 src_frames1 = src_frames; 100 src_frames1 = src_frames;
106 dst_frames1 = dst_frames; 101 dst_frames1 = dst_frames;
107 while (dst_frames1-- > 0) { 102 while (dst_frames1-- > 0) {
@@ -109,12 +104,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
109 pos &= R_MASK; 104 pos &= R_MASK;
110 S1 = S2; 105 S1 = S2;
111 if (src_frames1-- > 0) { 106 if (src_frames1-- > 0) {
112 goto *get; 107 S2 = *src;
113#define GET_S16_END after_get
114#include "plugin_ops.h"
115#undef GET_S16_END
116 after_get:
117 S2 = sample;
118 src += src_step; 108 src += src_step;
119 } 109 }
120 } 110 }
@@ -123,12 +113,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
123 val = -32768; 113 val = -32768;
124 else if (val > 32767) 114 else if (val > 32767)
125 val = 32767; 115 val = 32767;
126 sample = val; 116 *dst = val;
127 goto *put;
128#define PUT_S16_END after_put
129#include "plugin_ops.h"
130#undef PUT_S16_END
131 after_put:
132 dst += dst_step; 117 dst += dst_step;
133 pos += data->pitch; 118 pos += data->pitch;
134 } 119 }
@@ -147,21 +132,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
147 unsigned int pos = 0; 132 unsigned int pos = 0;
148 signed int val; 133 signed int val;
149 signed short S1, S2; 134 signed short S1, S2;
150 char *src, *dst; 135 signed short *src, *dst;
151 unsigned int channel; 136 unsigned int channel;
152 int src_step, dst_step; 137 int src_step, dst_step;
153 int src_frames1, dst_frames1; 138 int src_frames1, dst_frames1;
154 struct rate_priv *data = (struct rate_priv *)plugin->extra_data; 139 struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
155 struct rate_channel *rchannels = data->channels; 140 struct rate_channel *rchannels = data->channels;
156
157#define GET_S16_LABELS
158#define PUT_S16_LABELS
159#include "plugin_ops.h"
160#undef GET_S16_LABELS
161#undef PUT_S16_LABELS
162 void *get = get_s16_labels[data->get];
163 void *put = put_s16_labels[data->put];
164 signed short sample = 0;
165 141
166 for (channel = 0; channel < plugin->src_format.channels; ++channel) { 142 for (channel = 0; channel < plugin->src_format.channels; ++channel) {
167 pos = data->pos; 143 pos = data->pos;
@@ -174,21 +150,18 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
174 continue; 150 continue;
175 } 151 }
176 dst_channels[channel].enabled = 1; 152 dst_channels[channel].enabled = 1;
177 src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; 153 src = (signed short *)src_channels[channel].area.addr +
178 dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; 154 src_channels[channel].area.first / 8 / 2;
179 src_step = src_channels[channel].area.step / 8; 155 dst = (signed short *)dst_channels[channel].area.addr +
180 dst_step = dst_channels[channel].area.step / 8; 156 dst_channels[channel].area.first / 8 / 2;
157 src_step = src_channels[channel].area.step / 8 / 2;
158 dst_step = dst_channels[channel].area.step / 8 / 2;
181 src_frames1 = src_frames; 159 src_frames1 = src_frames;
182 dst_frames1 = dst_frames; 160 dst_frames1 = dst_frames;
183 while (dst_frames1 > 0) { 161 while (dst_frames1 > 0) {
184 S1 = S2; 162 S1 = S2;
185 if (src_frames1-- > 0) { 163 if (src_frames1-- > 0) {
186 goto *get; 164 S1 = *src;
187#define GET_S16_END after_get
188#include "plugin_ops.h"
189#undef GET_S16_END
190 after_get:
191 S2 = sample;
192 src += src_step; 165 src += src_step;
193 } 166 }
194 if (pos & ~R_MASK) { 167 if (pos & ~R_MASK) {
@@ -198,12 +171,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
198 val = -32768; 171 val = -32768;
199 else if (val > 32767) 172 else if (val > 32767)
200 val = 32767; 173 val = 32767;
201 sample = val; 174 *dst = val;
202 goto *put;
203#define PUT_S16_END after_put
204#include "plugin_ops.h"
205#undef PUT_S16_END
206 after_put:
207 dst += dst_step; 175 dst += dst_step;
208 dst_frames1--; 176 dst_frames1--;
209 } 177 }
@@ -343,8 +311,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
343 311
344 snd_assert(src_format->channels == dst_format->channels, return -ENXIO); 312 snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
345 snd_assert(src_format->channels > 0, return -ENXIO); 313 snd_assert(src_format->channels > 0, return -ENXIO);
346 snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO); 314 snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
347 snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO); 315 snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
348 snd_assert(src_format->rate != dst_format->rate, return -ENXIO); 316 snd_assert(src_format->rate != dst_format->rate, return -ENXIO);
349 317
350 err = snd_pcm_plugin_build(plug, "rate conversion", 318 err = snd_pcm_plugin_build(plug, "rate conversion",
@@ -355,11 +323,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
355 if (err < 0) 323 if (err < 0)
356 return err; 324 return err;
357 data = (struct rate_priv *)plugin->extra_data; 325 data = (struct rate_priv *)plugin->extra_data;
358 data->get = getput_index(src_format->format);
359 snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
360 data->put = getput_index(dst_format->format);
361 snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL);
362
363 if (src_format->rate < dst_format->rate) { 326 if (src_format->rate < dst_format->rate) {
364 data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; 327 data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate;
365 data->func = resample_expand; 328 data->func = resample_expand;
@@ -377,3 +340,5 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
377 *r_plugin = plugin; 340 *r_plugin = plugin;
378 return 0; 341 return 0;
379} 342}
343
344#endif
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index 726c5caa3fdb..46917dc0196b 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Attenuated route Plug-In 2 * Route Plug-In
3 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> 3 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
4 * 4 *
5 * 5 *
@@ -20,502 +20,93 @@
20 */ 20 */
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23
24#ifdef CONFIG_SND_PCM_OSS_PLUGINS
25
23#include <linux/slab.h> 26#include <linux/slab.h>
24#include <linux/time.h> 27#include <linux/time.h>
25#include <sound/core.h> 28#include <sound/core.h>
26#include <sound/pcm.h> 29#include <sound/pcm.h>
27#include "pcm_plugin.h" 30#include "pcm_plugin.h"
28 31
29/* The best possible hack to support missing optimization in gcc 2.7.2.3 */ 32static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
30#if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0 33 snd_pcm_uframes_t frames, int format)
31#define div(a) a /= ROUTE_PLUGIN_RESOLUTION
32#elif ROUTE_PLUGIN_RESOLUTION == 16
33#define div(a) a >>= 4
34#else
35#error "Add some code here"
36#endif
37
38struct ttable_dst;
39
40typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin,
41 const struct snd_pcm_plugin_channel *src_channels,
42 struct snd_pcm_plugin_channel *dst_channel,
43 struct ttable_dst *ttable, snd_pcm_uframes_t frames);
44
45struct ttable_src {
46 int channel;
47 int as_int;
48};
49
50struct ttable_dst {
51 int att; /* Attenuated */
52 unsigned int nsrcs;
53 struct ttable_src *srcs;
54 route_channel_f func;
55};
56
57struct route_priv {
58 enum {R_UINT32=0, R_UINT64=1} sum_type;
59 int get, put;
60 int conv;
61 int src_sample_size;
62 struct ttable_dst ttable[0];
63};
64
65union sum {
66 u_int32_t as_uint32;
67 u_int64_t as_uint64;
68};
69
70
71static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin,
72 const struct snd_pcm_plugin_channel *src_channels,
73 struct snd_pcm_plugin_channel *dst_channel,
74 struct ttable_dst *ttable,
75 snd_pcm_uframes_t frames)
76{
77 if (dst_channel->wanted)
78 snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format);
79 dst_channel->enabled = 0;
80}
81
82static void route_to_channel_from_one(struct snd_pcm_plugin *plugin,
83 const struct snd_pcm_plugin_channel *src_channels,
84 struct snd_pcm_plugin_channel *dst_channel,
85 struct ttable_dst *ttable,
86 snd_pcm_uframes_t frames)
87{ 34{
88#define CONV_LABELS 35 int dst = 0;
89#include "plugin_ops.h" 36 for (; dst < ndsts; ++dst) {
90#undef CONV_LABELS 37 if (dvp->wanted)
91 struct route_priv *data = (struct route_priv *)plugin->extra_data; 38 snd_pcm_area_silence(&dvp->area, 0, frames, format);
92 void *conv; 39 dvp->enabled = 0;
93 const struct snd_pcm_plugin_channel *src_channel = NULL; 40 dvp++;
94 unsigned int srcidx;
95 char *src, *dst;
96 int src_step, dst_step;
97 for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
98 src_channel = &src_channels[ttable->srcs[srcidx].channel];
99 if (src_channel->area.addr != NULL)
100 break;
101 }
102 if (srcidx == ttable->nsrcs) {
103 route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
104 return;
105 }
106
107 dst_channel->enabled = 1;
108 conv = conv_labels[data->conv];
109 src = src_channel->area.addr + src_channel->area.first / 8;
110 src_step = src_channel->area.step / 8;
111 dst = dst_channel->area.addr + dst_channel->area.first / 8;
112 dst_step = dst_channel->area.step / 8;
113 while (frames-- > 0) {
114 goto *conv;
115#define CONV_END after
116#include "plugin_ops.h"
117#undef CONV_END
118 after:
119 src += src_step;
120 dst += dst_step;
121 } 41 }
122} 42}
123 43
124static void route_to_channel(struct snd_pcm_plugin *plugin, 44static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel,
125 const struct snd_pcm_plugin_channel *src_channels,
126 struct snd_pcm_plugin_channel *dst_channel, 45 struct snd_pcm_plugin_channel *dst_channel,
127 struct ttable_dst *ttable, snd_pcm_uframes_t frames) 46 snd_pcm_uframes_t frames, int format)
128{ 47{
129#define GET_U_LABELS
130#define PUT_U32_LABELS
131#include "plugin_ops.h"
132#undef GET_U_LABELS
133#undef PUT_U32_LABELS
134 static void *zero_labels[2] = { &&zero_int32, &&zero_int64 };
135 /* sum_type att */
136 static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att,
137 &&add_int64_noatt, &&add_int64_att,
138 };
139 /* sum_type att shift */
140 static void *norm_labels[2 * 2 * 4] = { NULL,
141 &&norm_int32_8_noatt,
142 &&norm_int32_16_noatt,
143 &&norm_int32_24_noatt,
144 NULL,
145 &&norm_int32_8_att,
146 &&norm_int32_16_att,
147 &&norm_int32_24_att,
148 &&norm_int64_0_noatt,
149 &&norm_int64_8_noatt,
150 &&norm_int64_16_noatt,
151 &&norm_int64_24_noatt,
152 &&norm_int64_0_att,
153 &&norm_int64_8_att,
154 &&norm_int64_16_att,
155 &&norm_int64_24_att,
156 };
157 struct route_priv *data = (struct route_priv *)plugin->extra_data;
158 void *zero, *get, *add, *norm, *put_u32;
159 int nsrcs = ttable->nsrcs;
160 char *dst;
161 int dst_step;
162 char *srcs[nsrcs];
163 int src_steps[nsrcs];
164 struct ttable_src src_tt[nsrcs];
165 u_int32_t sample = 0;
166 int srcidx, srcidx1 = 0;
167 for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
168 const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel];
169 if (!src_channel->enabled)
170 continue;
171 srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8;
172 src_steps[srcidx1] = src_channel->area.step / 8;
173 src_tt[srcidx1] = ttable->srcs[srcidx];
174 srcidx1++;
175 }
176 nsrcs = srcidx1;
177 if (nsrcs == 0) {
178 route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
179 return;
180 } else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
181 route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames);
182 return;
183 }
184
185 dst_channel->enabled = 1; 48 dst_channel->enabled = 1;
186 zero = zero_labels[data->sum_type]; 49 snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format);
187 get = get_u_labels[data->get];
188 add = add_labels[data->sum_type * 2 + ttable->att];
189 norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size];
190 put_u32 = put_u32_labels[data->put];
191 dst = dst_channel->area.addr + dst_channel->area.first / 8;
192 dst_step = dst_channel->area.step / 8;
193
194 while (frames-- > 0) {
195 struct ttable_src *ttp = src_tt;
196 union sum sum;
197
198 /* Zero sum */
199 goto *zero;
200 zero_int32:
201 sum.as_uint32 = 0;
202 goto zero_end;
203 zero_int64:
204 sum.as_uint64 = 0;
205 goto zero_end;
206 zero_end:
207 for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
208 char *src = srcs[srcidx];
209
210 /* Get sample */
211 goto *get;
212#define GET_U_END after_get
213#include "plugin_ops.h"
214#undef GET_U_END
215 after_get:
216
217 /* Sum */
218 goto *add;
219 add_int32_att:
220 sum.as_uint32 += sample * ttp->as_int;
221 goto after_sum;
222 add_int32_noatt:
223 if (ttp->as_int)
224 sum.as_uint32 += sample;
225 goto after_sum;
226 add_int64_att:
227 sum.as_uint64 += (u_int64_t) sample * ttp->as_int;
228 goto after_sum;
229 add_int64_noatt:
230 if (ttp->as_int)
231 sum.as_uint64 += sample;
232 goto after_sum;
233 after_sum:
234 srcs[srcidx] += src_steps[srcidx];
235 ttp++;
236 }
237
238 /* Normalization */
239 goto *norm;
240 norm_int32_8_att:
241 sum.as_uint64 = sum.as_uint32;
242 norm_int64_8_att:
243 sum.as_uint64 <<= 8;
244 norm_int64_0_att:
245 div(sum.as_uint64);
246 goto norm_int;
247
248 norm_int32_16_att:
249 sum.as_uint64 = sum.as_uint32;
250 norm_int64_16_att:
251 sum.as_uint64 <<= 16;
252 div(sum.as_uint64);
253 goto norm_int;
254
255 norm_int32_24_att:
256 sum.as_uint64 = sum.as_uint32;
257 norm_int64_24_att:
258 sum.as_uint64 <<= 24;
259 div(sum.as_uint64);
260 goto norm_int;
261
262 norm_int32_8_noatt:
263 sum.as_uint64 = sum.as_uint32;
264 norm_int64_8_noatt:
265 sum.as_uint64 <<= 8;
266 goto norm_int;
267
268 norm_int32_16_noatt:
269 sum.as_uint64 = sum.as_uint32;
270 norm_int64_16_noatt:
271 sum.as_uint64 <<= 16;
272 goto norm_int;
273
274 norm_int32_24_noatt:
275 sum.as_uint64 = sum.as_uint32;
276 norm_int64_24_noatt:
277 sum.as_uint64 <<= 24;
278 goto norm_int;
279
280 norm_int64_0_noatt:
281 norm_int:
282 if (sum.as_uint64 > (u_int32_t)0xffffffff)
283 sample = (u_int32_t)0xffffffff;
284 else
285 sample = sum.as_uint64;
286 goto after_norm;
287
288 after_norm:
289
290 /* Put sample */
291 goto *put_u32;
292#define PUT_U32_END after_put_u32
293#include "plugin_ops.h"
294#undef PUT_U32_END
295 after_put_u32:
296
297 dst += dst_step;
298 }
299}
300
301static int route_src_channels_mask(struct snd_pcm_plugin *plugin,
302 unsigned long *dst_vmask,
303 unsigned long **src_vmask)
304{
305 struct route_priv *data = (struct route_priv *)plugin->extra_data;
306 int schannels = plugin->src_format.channels;
307 int dchannels = plugin->dst_format.channels;
308 unsigned long *vmask = plugin->src_vmask;
309 int channel;
310 struct ttable_dst *dp = data->ttable;
311 bitmap_zero(vmask, schannels);
312 for (channel = 0; channel < dchannels; channel++, dp++) {
313 unsigned int src;
314 struct ttable_src *sp;
315 if (!test_bit(channel, dst_vmask))
316 continue;
317 sp = dp->srcs;
318 for (src = 0; src < dp->nsrcs; src++, sp++)
319 set_bit(sp->channel, vmask);
320 }
321 *src_vmask = vmask;
322 return 0;
323}
324
325static int route_dst_channels_mask(struct snd_pcm_plugin *plugin,
326 unsigned long *src_vmask,
327 unsigned long **dst_vmask)
328{
329 struct route_priv *data = (struct route_priv *)plugin->extra_data;
330 int dchannels = plugin->dst_format.channels;
331 unsigned long *vmask = plugin->dst_vmask;
332 int channel;
333 struct ttable_dst *dp = data->ttable;
334 bitmap_zero(vmask, dchannels);
335 for (channel = 0; channel < dchannels; channel++, dp++) {
336 unsigned int src;
337 struct ttable_src *sp;
338 sp = dp->srcs;
339 for (src = 0; src < dp->nsrcs; src++, sp++) {
340 if (test_bit(sp->channel, src_vmask)) {
341 set_bit(channel, vmask);
342 break;
343 }
344 }
345 }
346 *dst_vmask = vmask;
347 return 0;
348}
349
350static void route_free(struct snd_pcm_plugin *plugin)
351{
352 struct route_priv *data = (struct route_priv *)plugin->extra_data;
353 unsigned int dst_channel;
354 for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
355 kfree(data->ttable[dst_channel].srcs);
356 }
357}
358
359static int route_load_ttable(struct snd_pcm_plugin *plugin,
360 const int *src_ttable)
361{
362 struct route_priv *data;
363 unsigned int src_channel, dst_channel;
364 const int *sptr;
365 struct ttable_dst *dptr;
366 if (src_ttable == NULL)
367 return 0;
368 data = (struct route_priv *)plugin->extra_data;
369 dptr = data->ttable;
370 sptr = src_ttable;
371 plugin->private_free = route_free;
372 for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
373 int t = 0;
374 int att = 0;
375 int nsrcs = 0;
376 struct ttable_src srcs[plugin->src_format.channels];
377 for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
378 snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO);
379 if (*sptr != 0) {
380 srcs[nsrcs].channel = src_channel;
381 srcs[nsrcs].as_int = *sptr;
382 if (*sptr != FULL)
383 att = 1;
384 t += *sptr;
385 nsrcs++;
386 }
387 sptr++;
388 }
389 dptr->att = att;
390 dptr->nsrcs = nsrcs;
391 if (nsrcs == 0)
392 dptr->func = route_to_channel_from_zero;
393 else if (nsrcs == 1 && !att)
394 dptr->func = route_to_channel_from_one;
395 else
396 dptr->func = route_to_channel;
397 if (nsrcs > 0) {
398 int srcidx;
399 dptr->srcs = kcalloc(nsrcs, sizeof(*srcs), GFP_KERNEL);
400 for(srcidx = 0; srcidx < nsrcs; srcidx++)
401 dptr->srcs[srcidx] = srcs[srcidx];
402 } else
403 dptr->srcs = NULL;
404 dptr++;
405 }
406 return 0;
407} 50}
408 51
409static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin, 52static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
410 const struct snd_pcm_plugin_channel *src_channels, 53 const struct snd_pcm_plugin_channel *src_channels,
411 struct snd_pcm_plugin_channel *dst_channels, 54 struct snd_pcm_plugin_channel *dst_channels,
412 snd_pcm_uframes_t frames) 55 snd_pcm_uframes_t frames)
413{ 56{
414 struct route_priv *data; 57 int nsrcs, ndsts, dst;
415 int src_nchannels, dst_nchannels;
416 int dst_channel;
417 struct ttable_dst *ttp;
418 struct snd_pcm_plugin_channel *dvp; 58 struct snd_pcm_plugin_channel *dvp;
59 int format;
419 60
420 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); 61 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
421 if (frames == 0) 62 if (frames == 0)
422 return 0; 63 return 0;
423 data = (struct route_priv *)plugin->extra_data;
424 64
425 src_nchannels = plugin->src_format.channels; 65 nsrcs = plugin->src_format.channels;
426 dst_nchannels = plugin->dst_format.channels; 66 ndsts = plugin->dst_format.channels;
427 67
428#ifdef CONFIG_SND_DEBUG 68 format = plugin->dst_format.format;
429 { 69 dvp = dst_channels;
430 int src_channel; 70 if (nsrcs <= 1) {
431 for (src_channel = 0; src_channel < src_nchannels; ++src_channel) { 71 /* expand to all channels */
432 snd_assert(src_channels[src_channel].area.first % 8 == 0 || 72 for (dst = 0; dst < ndsts; ++dst) {
433 src_channels[src_channel].area.step % 8 == 0, 73 copy_area(src_channels, dvp, frames, format);
434 return -ENXIO); 74 dvp++;
435 }
436 for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
437 snd_assert(dst_channels[dst_channel].area.first % 8 == 0 ||
438 dst_channels[dst_channel].area.step % 8 == 0,
439 return -ENXIO);
440 } 75 }
76 return frames;
441 } 77 }
442#endif
443 78
444 ttp = data->ttable; 79 for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) {
445 dvp = dst_channels; 80 copy_area(src_channels, dvp, frames, format);
446 for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
447 ttp->func(plugin, src_channels, dvp, ttp, frames);
448 dvp++; 81 dvp++;
449 ttp++; 82 src_channels++;
450 } 83 }
84 if (dst < ndsts)
85 zero_areas(dvp, ndsts - dst, frames, format);
451 return frames; 86 return frames;
452} 87}
453 88
454int getput_index(int format)
455{
456 int sign, width, endian;
457 sign = !snd_pcm_format_signed(format);
458 width = snd_pcm_format_width(format) / 8 - 1;
459 if (width < 0 || width > 3) {
460 snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
461 width = 0;
462 }
463#ifdef SNDRV_LITTLE_ENDIAN
464 endian = snd_pcm_format_big_endian(format);
465#else
466 endian = snd_pcm_format_little_endian(format);
467#endif
468 if (endian < 0)
469 endian = 0;
470 return width * 4 + endian * 2 + sign;
471}
472
473int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug, 89int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
474 struct snd_pcm_plugin_format *src_format, 90 struct snd_pcm_plugin_format *src_format,
475 struct snd_pcm_plugin_format *dst_format, 91 struct snd_pcm_plugin_format *dst_format,
476 int *ttable,
477 struct snd_pcm_plugin **r_plugin) 92 struct snd_pcm_plugin **r_plugin)
478{ 93{
479 struct route_priv *data;
480 struct snd_pcm_plugin *plugin; 94 struct snd_pcm_plugin *plugin;
481 int err; 95 int err;
482 96
483 snd_assert(r_plugin != NULL, return -ENXIO); 97 snd_assert(r_plugin != NULL, return -ENXIO);
484 *r_plugin = NULL; 98 *r_plugin = NULL;
485 snd_assert(src_format->rate == dst_format->rate, return -ENXIO); 99 snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
486 snd_assert(snd_pcm_format_linear(src_format->format) != 0 && 100 snd_assert(src_format->format == dst_format->format, return -ENXIO);
487 snd_pcm_format_linear(dst_format->format) != 0,
488 return -ENXIO);
489 101
490 err = snd_pcm_plugin_build(plug, "attenuated route conversion", 102 err = snd_pcm_plugin_build(plug, "route conversion",
491 src_format, dst_format, 103 src_format, dst_format, 0, &plugin);
492 sizeof(struct route_priv) +
493 sizeof(data->ttable[0]) * dst_format->channels,
494 &plugin);
495 if (err < 0) 104 if (err < 0)
496 return err; 105 return err;
497 106
498 data = (struct route_priv *)plugin->extra_data;
499
500 data->get = getput_index(src_format->format);
501 snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
502 data->put = getput_index(dst_format->format);
503 snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
504 data->conv = conv_index(src_format->format, dst_format->format);
505
506 if (snd_pcm_format_width(src_format->format) == 32)
507 data->sum_type = R_UINT64;
508 else
509 data->sum_type = R_UINT32;
510 data->src_sample_size = snd_pcm_format_width(src_format->format) / 8;
511
512 if ((err = route_load_ttable(plugin, ttable)) < 0) {
513 snd_pcm_plugin_free(plugin);
514 return err;
515 }
516 plugin->transfer = route_transfer; 107 plugin->transfer = route_transfer;
517 plugin->src_channels_mask = route_src_channels_mask;
518 plugin->dst_channels_mask = route_dst_channels_mask;
519 *r_plugin = plugin; 108 *r_plugin = plugin;
520 return 0; 109 return 0;
521} 110}
111
112#endif
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 28ca61eb0b0d..3da6a38c2d0f 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -23,6 +23,7 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/time.h> 25#include <linux/time.h>
26#include <linux/mutex.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/minors.h> 28#include <sound/minors.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
@@ -35,7 +36,7 @@ MODULE_LICENSE("GPL");
35 36
36static LIST_HEAD(snd_pcm_devices); 37static LIST_HEAD(snd_pcm_devices);
37static LIST_HEAD(snd_pcm_notify_list); 38static LIST_HEAD(snd_pcm_notify_list);
38static DECLARE_MUTEX(register_mutex); 39static DEFINE_MUTEX(register_mutex);
39 40
40static int snd_pcm_free(struct snd_pcm *pcm); 41static int snd_pcm_free(struct snd_pcm *pcm);
41static int snd_pcm_dev_free(struct snd_device *device); 42static int snd_pcm_dev_free(struct snd_device *device);
@@ -67,7 +68,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
67 68
68 if (get_user(device, (int __user *)arg)) 69 if (get_user(device, (int __user *)arg))
69 return -EFAULT; 70 return -EFAULT;
70 down(&register_mutex); 71 mutex_lock(&register_mutex);
71 device = device < 0 ? 0 : device + 1; 72 device = device < 0 ? 0 : device + 1;
72 while (device < SNDRV_PCM_DEVICES) { 73 while (device < SNDRV_PCM_DEVICES) {
73 if (snd_pcm_search(card, device)) 74 if (snd_pcm_search(card, device))
@@ -76,7 +77,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
76 } 77 }
77 if (device == SNDRV_PCM_DEVICES) 78 if (device == SNDRV_PCM_DEVICES)
78 device = -1; 79 device = -1;
79 up(&register_mutex); 80 mutex_unlock(&register_mutex);
80 if (put_user(device, (int __user *)arg)) 81 if (put_user(device, (int __user *)arg))
81 return -EFAULT; 82 return -EFAULT;
82 return 0; 83 return 0;
@@ -100,7 +101,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
100 return -EINVAL; 101 return -EINVAL;
101 if (get_user(subdevice, &info->subdevice)) 102 if (get_user(subdevice, &info->subdevice))
102 return -EFAULT; 103 return -EFAULT;
103 down(&register_mutex); 104 mutex_lock(&register_mutex);
104 pcm = snd_pcm_search(card, device); 105 pcm = snd_pcm_search(card, device);
105 if (pcm == NULL) { 106 if (pcm == NULL) {
106 err = -ENXIO; 107 err = -ENXIO;
@@ -125,7 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
125 } 126 }
126 err = snd_pcm_info_user(substream, info); 127 err = snd_pcm_info_user(substream, info);
127 _error: 128 _error:
128 up(&register_mutex); 129 mutex_unlock(&register_mutex);
129 return err; 130 return err;
130 } 131 }
131 case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: 132 case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
@@ -140,6 +141,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
140 } 141 }
141 return -ENOIOCTLCMD; 142 return -ENOIOCTLCMD;
142} 143}
144
145#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
146
143#define STATE(v) [SNDRV_PCM_STATE_##v] = #v 147#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
144#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v 148#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
145#define READY(v) [SNDRV_PCM_READY_##v] = #v 149#define READY(v) [SNDRV_PCM_READY_##v] = #v
@@ -197,7 +201,6 @@ const char *snd_pcm_format_name(snd_pcm_format_t format)
197 return snd_pcm_format_names[format]; 201 return snd_pcm_format_names[format];
198} 202}
199 203
200#ifdef CONFIG_PROC_FS
201static char *snd_pcm_stream_names[] = { 204static char *snd_pcm_stream_names[] = {
202 STREAM(PLAYBACK), 205 STREAM(PLAYBACK),
203 STREAM(CAPTURE), 206 STREAM(CAPTURE),
@@ -260,6 +263,7 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state)
260 263
261#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 264#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
262#include <linux/soundcard.h> 265#include <linux/soundcard.h>
266
263static const char *snd_pcm_oss_format_name(int format) 267static const char *snd_pcm_oss_format_name(int format)
264{ 268{
265 switch (format) { 269 switch (format) {
@@ -622,7 +626,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
622 struct snd_pcm_substream *substream, *prev; 626 struct snd_pcm_substream *substream, *prev;
623 627
624#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 628#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
625 init_MUTEX(&pstr->oss.setup_mutex); 629 mutex_init(&pstr->oss.setup_mutex);
626#endif 630#endif
627 pstr->stream = stream; 631 pstr->stream = stream;
628 pstr->pcm = pcm; 632 pstr->pcm = pcm;
@@ -716,7 +720,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
716 snd_pcm_free(pcm); 720 snd_pcm_free(pcm);
717 return err; 721 return err;
718 } 722 }
719 init_MUTEX(&pcm->open_mutex); 723 mutex_init(&pcm->open_mutex);
720 init_waitqueue_head(&pcm->open_wait); 724 init_waitqueue_head(&pcm->open_wait);
721 if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { 725 if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
722 snd_pcm_free(pcm); 726 snd_pcm_free(pcm);
@@ -902,9 +906,9 @@ static int snd_pcm_dev_register(struct snd_device *device)
902 struct snd_pcm *pcm = device->device_data; 906 struct snd_pcm *pcm = device->device_data;
903 907
904 snd_assert(pcm != NULL && device != NULL, return -ENXIO); 908 snd_assert(pcm != NULL && device != NULL, return -ENXIO);
905 down(&register_mutex); 909 mutex_lock(&register_mutex);
906 if (snd_pcm_search(pcm->card, pcm->device)) { 910 if (snd_pcm_search(pcm->card, pcm->device)) {
907 up(&register_mutex); 911 mutex_unlock(&register_mutex);
908 return -EBUSY; 912 return -EBUSY;
909 } 913 }
910 list_add_tail(&pcm->list, &snd_pcm_devices); 914 list_add_tail(&pcm->list, &snd_pcm_devices);
@@ -928,7 +932,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
928 pcm, str)) < 0) 932 pcm, str)) < 0)
929 { 933 {
930 list_del(&pcm->list); 934 list_del(&pcm->list);
931 up(&register_mutex); 935 mutex_unlock(&register_mutex);
932 return err; 936 return err;
933 } 937 }
934 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) 938 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
@@ -939,7 +943,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
939 notify = list_entry(list, struct snd_pcm_notify, list); 943 notify = list_entry(list, struct snd_pcm_notify, list);
940 notify->n_register(pcm); 944 notify->n_register(pcm);
941 } 945 }
942 up(&register_mutex); 946 mutex_unlock(&register_mutex);
943 return 0; 947 return 0;
944} 948}
945 949
@@ -950,7 +954,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
950 struct snd_pcm_substream *substream; 954 struct snd_pcm_substream *substream;
951 int cidx; 955 int cidx;
952 956
953 down(&register_mutex); 957 mutex_lock(&register_mutex);
954 list_del_init(&pcm->list); 958 list_del_init(&pcm->list);
955 for (cidx = 0; cidx < 2; cidx++) 959 for (cidx = 0; cidx < 2; cidx++)
956 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) 960 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
@@ -961,7 +965,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
961 notify = list_entry(list, struct snd_pcm_notify, list); 965 notify = list_entry(list, struct snd_pcm_notify, list);
962 notify->n_disconnect(pcm); 966 notify->n_disconnect(pcm);
963 } 967 }
964 up(&register_mutex); 968 mutex_unlock(&register_mutex);
965 return 0; 969 return 0;
966} 970}
967 971
@@ -973,7 +977,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device)
973 struct snd_pcm *pcm = device->device_data; 977 struct snd_pcm *pcm = device->device_data;
974 978
975 snd_assert(pcm != NULL, return -ENXIO); 979 snd_assert(pcm != NULL, return -ENXIO);
976 down(&register_mutex); 980 mutex_lock(&register_mutex);
977 list_del(&pcm->list); 981 list_del(&pcm->list);
978 for (cidx = 0; cidx < 2; cidx++) { 982 for (cidx = 0; cidx < 2; cidx++) {
979 devtype = -1; 983 devtype = -1;
@@ -994,7 +998,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device)
994 notify = list_entry(list, struct snd_pcm_notify, list); 998 notify = list_entry(list, struct snd_pcm_notify, list);
995 notify->n_unregister(pcm); 999 notify->n_unregister(pcm);
996 } 1000 }
997 up(&register_mutex); 1001 mutex_unlock(&register_mutex);
998 return snd_pcm_free(pcm); 1002 return snd_pcm_free(pcm);
999} 1003}
1000 1004
@@ -1003,7 +1007,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1003 struct list_head *p; 1007 struct list_head *p;
1004 1008
1005 snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); 1009 snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL);
1006 down(&register_mutex); 1010 mutex_lock(&register_mutex);
1007 if (nfree) { 1011 if (nfree) {
1008 list_del(&notify->list); 1012 list_del(&notify->list);
1009 list_for_each(p, &snd_pcm_devices) 1013 list_for_each(p, &snd_pcm_devices)
@@ -1014,7 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1014 list_for_each(p, &snd_pcm_devices) 1018 list_for_each(p, &snd_pcm_devices)
1015 notify->n_register(list_entry(p, struct snd_pcm, list)); 1019 notify->n_register(list_entry(p, struct snd_pcm, list));
1016 } 1020 }
1017 up(&register_mutex); 1021 mutex_unlock(&register_mutex);
1018 return 0; 1022 return 0;
1019} 1023}
1020 1024
@@ -1029,7 +1033,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
1029 struct list_head *p; 1033 struct list_head *p;
1030 struct snd_pcm *pcm; 1034 struct snd_pcm *pcm;
1031 1035
1032 down(&register_mutex); 1036 mutex_lock(&register_mutex);
1033 list_for_each(p, &snd_pcm_devices) { 1037 list_for_each(p, &snd_pcm_devices) {
1034 pcm = list_entry(p, struct snd_pcm, list); 1038 pcm = list_entry(p, struct snd_pcm, list);
1035 snd_iprintf(buffer, "%02i-%02i: %s : %s", 1039 snd_iprintf(buffer, "%02i-%02i: %s : %s",
@@ -1042,7 +1046,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
1042 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); 1046 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
1043 snd_iprintf(buffer, "\n"); 1047 snd_iprintf(buffer, "\n");
1044 } 1048 }
1045 up(&register_mutex); 1049 mutex_unlock(&register_mutex);
1046} 1050}
1047 1051
1048static struct snd_info_entry *snd_pcm_proc_entry = NULL; 1052static struct snd_info_entry *snd_pcm_proc_entry = NULL;
@@ -1101,7 +1105,6 @@ EXPORT_SYMBOL(snd_pcm_new_stream);
1101EXPORT_SYMBOL(snd_pcm_notify); 1105EXPORT_SYMBOL(snd_pcm_notify);
1102EXPORT_SYMBOL(snd_pcm_open_substream); 1106EXPORT_SYMBOL(snd_pcm_open_substream);
1103EXPORT_SYMBOL(snd_pcm_release_substream); 1107EXPORT_SYMBOL(snd_pcm_release_substream);
1104EXPORT_SYMBOL(snd_pcm_format_name);
1105 /* pcm_native.c */ 1108 /* pcm_native.c */
1106EXPORT_SYMBOL(snd_pcm_link_rwlock); 1109EXPORT_SYMBOL(snd_pcm_link_rwlock);
1107#ifdef CONFIG_PM 1110#ifdef CONFIG_PM
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f3d5de7b55ac..01f150f0990e 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2112,7 +2112,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2112 } 2112 }
2113 init_waitqueue_entry(&wait, current); 2113 init_waitqueue_entry(&wait, current);
2114 add_wait_queue(&pcm->open_wait, &wait); 2114 add_wait_queue(&pcm->open_wait, &wait);
2115 down(&pcm->open_mutex); 2115 mutex_lock(&pcm->open_mutex);
2116 while (1) { 2116 while (1) {
2117 err = snd_pcm_open_file(file, pcm, stream, &pcm_file); 2117 err = snd_pcm_open_file(file, pcm, stream, &pcm_file);
2118 if (err >= 0) 2118 if (err >= 0)
@@ -2125,16 +2125,16 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2125 } else 2125 } else
2126 break; 2126 break;
2127 set_current_state(TASK_INTERRUPTIBLE); 2127 set_current_state(TASK_INTERRUPTIBLE);
2128 up(&pcm->open_mutex); 2128 mutex_unlock(&pcm->open_mutex);
2129 schedule(); 2129 schedule();
2130 down(&pcm->open_mutex); 2130 mutex_lock(&pcm->open_mutex);
2131 if (signal_pending(current)) { 2131 if (signal_pending(current)) {
2132 err = -ERESTARTSYS; 2132 err = -ERESTARTSYS;
2133 break; 2133 break;
2134 } 2134 }
2135 } 2135 }
2136 remove_wait_queue(&pcm->open_wait, &wait); 2136 remove_wait_queue(&pcm->open_wait, &wait);
2137 up(&pcm->open_mutex); 2137 mutex_unlock(&pcm->open_mutex);
2138 if (err < 0) 2138 if (err < 0)
2139 goto __error; 2139 goto __error;
2140 return err; 2140 return err;
@@ -2160,9 +2160,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2160 pcm = substream->pcm; 2160 pcm = substream->pcm;
2161 snd_pcm_drop(substream); 2161 snd_pcm_drop(substream);
2162 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2162 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2163 down(&pcm->open_mutex); 2163 mutex_lock(&pcm->open_mutex);
2164 snd_pcm_release_file(pcm_file); 2164 snd_pcm_release_file(pcm_file);
2165 up(&pcm->open_mutex); 2165 mutex_unlock(&pcm->open_mutex);
2166 wake_up(&pcm->open_wait); 2166 wake_up(&pcm->open_wait);
2167 module_put(pcm->card->module); 2167 module_put(pcm->card->module);
2168 snd_card_file_remove(pcm->card, file); 2168 snd_card_file_remove(pcm->card, file);
@@ -2539,6 +2539,14 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2539 return snd_pcm_drain(substream); 2539 return snd_pcm_drain(substream);
2540 case SNDRV_PCM_IOCTL_DROP: 2540 case SNDRV_PCM_IOCTL_DROP:
2541 return snd_pcm_drop(substream); 2541 return snd_pcm_drop(substream);
2542 case SNDRV_PCM_IOCTL_PAUSE:
2543 {
2544 int res;
2545 snd_pcm_stream_lock_irq(substream);
2546 res = snd_pcm_pause(substream, (int)(unsigned long)arg);
2547 snd_pcm_stream_unlock_irq(substream);
2548 return res;
2549 }
2542 } 2550 }
2543 snd_printd("unknown ioctl = 0x%x\n", cmd); 2551 snd_printd("unknown ioctl = 0x%x\n", cmd);
2544 return -ENOTTY; 2552 return -ENOTTY;
@@ -2619,14 +2627,6 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2619 __put_user(result, _frames); 2627 __put_user(result, _frames);
2620 return result < 0 ? result : 0; 2628 return result < 0 ? result : 0;
2621 } 2629 }
2622 case SNDRV_PCM_IOCTL_PAUSE:
2623 {
2624 int res;
2625 snd_pcm_stream_lock_irq(substream);
2626 res = snd_pcm_pause(substream, (int)(unsigned long)arg);
2627 snd_pcm_stream_unlock_irq(substream);
2628 return res;
2629 }
2630 } 2630 }
2631 return snd_pcm_common_ioctl1(substream, cmd, arg); 2631 return snd_pcm_common_ioctl1(substream, cmd, arg);
2632} 2632}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index d4d124e21924..6b7a36774298 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -28,6 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/time.h> 29#include <linux/time.h>
30#include <linux/wait.h> 30#include <linux/wait.h>
31#include <linux/mutex.h>
31#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
32#include <linux/delay.h> 33#include <linux/delay.h>
33#include <linux/wait.h> 34#include <linux/wait.h>
@@ -57,7 +58,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device);
57static int snd_rawmidi_dev_unregister(struct snd_device *device); 58static int snd_rawmidi_dev_unregister(struct snd_device *device);
58 59
59static LIST_HEAD(snd_rawmidi_devices); 60static LIST_HEAD(snd_rawmidi_devices);
60static DECLARE_MUTEX(register_mutex); 61static DEFINE_MUTEX(register_mutex);
61 62
62static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) 63static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
63{ 64{
@@ -237,9 +238,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
237 238
238 if (rfile) 239 if (rfile)
239 rfile->input = rfile->output = NULL; 240 rfile->input = rfile->output = NULL;
240 down(&register_mutex); 241 mutex_lock(&register_mutex);
241 rmidi = snd_rawmidi_search(card, device); 242 rmidi = snd_rawmidi_search(card, device);
242 up(&register_mutex); 243 mutex_unlock(&register_mutex);
243 if (rmidi == NULL) { 244 if (rmidi == NULL) {
244 err = -ENODEV; 245 err = -ENODEV;
245 goto __error1; 246 goto __error1;
@@ -249,7 +250,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
249 goto __error1; 250 goto __error1;
250 } 251 }
251 if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) 252 if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
252 down(&rmidi->open_mutex); 253 mutex_lock(&rmidi->open_mutex);
253 if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { 254 if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
254 if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { 255 if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) {
255 err = -ENXIO; 256 err = -ENXIO;
@@ -359,7 +360,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
359 soutput = NULL; 360 soutput = NULL;
360 } 361 }
361 if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) 362 if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
362 up(&rmidi->open_mutex); 363 mutex_unlock(&rmidi->open_mutex);
363 if (rfile) { 364 if (rfile) {
364 rfile->rmidi = rmidi; 365 rfile->rmidi = rmidi;
365 rfile->input = sinput; 366 rfile->input = sinput;
@@ -374,7 +375,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
374 snd_rawmidi_runtime_free(soutput); 375 snd_rawmidi_runtime_free(soutput);
375 module_put(rmidi->card->module); 376 module_put(rmidi->card->module);
376 if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) 377 if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
377 up(&rmidi->open_mutex); 378 mutex_unlock(&rmidi->open_mutex);
378 __error1: 379 __error1:
379 return err; 380 return err;
380} 381}
@@ -422,7 +423,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
422 } 423 }
423 init_waitqueue_entry(&wait, current); 424 init_waitqueue_entry(&wait, current);
424 add_wait_queue(&rmidi->open_wait, &wait); 425 add_wait_queue(&rmidi->open_wait, &wait);
425 down(&rmidi->open_mutex); 426 mutex_lock(&rmidi->open_mutex);
426 while (1) { 427 while (1) {
427 subdevice = -1; 428 subdevice = -1;
428 down_read(&card->controls_rwsem); 429 down_read(&card->controls_rwsem);
@@ -446,9 +447,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
446 } else 447 } else
447 break; 448 break;
448 set_current_state(TASK_INTERRUPTIBLE); 449 set_current_state(TASK_INTERRUPTIBLE);
449 up(&rmidi->open_mutex); 450 mutex_unlock(&rmidi->open_mutex);
450 schedule(); 451 schedule();
451 down(&rmidi->open_mutex); 452 mutex_lock(&rmidi->open_mutex);
452 if (signal_pending(current)) { 453 if (signal_pending(current)) {
453 err = -ERESTARTSYS; 454 err = -ERESTARTSYS;
454 break; 455 break;
@@ -467,7 +468,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
467 snd_card_file_remove(card, file); 468 snd_card_file_remove(card, file);
468 kfree(rawmidi_file); 469 kfree(rawmidi_file);
469 } 470 }
470 up(&rmidi->open_mutex); 471 mutex_unlock(&rmidi->open_mutex);
471 return err; 472 return err;
472} 473}
473 474
@@ -480,7 +481,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
480 snd_assert(rfile != NULL, return -ENXIO); 481 snd_assert(rfile != NULL, return -ENXIO);
481 snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); 482 snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO);
482 rmidi = rfile->rmidi; 483 rmidi = rfile->rmidi;
483 down(&rmidi->open_mutex); 484 mutex_lock(&rmidi->open_mutex);
484 if (rfile->input != NULL) { 485 if (rfile->input != NULL) {
485 substream = rfile->input; 486 substream = rfile->input;
486 rfile->input = NULL; 487 rfile->input = NULL;
@@ -514,7 +515,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
514 } 515 }
515 rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; 516 rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--;
516 } 517 }
517 up(&rmidi->open_mutex); 518 mutex_unlock(&rmidi->open_mutex);
518 module_put(rmidi->card->module); 519 module_put(rmidi->card->module);
519 return 0; 520 return 0;
520} 521}
@@ -576,9 +577,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
576 struct snd_rawmidi_substream *substream; 577 struct snd_rawmidi_substream *substream;
577 struct list_head *list; 578 struct list_head *list;
578 579
579 down(&register_mutex); 580 mutex_lock(&register_mutex);
580 rmidi = snd_rawmidi_search(card, info->device); 581 rmidi = snd_rawmidi_search(card, info->device);
581 up(&register_mutex); 582 mutex_unlock(&register_mutex);
582 if (!rmidi) 583 if (!rmidi)
583 return -ENXIO; 584 return -ENXIO;
584 if (info->stream < 0 || info->stream > 1) 585 if (info->stream < 0 || info->stream > 1)
@@ -818,7 +819,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
818 819
819 if (get_user(device, (int __user *)argp)) 820 if (get_user(device, (int __user *)argp))
820 return -EFAULT; 821 return -EFAULT;
821 down(&register_mutex); 822 mutex_lock(&register_mutex);
822 device = device < 0 ? 0 : device + 1; 823 device = device < 0 ? 0 : device + 1;
823 while (device < SNDRV_RAWMIDI_DEVICES) { 824 while (device < SNDRV_RAWMIDI_DEVICES) {
824 if (snd_rawmidi_search(card, device)) 825 if (snd_rawmidi_search(card, device))
@@ -827,7 +828,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
827 } 828 }
828 if (device == SNDRV_RAWMIDI_DEVICES) 829 if (device == SNDRV_RAWMIDI_DEVICES)
829 device = -1; 830 device = -1;
830 up(&register_mutex); 831 mutex_unlock(&register_mutex);
831 if (put_user(device, (int __user *)argp)) 832 if (put_user(device, (int __user *)argp))
832 return -EFAULT; 833 return -EFAULT;
833 return 0; 834 return 0;
@@ -1314,7 +1315,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1314 1315
1315 rmidi = entry->private_data; 1316 rmidi = entry->private_data;
1316 snd_iprintf(buffer, "%s\n\n", rmidi->name); 1317 snd_iprintf(buffer, "%s\n\n", rmidi->name);
1317 down(&rmidi->open_mutex); 1318 mutex_lock(&rmidi->open_mutex);
1318 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { 1319 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
1319 list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { 1320 list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
1320 substream = list_entry(list, struct snd_rawmidi_substream, list); 1321 substream = list_entry(list, struct snd_rawmidi_substream, list);
@@ -1355,7 +1356,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1355 } 1356 }
1356 } 1357 }
1357 } 1358 }
1358 up(&rmidi->open_mutex); 1359 mutex_unlock(&rmidi->open_mutex);
1359} 1360}
1360 1361
1361/* 1362/*
@@ -1436,7 +1437,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
1436 } 1437 }
1437 rmidi->card = card; 1438 rmidi->card = card;
1438 rmidi->device = device; 1439 rmidi->device = device;
1439 init_MUTEX(&rmidi->open_mutex); 1440 mutex_init(&rmidi->open_mutex);
1440 init_waitqueue_head(&rmidi->open_wait); 1441 init_waitqueue_head(&rmidi->open_wait);
1441 if (id != NULL) 1442 if (id != NULL)
1442 strlcpy(rmidi->id, id, sizeof(rmidi->id)); 1443 strlcpy(rmidi->id, id, sizeof(rmidi->id));
@@ -1507,9 +1508,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1507 1508
1508 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) 1509 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
1509 return -ENOMEM; 1510 return -ENOMEM;
1510 down(&register_mutex); 1511 mutex_lock(&register_mutex);
1511 if (snd_rawmidi_search(rmidi->card, rmidi->device)) { 1512 if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
1512 up(&register_mutex); 1513 mutex_unlock(&register_mutex);
1513 return -EBUSY; 1514 return -EBUSY;
1514 } 1515 }
1515 list_add_tail(&rmidi->list, &snd_rawmidi_devices); 1516 list_add_tail(&rmidi->list, &snd_rawmidi_devices);
@@ -1519,14 +1520,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1519 &snd_rawmidi_f_ops, rmidi, name)) < 0) { 1520 &snd_rawmidi_f_ops, rmidi, name)) < 0) {
1520 snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); 1521 snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
1521 list_del(&rmidi->list); 1522 list_del(&rmidi->list);
1522 up(&register_mutex); 1523 mutex_unlock(&register_mutex);
1523 return err; 1524 return err;
1524 } 1525 }
1525 if (rmidi->ops && rmidi->ops->dev_register && 1526 if (rmidi->ops && rmidi->ops->dev_register &&
1526 (err = rmidi->ops->dev_register(rmidi)) < 0) { 1527 (err = rmidi->ops->dev_register(rmidi)) < 0) {
1527 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); 1528 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1528 list_del(&rmidi->list); 1529 list_del(&rmidi->list);
1529 up(&register_mutex); 1530 mutex_unlock(&register_mutex);
1530 return err; 1531 return err;
1531 } 1532 }
1532#ifdef CONFIG_SND_OSSEMUL 1533#ifdef CONFIG_SND_OSSEMUL
@@ -1553,7 +1554,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1553 } 1554 }
1554 } 1555 }
1555#endif /* CONFIG_SND_OSSEMUL */ 1556#endif /* CONFIG_SND_OSSEMUL */
1556 up(&register_mutex); 1557 mutex_unlock(&register_mutex);
1557 sprintf(name, "midi%d", rmidi->device); 1558 sprintf(name, "midi%d", rmidi->device);
1558 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); 1559 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
1559 if (entry) { 1560 if (entry) {
@@ -1583,9 +1584,9 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1583{ 1584{
1584 struct snd_rawmidi *rmidi = device->device_data; 1585 struct snd_rawmidi *rmidi = device->device_data;
1585 1586
1586 down(&register_mutex); 1587 mutex_lock(&register_mutex);
1587 list_del_init(&rmidi->list); 1588 list_del_init(&rmidi->list);
1588 up(&register_mutex); 1589 mutex_unlock(&register_mutex);
1589 return 0; 1590 return 0;
1590} 1591}
1591 1592
@@ -1594,7 +1595,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device)
1594 struct snd_rawmidi *rmidi = device->device_data; 1595 struct snd_rawmidi *rmidi = device->device_data;
1595 1596
1596 snd_assert(rmidi != NULL, return -ENXIO); 1597 snd_assert(rmidi != NULL, return -ENXIO);
1597 down(&register_mutex); 1598 mutex_lock(&register_mutex);
1598 list_del(&rmidi->list); 1599 list_del(&rmidi->list);
1599 if (rmidi->proc_entry) { 1600 if (rmidi->proc_entry) {
1600 snd_info_unregister(rmidi->proc_entry); 1601 snd_info_unregister(rmidi->proc_entry);
@@ -1616,7 +1617,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device)
1616 if (rmidi->ops && rmidi->ops->dev_unregister) 1617 if (rmidi->ops && rmidi->ops->dev_unregister)
1617 rmidi->ops->dev_unregister(rmidi); 1618 rmidi->ops->dev_unregister(rmidi);
1618 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); 1619 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1619 up(&register_mutex); 1620 mutex_unlock(&register_mutex);
1620#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 1621#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1621 if (rmidi->seq_dev) { 1622 if (rmidi->seq_dev) {
1622 snd_device_free(rmidi->card, rmidi->seq_dev); 1623 snd_device_free(rmidi->card, rmidi->seq_dev);
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index c98f0ba13810..b9919785180b 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/mutex.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/minors.h> 29#include <sound/minors.h>
29#include <sound/initval.h> 30#include <sound/initval.h>
@@ -124,7 +125,7 @@ module_exit(alsa_seq_oss_exit)
124 * ALSA minor device interface 125 * ALSA minor device interface
125 */ 126 */
126 127
127static DECLARE_MUTEX(register_mutex); 128static DEFINE_MUTEX(register_mutex);
128 129
129static int 130static int
130odev_open(struct inode *inode, struct file *file) 131odev_open(struct inode *inode, struct file *file)
@@ -136,9 +137,9 @@ odev_open(struct inode *inode, struct file *file)
136 else 137 else
137 level = SNDRV_SEQ_OSS_MODE_SYNTH; 138 level = SNDRV_SEQ_OSS_MODE_SYNTH;
138 139
139 down(&register_mutex); 140 mutex_lock(&register_mutex);
140 rc = snd_seq_oss_open(file, level); 141 rc = snd_seq_oss_open(file, level);
141 up(&register_mutex); 142 mutex_unlock(&register_mutex);
142 143
143 return rc; 144 return rc;
144} 145}
@@ -153,9 +154,9 @@ odev_release(struct inode *inode, struct file *file)
153 154
154 snd_seq_oss_drain_write(dp); 155 snd_seq_oss_drain_write(dp);
155 156
156 down(&register_mutex); 157 mutex_lock(&register_mutex);
157 snd_seq_oss_release(dp); 158 snd_seq_oss_release(dp);
158 up(&register_mutex); 159 mutex_unlock(&register_mutex);
159 160
160 return 0; 161 return 0;
161} 162}
@@ -224,13 +225,13 @@ register_device(void)
224{ 225{
225 int rc; 226 int rc;
226 227
227 down(&register_mutex); 228 mutex_lock(&register_mutex);
228 if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, 229 if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
229 NULL, 0, 230 NULL, 0,
230 &seq_oss_f_ops, NULL, 231 &seq_oss_f_ops, NULL,
231 SNDRV_SEQ_OSS_DEVNAME)) < 0) { 232 SNDRV_SEQ_OSS_DEVNAME)) < 0) {
232 snd_printk(KERN_ERR "can't register device seq\n"); 233 snd_printk(KERN_ERR "can't register device seq\n");
233 up(&register_mutex); 234 mutex_unlock(&register_mutex);
234 return rc; 235 return rc;
235 } 236 }
236 if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, 237 if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
@@ -239,24 +240,24 @@ register_device(void)
239 SNDRV_SEQ_OSS_DEVNAME)) < 0) { 240 SNDRV_SEQ_OSS_DEVNAME)) < 0) {
240 snd_printk(KERN_ERR "can't register device music\n"); 241 snd_printk(KERN_ERR "can't register device music\n");
241 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); 242 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
242 up(&register_mutex); 243 mutex_unlock(&register_mutex);
243 return rc; 244 return rc;
244 } 245 }
245 debug_printk(("device registered\n")); 246 debug_printk(("device registered\n"));
246 up(&register_mutex); 247 mutex_unlock(&register_mutex);
247 return 0; 248 return 0;
248} 249}
249 250
250static void 251static void
251unregister_device(void) 252unregister_device(void)
252{ 253{
253 down(&register_mutex); 254 mutex_lock(&register_mutex);
254 debug_printk(("device unregistered\n")); 255 debug_printk(("device unregistered\n"));
255 if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) 256 if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)
256 snd_printk(KERN_ERR "error unregister device music\n"); 257 snd_printk(KERN_ERR "error unregister device music\n");
257 if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0) 258 if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
258 snd_printk(KERN_ERR "error unregister device seq\n"); 259 snd_printk(KERN_ERR "error unregister device seq\n");
259 up(&register_mutex); 260 mutex_unlock(&register_mutex);
260} 261}
261 262
262/* 263/*
@@ -270,12 +271,12 @@ static struct snd_info_entry *info_entry;
270static void 271static void
271info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) 272info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
272{ 273{
273 down(&register_mutex); 274 mutex_lock(&register_mutex);
274 snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR); 275 snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
275 snd_seq_oss_system_info_read(buf); 276 snd_seq_oss_system_info_read(buf);
276 snd_seq_oss_synth_info_read(buf); 277 snd_seq_oss_synth_info_read(buf);
277 snd_seq_oss_midi_info_read(buf); 278 snd_seq_oss_midi_info_read(buf);
278 up(&register_mutex); 279 mutex_unlock(&register_mutex);
279} 280}
280 281
281 282
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index fd2032eae214..bb15d9ee8842 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -67,7 +67,7 @@
67#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT) 67#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
68 68
69static DEFINE_SPINLOCK(clients_lock); 69static DEFINE_SPINLOCK(clients_lock);
70static DECLARE_MUTEX(register_mutex); 70static DEFINE_MUTEX(register_mutex);
71 71
72/* 72/*
73 * client table 73 * client table
@@ -237,7 +237,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
237 client->type = NO_CLIENT; 237 client->type = NO_CLIENT;
238 snd_use_lock_init(&client->use_lock); 238 snd_use_lock_init(&client->use_lock);
239 rwlock_init(&client->ports_lock); 239 rwlock_init(&client->ports_lock);
240 init_MUTEX(&client->ports_mutex); 240 mutex_init(&client->ports_mutex);
241 INIT_LIST_HEAD(&client->ports_list_head); 241 INIT_LIST_HEAD(&client->ports_list_head);
242 242
243 /* find free slot in the client table */ 243 /* find free slot in the client table */
@@ -290,7 +290,7 @@ static int seq_free_client1(struct snd_seq_client *client)
290 290
291static void seq_free_client(struct snd_seq_client * client) 291static void seq_free_client(struct snd_seq_client * client)
292{ 292{
293 down(&register_mutex); 293 mutex_lock(&register_mutex);
294 switch (client->type) { 294 switch (client->type) {
295 case NO_CLIENT: 295 case NO_CLIENT:
296 snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", 296 snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n",
@@ -306,7 +306,7 @@ static void seq_free_client(struct snd_seq_client * client)
306 snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", 306 snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n",
307 client->number, client->type); 307 client->number, client->type);
308 } 308 }
309 up(&register_mutex); 309 mutex_unlock(&register_mutex);
310 310
311 snd_seq_system_client_ev_client_exit(client->number); 311 snd_seq_system_client_ev_client_exit(client->number);
312} 312}
@@ -322,11 +322,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
322 struct snd_seq_client *client; 322 struct snd_seq_client *client;
323 struct snd_seq_user_client *user; 323 struct snd_seq_user_client *user;
324 324
325 if (down_interruptible(&register_mutex)) 325 if (mutex_lock_interruptible(&register_mutex))
326 return -ERESTARTSYS; 326 return -ERESTARTSYS;
327 client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS); 327 client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
328 if (client == NULL) { 328 if (client == NULL) {
329 up(&register_mutex); 329 mutex_unlock(&register_mutex);
330 return -ENOMEM; /* failure code */ 330 return -ENOMEM; /* failure code */
331 } 331 }
332 332
@@ -346,14 +346,14 @@ static int snd_seq_open(struct inode *inode, struct file *file)
346 if (user->fifo == NULL) { 346 if (user->fifo == NULL) {
347 seq_free_client1(client); 347 seq_free_client1(client);
348 kfree(client); 348 kfree(client);
349 up(&register_mutex); 349 mutex_unlock(&register_mutex);
350 return -ENOMEM; 350 return -ENOMEM;
351 } 351 }
352 } 352 }
353 353
354 usage_alloc(&client_usage, 1); 354 usage_alloc(&client_usage, 1);
355 client->type = USER_CLIENT; 355 client->type = USER_CLIENT;
356 up(&register_mutex); 356 mutex_unlock(&register_mutex);
357 357
358 c = client->number; 358 c = client->number;
359 file->private_data = client; 359 file->private_data = client;
@@ -1743,7 +1743,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
1743 if (queue == NULL) 1743 if (queue == NULL)
1744 return -EINVAL; 1744 return -EINVAL;
1745 1745
1746 if (down_interruptible(&queue->timer_mutex)) { 1746 if (mutex_lock_interruptible(&queue->timer_mutex)) {
1747 queuefree(queue); 1747 queuefree(queue);
1748 return -ERESTARTSYS; 1748 return -ERESTARTSYS;
1749 } 1749 }
@@ -1756,7 +1756,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
1756 timer.u.alsa.id = tmr->alsa_id; 1756 timer.u.alsa.id = tmr->alsa_id;
1757 timer.u.alsa.resolution = tmr->preferred_resolution; 1757 timer.u.alsa.resolution = tmr->preferred_resolution;
1758 } 1758 }
1759 up(&queue->timer_mutex); 1759 mutex_unlock(&queue->timer_mutex);
1760 queuefree(queue); 1760 queuefree(queue);
1761 1761
1762 if (copy_to_user(arg, &timer, sizeof(timer))) 1762 if (copy_to_user(arg, &timer, sizeof(timer)))
@@ -1785,7 +1785,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
1785 q = queueptr(timer.queue); 1785 q = queueptr(timer.queue);
1786 if (q == NULL) 1786 if (q == NULL)
1787 return -ENXIO; 1787 return -ENXIO;
1788 if (down_interruptible(&q->timer_mutex)) { 1788 if (mutex_lock_interruptible(&q->timer_mutex)) {
1789 queuefree(q); 1789 queuefree(q);
1790 return -ERESTARTSYS; 1790 return -ERESTARTSYS;
1791 } 1791 }
@@ -1797,7 +1797,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
1797 tmr->preferred_resolution = timer.u.alsa.resolution; 1797 tmr->preferred_resolution = timer.u.alsa.resolution;
1798 } 1798 }
1799 result = snd_seq_queue_timer_open(timer.queue); 1799 result = snd_seq_queue_timer_open(timer.queue);
1800 up(&q->timer_mutex); 1800 mutex_unlock(&q->timer_mutex);
1801 queuefree(q); 1801 queuefree(q);
1802 } else { 1802 } else {
1803 return -EPERM; 1803 return -EPERM;
@@ -1866,8 +1866,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
1866 info.output_pool = cptr->pool->size; 1866 info.output_pool = cptr->pool->size;
1867 info.output_room = cptr->pool->room; 1867 info.output_room = cptr->pool->room;
1868 info.output_free = info.output_pool; 1868 info.output_free = info.output_pool;
1869 if (cptr->pool) 1869 info.output_free = snd_seq_unused_cells(cptr->pool);
1870 info.output_free = snd_seq_unused_cells(cptr->pool);
1871 if (cptr->type == USER_CLIENT) { 1870 if (cptr->type == USER_CLIENT) {
1872 info.input_pool = cptr->data.user.fifo_pool_size; 1871 info.input_pool = cptr->data.user.fifo_pool_size;
1873 info.input_free = info.input_pool; 1872 info.input_free = info.input_pool;
@@ -2230,7 +2229,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2230 if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS) 2229 if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
2231 return -EINVAL; 2230 return -EINVAL;
2232 2231
2233 if (down_interruptible(&register_mutex)) 2232 if (mutex_lock_interruptible(&register_mutex))
2234 return -ERESTARTSYS; 2233 return -ERESTARTSYS;
2235 2234
2236 if (card) { 2235 if (card) {
@@ -2243,7 +2242,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2243 /* empty write queue as default */ 2242 /* empty write queue as default */
2244 client = seq_create_client1(client_index, 0); 2243 client = seq_create_client1(client_index, 0);
2245 if (client == NULL) { 2244 if (client == NULL) {
2246 up(&register_mutex); 2245 mutex_unlock(&register_mutex);
2247 return -EBUSY; /* failure code */ 2246 return -EBUSY; /* failure code */
2248 } 2247 }
2249 usage_alloc(&client_usage, 1); 2248 usage_alloc(&client_usage, 1);
@@ -2256,7 +2255,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2256 va_end(args); 2255 va_end(args);
2257 2256
2258 client->type = KERNEL_CLIENT; 2257 client->type = KERNEL_CLIENT;
2259 up(&register_mutex); 2258 mutex_unlock(&register_mutex);
2260 2259
2261 /* make others aware this new client */ 2260 /* make others aware this new client */
2262 snd_seq_system_client_ev_client_start(client->number); 2261 snd_seq_system_client_ev_client_start(client->number);
@@ -2464,7 +2463,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
2464{ 2463{
2465 struct list_head *l; 2464 struct list_head *l;
2466 2465
2467 down(&client->ports_mutex); 2466 mutex_lock(&client->ports_mutex);
2468 list_for_each(l, &client->ports_list_head) { 2467 list_for_each(l, &client->ports_list_head) {
2469 struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); 2468 struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
2470 snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", 2469 snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n",
@@ -2476,7 +2475,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
2476 snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); 2475 snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: ");
2477 snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); 2476 snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: ");
2478 } 2477 }
2479 up(&client->ports_mutex); 2478 mutex_unlock(&client->ports_mutex);
2480} 2479}
2481 2480
2482 2481
@@ -2550,16 +2549,16 @@ int __init snd_sequencer_device_init(void)
2550{ 2549{
2551 int err; 2550 int err;
2552 2551
2553 if (down_interruptible(&register_mutex)) 2552 if (mutex_lock_interruptible(&register_mutex))
2554 return -ERESTARTSYS; 2553 return -ERESTARTSYS;
2555 2554
2556 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, 2555 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
2557 &snd_seq_f_ops, NULL, "seq")) < 0) { 2556 &snd_seq_f_ops, NULL, "seq")) < 0) {
2558 up(&register_mutex); 2557 mutex_unlock(&register_mutex);
2559 return err; 2558 return err;
2560 } 2559 }
2561 2560
2562 up(&register_mutex); 2561 mutex_unlock(&register_mutex);
2563 2562
2564 return 0; 2563 return 0;
2565} 2564}
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
index 450091ca153d..5e04e20e239f 100644
--- a/sound/core/seq/seq_clientmgr.h
+++ b/sound/core/seq/seq_clientmgr.h
@@ -58,7 +58,7 @@ struct snd_seq_client {
58 int num_ports; /* number of ports */ 58 int num_ports; /* number of ports */
59 struct list_head ports_list_head; 59 struct list_head ports_list_head;
60 rwlock_t ports_lock; 60 rwlock_t ports_lock;
61 struct semaphore ports_mutex; 61 struct mutex ports_mutex;
62 int convert32; /* convert 32->64bit */ 62 int convert32; /* convert 32->64bit */
63 63
64 /* output pool */ 64 /* output pool */
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 9ece443fba55..d9a3e5a18d6a 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -45,6 +45,7 @@
45#include <sound/initval.h> 45#include <sound/initval.h>
46#include <linux/kmod.h> 46#include <linux/kmod.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/mutex.h>
48 49
49MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); 50MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
50MODULE_DESCRIPTION("ALSA sequencer device management"); 51MODULE_DESCRIPTION("ALSA sequencer device management");
@@ -69,7 +70,7 @@ struct ops_list {
69 struct list_head dev_list; /* list of devices */ 70 struct list_head dev_list; /* list of devices */
70 int num_devices; /* number of associated devices */ 71 int num_devices; /* number of associated devices */
71 int num_init_devices; /* number of initialized devices */ 72 int num_init_devices; /* number of initialized devices */
72 struct semaphore reg_mutex; 73 struct mutex reg_mutex;
73 74
74 struct list_head list; /* next driver */ 75 struct list_head list; /* next driver */
75}; 76};
@@ -77,7 +78,7 @@ struct ops_list {
77 78
78static LIST_HEAD(opslist); 79static LIST_HEAD(opslist);
79static int num_ops; 80static int num_ops;
80static DECLARE_MUTEX(ops_mutex); 81static DEFINE_MUTEX(ops_mutex);
81#ifdef CONFIG_PROC_FS 82#ifdef CONFIG_PROC_FS
82static struct snd_info_entry *info_entry = NULL; 83static struct snd_info_entry *info_entry = NULL;
83#endif 84#endif
@@ -108,7 +109,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
108{ 109{
109 struct list_head *head; 110 struct list_head *head;
110 111
111 down(&ops_mutex); 112 mutex_lock(&ops_mutex);
112 list_for_each(head, &opslist) { 113 list_for_each(head, &opslist) {
113 struct ops_list *ops = list_entry(head, struct ops_list, list); 114 struct ops_list *ops = list_entry(head, struct ops_list, list);
114 snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", 115 snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
@@ -118,7 +119,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
118 ops->driver & DRIVER_LOCKED ? ",locked" : "", 119 ops->driver & DRIVER_LOCKED ? ",locked" : "",
119 ops->num_devices); 120 ops->num_devices);
120 } 121 }
121 up(&ops_mutex); 122 mutex_unlock(&ops_mutex);
122} 123}
123#endif 124#endif
124 125
@@ -154,20 +155,20 @@ void snd_seq_device_load_drivers(void)
154 if (! current->fs->root) 155 if (! current->fs->root)
155 return; 156 return;
156 157
157 down(&ops_mutex); 158 mutex_lock(&ops_mutex);
158 list_for_each(head, &opslist) { 159 list_for_each(head, &opslist) {
159 struct ops_list *ops = list_entry(head, struct ops_list, list); 160 struct ops_list *ops = list_entry(head, struct ops_list, list);
160 if (! (ops->driver & DRIVER_LOADED) && 161 if (! (ops->driver & DRIVER_LOADED) &&
161 ! (ops->driver & DRIVER_REQUESTED)) { 162 ! (ops->driver & DRIVER_REQUESTED)) {
162 ops->used++; 163 ops->used++;
163 up(&ops_mutex); 164 mutex_unlock(&ops_mutex);
164 ops->driver |= DRIVER_REQUESTED; 165 ops->driver |= DRIVER_REQUESTED;
165 request_module("snd-%s", ops->id); 166 request_module("snd-%s", ops->id);
166 down(&ops_mutex); 167 mutex_lock(&ops_mutex);
167 ops->used--; 168 ops->used--;
168 } 169 }
169 } 170 }
170 up(&ops_mutex); 171 mutex_unlock(&ops_mutex);
171#endif 172#endif
172} 173}
173 174
@@ -214,10 +215,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
214 dev->status = SNDRV_SEQ_DEVICE_FREE; 215 dev->status = SNDRV_SEQ_DEVICE_FREE;
215 216
216 /* add this device to the list */ 217 /* add this device to the list */
217 down(&ops->reg_mutex); 218 mutex_lock(&ops->reg_mutex);
218 list_add_tail(&dev->list, &ops->dev_list); 219 list_add_tail(&dev->list, &ops->dev_list);
219 ops->num_devices++; 220 ops->num_devices++;
220 up(&ops->reg_mutex); 221 mutex_unlock(&ops->reg_mutex);
221 222
222 unlock_driver(ops); 223 unlock_driver(ops);
223 224
@@ -246,10 +247,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev)
246 return -ENXIO; 247 return -ENXIO;
247 248
248 /* remove the device from the list */ 249 /* remove the device from the list */
249 down(&ops->reg_mutex); 250 mutex_lock(&ops->reg_mutex);
250 list_del(&dev->list); 251 list_del(&dev->list);
251 ops->num_devices--; 252 ops->num_devices--;
252 up(&ops->reg_mutex); 253 mutex_unlock(&ops->reg_mutex);
253 254
254 free_device(dev, ops); 255 free_device(dev, ops);
255 if (dev->private_free) 256 if (dev->private_free)
@@ -344,7 +345,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
344 return -EBUSY; 345 return -EBUSY;
345 } 346 }
346 347
347 down(&ops->reg_mutex); 348 mutex_lock(&ops->reg_mutex);
348 /* copy driver operators */ 349 /* copy driver operators */
349 ops->ops = *entry; 350 ops->ops = *entry;
350 ops->driver |= DRIVER_LOADED; 351 ops->driver |= DRIVER_LOADED;
@@ -355,7 +356,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
355 struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); 356 struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
356 init_device(dev, ops); 357 init_device(dev, ops);
357 } 358 }
358 up(&ops->reg_mutex); 359 mutex_unlock(&ops->reg_mutex);
359 360
360 unlock_driver(ops); 361 unlock_driver(ops);
361 snd_seq_autoload_unlock(); 362 snd_seq_autoload_unlock();
@@ -378,17 +379,17 @@ static struct ops_list * create_driver(char *id)
378 379
379 /* set up driver entry */ 380 /* set up driver entry */
380 strlcpy(ops->id, id, sizeof(ops->id)); 381 strlcpy(ops->id, id, sizeof(ops->id));
381 init_MUTEX(&ops->reg_mutex); 382 mutex_init(&ops->reg_mutex);
382 ops->driver = DRIVER_EMPTY; 383 ops->driver = DRIVER_EMPTY;
383 INIT_LIST_HEAD(&ops->dev_list); 384 INIT_LIST_HEAD(&ops->dev_list);
384 /* lock this instance */ 385 /* lock this instance */
385 ops->used = 1; 386 ops->used = 1;
386 387
387 /* register driver entry */ 388 /* register driver entry */
388 down(&ops_mutex); 389 mutex_lock(&ops_mutex);
389 list_add_tail(&ops->list, &opslist); 390 list_add_tail(&ops->list, &opslist);
390 num_ops++; 391 num_ops++;
391 up(&ops_mutex); 392 mutex_unlock(&ops_mutex);
392 393
393 return ops; 394 return ops;
394} 395}
@@ -414,7 +415,7 @@ int snd_seq_device_unregister_driver(char *id)
414 } 415 }
415 416
416 /* close and release all devices associated with this driver */ 417 /* close and release all devices associated with this driver */
417 down(&ops->reg_mutex); 418 mutex_lock(&ops->reg_mutex);
418 ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ 419 ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
419 list_for_each(head, &ops->dev_list) { 420 list_for_each(head, &ops->dev_list) {
420 struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); 421 struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
@@ -425,7 +426,7 @@ int snd_seq_device_unregister_driver(char *id)
425 if (ops->num_init_devices > 0) 426 if (ops->num_init_devices > 0)
426 snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", 427 snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
427 ops->num_init_devices); 428 ops->num_init_devices);
428 up(&ops->reg_mutex); 429 mutex_unlock(&ops->reg_mutex);
429 430
430 unlock_driver(ops); 431 unlock_driver(ops);
431 432
@@ -443,7 +444,7 @@ static void remove_drivers(void)
443{ 444{
444 struct list_head *head; 445 struct list_head *head;
445 446
446 down(&ops_mutex); 447 mutex_lock(&ops_mutex);
447 head = opslist.next; 448 head = opslist.next;
448 while (head != &opslist) { 449 while (head != &opslist) {
449 struct ops_list *ops = list_entry(head, struct ops_list, list); 450 struct ops_list *ops = list_entry(head, struct ops_list, list);
@@ -456,7 +457,7 @@ static void remove_drivers(void)
456 } else 457 } else
457 head = head->next; 458 head = head->next;
458 } 459 }
459 up(&ops_mutex); 460 mutex_unlock(&ops_mutex);
460} 461}
461 462
462/* 463/*
@@ -519,16 +520,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
519{ 520{
520 struct list_head *head; 521 struct list_head *head;
521 522
522 down(&ops_mutex); 523 mutex_lock(&ops_mutex);
523 list_for_each(head, &opslist) { 524 list_for_each(head, &opslist) {
524 struct ops_list *ops = list_entry(head, struct ops_list, list); 525 struct ops_list *ops = list_entry(head, struct ops_list, list);
525 if (strcmp(ops->id, id) == 0) { 526 if (strcmp(ops->id, id) == 0) {
526 ops->used++; 527 ops->used++;
527 up(&ops_mutex); 528 mutex_unlock(&ops_mutex);
528 return ops; 529 return ops;
529 } 530 }
530 } 531 }
531 up(&ops_mutex); 532 mutex_unlock(&ops_mutex);
532 if (create_if_empty) 533 if (create_if_empty)
533 return create_driver(id); 534 return create_driver(id);
534 return NULL; 535 return NULL;
@@ -536,9 +537,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
536 537
537static void unlock_driver(struct ops_list *ops) 538static void unlock_driver(struct ops_list *ops)
538{ 539{
539 down(&ops_mutex); 540 mutex_lock(&ops_mutex);
540 ops->used--; 541 ops->used--;
541 up(&ops_mutex); 542 mutex_unlock(&ops_mutex);
542} 543}
543 544
544 545
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 487452063965..f30d171b6d96 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -36,7 +36,7 @@ static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list)
36 if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { 36 if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
37 spin_lock_irqsave(&list->ops_lock, list->ops_flags); 37 spin_lock_irqsave(&list->ops_lock, list->ops_flags);
38 } else { 38 } else {
39 down(&list->ops_mutex); 39 mutex_lock(&list->ops_mutex);
40 } 40 }
41} 41}
42 42
@@ -45,7 +45,7 @@ static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list)
45 if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { 45 if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
46 spin_unlock_irqrestore(&list->ops_lock, list->ops_flags); 46 spin_unlock_irqrestore(&list->ops_lock, list->ops_flags);
47 } else { 47 } else {
48 up(&list->ops_mutex); 48 mutex_unlock(&list->ops_mutex);
49 } 49 }
50} 50}
51 51
@@ -82,7 +82,7 @@ struct snd_seq_kinstr_list *snd_seq_instr_list_new(void)
82 return NULL; 82 return NULL;
83 spin_lock_init(&list->lock); 83 spin_lock_init(&list->lock);
84 spin_lock_init(&list->ops_lock); 84 spin_lock_init(&list->ops_lock);
85 init_MUTEX(&list->ops_mutex); 85 mutex_init(&list->ops_mutex);
86 list->owner = -1; 86 list->owner = -1;
87 return list; 87 return list;
88} 88}
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index ce0df86157de..9caa1372bece 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -32,7 +32,7 @@ Possible options for midisynth module:
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
35#include <asm/semaphore.h> 35#include <linux/mutex.h>
36#include <sound/core.h> 36#include <sound/core.h>
37#include <sound/rawmidi.h> 37#include <sound/rawmidi.h>
38#include <sound/seq_kernel.h> 38#include <sound/seq_kernel.h>
@@ -70,7 +70,7 @@ struct seq_midisynth_client {
70}; 70};
71 71
72static struct seq_midisynth_client *synths[SNDRV_CARDS]; 72static struct seq_midisynth_client *synths[SNDRV_CARDS];
73static DECLARE_MUTEX(register_mutex); 73static DEFINE_MUTEX(register_mutex);
74 74
75/* handle rawmidi input event (MIDI v1.0 stream) */ 75/* handle rawmidi input event (MIDI v1.0 stream) */
76static void snd_midi_input_event(struct snd_rawmidi_substream *substream) 76static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
@@ -308,13 +308,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
308 if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) 308 if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
309 ports = 256 / SNDRV_RAWMIDI_DEVICES; 309 ports = 256 / SNDRV_RAWMIDI_DEVICES;
310 310
311 down(&register_mutex); 311 mutex_lock(&register_mutex);
312 client = synths[card->number]; 312 client = synths[card->number];
313 if (client == NULL) { 313 if (client == NULL) {
314 newclient = 1; 314 newclient = 1;
315 client = kzalloc(sizeof(*client), GFP_KERNEL); 315 client = kzalloc(sizeof(*client), GFP_KERNEL);
316 if (client == NULL) { 316 if (client == NULL) {
317 up(&register_mutex); 317 mutex_unlock(&register_mutex);
318 kfree(info); 318 kfree(info);
319 return -ENOMEM; 319 return -ENOMEM;
320 } 320 }
@@ -324,7 +324,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
324 (const char *)info->name : "External MIDI"); 324 (const char *)info->name : "External MIDI");
325 if (client->seq_client < 0) { 325 if (client->seq_client < 0) {
326 kfree(client); 326 kfree(client);
327 up(&register_mutex); 327 mutex_unlock(&register_mutex);
328 kfree(info); 328 kfree(info);
329 return -ENOMEM; 329 return -ENOMEM;
330 } 330 }
@@ -397,7 +397,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
397 client->num_ports++; 397 client->num_ports++;
398 if (newclient) 398 if (newclient)
399 synths[card->number] = client; 399 synths[card->number] = client;
400 up(&register_mutex); 400 mutex_unlock(&register_mutex);
401 kfree(info); 401 kfree(info);
402 kfree(port); 402 kfree(port);
403 return 0; /* success */ 403 return 0; /* success */
@@ -414,7 +414,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
414 } 414 }
415 kfree(info); 415 kfree(info);
416 kfree(port); 416 kfree(port);
417 up(&register_mutex); 417 mutex_unlock(&register_mutex);
418 return -ENOMEM; 418 return -ENOMEM;
419} 419}
420 420
@@ -427,10 +427,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
427 struct snd_card *card = dev->card; 427 struct snd_card *card = dev->card;
428 int device = dev->device, p, ports; 428 int device = dev->device, p, ports;
429 429
430 down(&register_mutex); 430 mutex_lock(&register_mutex);
431 client = synths[card->number]; 431 client = synths[card->number];
432 if (client == NULL || client->ports[device] == NULL) { 432 if (client == NULL || client->ports[device] == NULL) {
433 up(&register_mutex); 433 mutex_unlock(&register_mutex);
434 return -ENODEV; 434 return -ENODEV;
435 } 435 }
436 ports = client->ports_per_device[device]; 436 ports = client->ports_per_device[device];
@@ -446,7 +446,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
446 synths[card->number] = NULL; 446 synths[card->number] = NULL;
447 kfree(client); 447 kfree(client);
448 } 448 }
449 up(&register_mutex); 449 mutex_unlock(&register_mutex);
450 return 0; 450 return 0;
451} 451}
452 452
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 2b384fd7967f..41e078c938cd 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -159,7 +159,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
159 port_subs_info_init(&new_port->c_dest); 159 port_subs_info_init(&new_port->c_dest);
160 160
161 num = port >= 0 ? port : 0; 161 num = port >= 0 ? port : 0;
162 down(&client->ports_mutex); 162 mutex_lock(&client->ports_mutex);
163 write_lock_irqsave(&client->ports_lock, flags); 163 write_lock_irqsave(&client->ports_lock, flags);
164 list_for_each(l, &client->ports_list_head) { 164 list_for_each(l, &client->ports_list_head) {
165 struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); 165 struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
@@ -173,7 +173,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
173 client->num_ports++; 173 client->num_ports++;
174 new_port->addr.port = num; /* store the port number in the port */ 174 new_port->addr.port = num; /* store the port number in the port */
175 write_unlock_irqrestore(&client->ports_lock, flags); 175 write_unlock_irqrestore(&client->ports_lock, flags);
176 up(&client->ports_mutex); 176 mutex_unlock(&client->ports_mutex);
177 sprintf(new_port->name, "port-%d", num); 177 sprintf(new_port->name, "port-%d", num);
178 178
179 return new_port; 179 return new_port;
@@ -292,7 +292,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
292 struct list_head *l; 292 struct list_head *l;
293 struct snd_seq_client_port *found = NULL; 293 struct snd_seq_client_port *found = NULL;
294 294
295 down(&client->ports_mutex); 295 mutex_lock(&client->ports_mutex);
296 write_lock_irqsave(&client->ports_lock, flags); 296 write_lock_irqsave(&client->ports_lock, flags);
297 list_for_each(l, &client->ports_list_head) { 297 list_for_each(l, &client->ports_list_head) {
298 struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); 298 struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
@@ -305,7 +305,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
305 } 305 }
306 } 306 }
307 write_unlock_irqrestore(&client->ports_lock, flags); 307 write_unlock_irqrestore(&client->ports_lock, flags);
308 up(&client->ports_mutex); 308 mutex_unlock(&client->ports_mutex);
309 if (found) 309 if (found)
310 return port_delete(client, found); 310 return port_delete(client, found);
311 else 311 else
@@ -321,7 +321,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
321 /* move the port list to deleted_list, and 321 /* move the port list to deleted_list, and
322 * clear the port list in the client data. 322 * clear the port list in the client data.
323 */ 323 */
324 down(&client->ports_mutex); 324 mutex_lock(&client->ports_mutex);
325 write_lock_irqsave(&client->ports_lock, flags); 325 write_lock_irqsave(&client->ports_lock, flags);
326 if (! list_empty(&client->ports_list_head)) { 326 if (! list_empty(&client->ports_list_head)) {
327 __list_add(&deleted_list, 327 __list_add(&deleted_list,
@@ -341,7 +341,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
341 snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); 341 snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
342 port_delete(client, port); 342 port_delete(client, port);
343 } 343 }
344 up(&client->ports_mutex); 344 mutex_unlock(&client->ports_mutex);
345 return 0; 345 return 0;
346} 346}
347 347
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 9cf20f045542..9b87bb0c7f33 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -119,7 +119,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked)
119 119
120 spin_lock_init(&q->owner_lock); 120 spin_lock_init(&q->owner_lock);
121 spin_lock_init(&q->check_lock); 121 spin_lock_init(&q->check_lock);
122 init_MUTEX(&q->timer_mutex); 122 mutex_init(&q->timer_mutex);
123 snd_use_lock_init(&q->use_lock); 123 snd_use_lock_init(&q->use_lock);
124 q->queue = -1; 124 q->queue = -1;
125 125
@@ -516,7 +516,7 @@ int snd_seq_queue_use(int queueid, int client, int use)
516 queue = queueptr(queueid); 516 queue = queueptr(queueid);
517 if (queue == NULL) 517 if (queue == NULL)
518 return -EINVAL; 518 return -EINVAL;
519 down(&queue->timer_mutex); 519 mutex_lock(&queue->timer_mutex);
520 if (use) { 520 if (use) {
521 if (!test_and_set_bit(client, queue->clients_bitmap)) 521 if (!test_and_set_bit(client, queue->clients_bitmap))
522 queue->clients++; 522 queue->clients++;
@@ -531,7 +531,7 @@ int snd_seq_queue_use(int queueid, int client, int use)
531 } else { 531 } else {
532 snd_seq_timer_close(queue); 532 snd_seq_timer_close(queue);
533 } 533 }
534 up(&queue->timer_mutex); 534 mutex_unlock(&queue->timer_mutex);
535 queuefree(queue); 535 queuefree(queue);
536 return 0; 536 return 0;
537} 537}
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
index 888438599387..30c8111477f6 100644
--- a/sound/core/seq/seq_queue.h
+++ b/sound/core/seq/seq_queue.h
@@ -54,7 +54,7 @@ struct snd_seq_queue {
54 /* clients which uses this queue (bitmap) */ 54 /* clients which uses this queue (bitmap) */
55 DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS); 55 DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS);
56 unsigned int clients; /* users of this queue */ 56 unsigned int clients; /* users of this queue */
57 struct semaphore timer_mutex; 57 struct mutex timer_mutex;
58 58
59 snd_use_lock_t use_lock; 59 snd_use_lock_t use_lock;
60}; 60};
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 14fd1a608e14..f4edec603b8f 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -167,7 +167,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
167 return; /* ignored */ 167 return; /* ignored */
168 } 168 }
169 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 169 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
170 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) 170 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
171 return; 171 return;
172 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 172 vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
173 } 173 }
@@ -186,7 +186,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
186 pbuf += res; 186 pbuf += res;
187 count -= res; 187 count -= res;
188 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 188 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
189 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) 189 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
190 return; 190 return;
191 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 191 vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
192 } 192 }
diff --git a/sound/core/sound.c b/sound/core/sound.c
index a8eda02bcf1c..4d28e5212611 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -33,6 +33,7 @@
33#include <sound/initval.h> 33#include <sound/initval.h>
34#include <linux/kmod.h> 34#include <linux/kmod.h>
35#include <linux/devfs_fs_kernel.h> 35#include <linux/devfs_fs_kernel.h>
36#include <linux/mutex.h>
36 37
37#define SNDRV_OS_MINORS 256 38#define SNDRV_OS_MINORS 256
38 39
@@ -61,7 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
61int snd_ecards_limit; 62int snd_ecards_limit;
62 63
63static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; 64static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
64static DECLARE_MUTEX(sound_mutex); 65static DEFINE_MUTEX(sound_mutex);
65 66
66extern struct class *sound_class; 67extern struct class *sound_class;
67 68
@@ -120,15 +121,15 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
120 struct snd_minor *mreg; 121 struct snd_minor *mreg;
121 void *private_data; 122 void *private_data;
122 123
123 if (minor > ARRAY_SIZE(snd_minors)) 124 if (minor >= ARRAY_SIZE(snd_minors))
124 return NULL; 125 return NULL;
125 down(&sound_mutex); 126 mutex_lock(&sound_mutex);
126 mreg = snd_minors[minor]; 127 mreg = snd_minors[minor];
127 if (mreg && mreg->type == type) 128 if (mreg && mreg->type == type)
128 private_data = mreg->private_data; 129 private_data = mreg->private_data;
129 else 130 else
130 private_data = NULL; 131 private_data = NULL;
131 up(&sound_mutex); 132 mutex_unlock(&sound_mutex);
132 return private_data; 133 return private_data;
133} 134}
134 135
@@ -139,7 +140,7 @@ static int snd_open(struct inode *inode, struct file *file)
139 struct file_operations *old_fops; 140 struct file_operations *old_fops;
140 int err = 0; 141 int err = 0;
141 142
142 if (minor > ARRAY_SIZE(snd_minors)) 143 if (minor >= ARRAY_SIZE(snd_minors))
143 return -ENODEV; 144 return -ENODEV;
144 mptr = snd_minors[minor]; 145 mptr = snd_minors[minor];
145 if (mptr == NULL) { 146 if (mptr == NULL) {
@@ -256,7 +257,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
256 preg->f_ops = f_ops; 257 preg->f_ops = f_ops;
257 preg->private_data = private_data; 258 preg->private_data = private_data;
258 strcpy(preg->name, name); 259 strcpy(preg->name, name);
259 down(&sound_mutex); 260 mutex_lock(&sound_mutex);
260#ifdef CONFIG_SND_DYNAMIC_MINORS 261#ifdef CONFIG_SND_DYNAMIC_MINORS
261 minor = snd_find_free_minor(); 262 minor = snd_find_free_minor();
262#else 263#else
@@ -265,7 +266,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
265 minor = -EBUSY; 266 minor = -EBUSY;
266#endif 267#endif
267 if (minor < 0) { 268 if (minor < 0) {
268 up(&sound_mutex); 269 mutex_unlock(&sound_mutex);
269 kfree(preg); 270 kfree(preg);
270 return minor; 271 return minor;
271 } 272 }
@@ -276,7 +277,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
276 device = card->dev; 277 device = card->dev;
277 class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name); 278 class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
278 279
279 up(&sound_mutex); 280 mutex_unlock(&sound_mutex);
280 return 0; 281 return 0;
281} 282}
282 283
@@ -297,7 +298,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
297 struct snd_minor *mptr; 298 struct snd_minor *mptr;
298 299
299 cardnum = card ? card->number : -1; 300 cardnum = card ? card->number : -1;
300 down(&sound_mutex); 301 mutex_lock(&sound_mutex);
301 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) 302 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
302 if ((mptr = snd_minors[minor]) != NULL && 303 if ((mptr = snd_minors[minor]) != NULL &&
303 mptr->type == type && 304 mptr->type == type &&
@@ -305,7 +306,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
305 mptr->device == dev) 306 mptr->device == dev)
306 break; 307 break;
307 if (minor == ARRAY_SIZE(snd_minors)) { 308 if (minor == ARRAY_SIZE(snd_minors)) {
308 up(&sound_mutex); 309 mutex_unlock(&sound_mutex);
309 return -EINVAL; 310 return -EINVAL;
310 } 311 }
311 312
@@ -315,7 +316,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
315 class_device_destroy(sound_class, MKDEV(major, minor)); 316 class_device_destroy(sound_class, MKDEV(major, minor));
316 317
317 snd_minors[minor] = NULL; 318 snd_minors[minor] = NULL;
318 up(&sound_mutex); 319 mutex_unlock(&sound_mutex);
319 kfree(mptr); 320 kfree(mptr);
320 return 0; 321 return 0;
321} 322}
@@ -354,7 +355,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
354 int minor; 355 int minor;
355 struct snd_minor *mptr; 356 struct snd_minor *mptr;
356 357
357 down(&sound_mutex); 358 mutex_lock(&sound_mutex);
358 for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { 359 for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
359 if (!(mptr = snd_minors[minor])) 360 if (!(mptr = snd_minors[minor]))
360 continue; 361 continue;
@@ -371,7 +372,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
371 snd_iprintf(buffer, "%3i: : %s\n", minor, 372 snd_iprintf(buffer, "%3i: : %s\n", minor,
372 snd_device_type_name(mptr->type)); 373 snd_device_type_name(mptr->type));
373 } 374 }
374 up(&sound_mutex); 375 mutex_unlock(&sound_mutex);
375} 376}
376 377
377int __init snd_minor_info_init(void) 378int __init snd_minor_info_init(void)
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index d0be32b517c1..4023d3b406de 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -34,26 +34,27 @@
34#include <sound/minors.h> 34#include <sound/minors.h>
35#include <sound/info.h> 35#include <sound/info.h>
36#include <linux/sound.h> 36#include <linux/sound.h>
37#include <linux/mutex.h>
37 38
38#define SNDRV_OSS_MINORS 128 39#define SNDRV_OSS_MINORS 128
39 40
40static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; 41static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
41static DECLARE_MUTEX(sound_oss_mutex); 42static DEFINE_MUTEX(sound_oss_mutex);
42 43
43void *snd_lookup_oss_minor_data(unsigned int minor, int type) 44void *snd_lookup_oss_minor_data(unsigned int minor, int type)
44{ 45{
45 struct snd_minor *mreg; 46 struct snd_minor *mreg;
46 void *private_data; 47 void *private_data;
47 48
48 if (minor > ARRAY_SIZE(snd_oss_minors)) 49 if (minor >= ARRAY_SIZE(snd_oss_minors))
49 return NULL; 50 return NULL;
50 down(&sound_oss_mutex); 51 mutex_lock(&sound_oss_mutex);
51 mreg = snd_oss_minors[minor]; 52 mreg = snd_oss_minors[minor];
52 if (mreg && mreg->type == type) 53 if (mreg && mreg->type == type)
53 private_data = mreg->private_data; 54 private_data = mreg->private_data;
54 else 55 else
55 private_data = NULL; 56 private_data = NULL;
56 up(&sound_oss_mutex); 57 mutex_unlock(&sound_oss_mutex);
57 return private_data; 58 return private_data;
58} 59}
59 60
@@ -117,7 +118,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
117 preg->device = dev; 118 preg->device = dev;
118 preg->f_ops = f_ops; 119 preg->f_ops = f_ops;
119 preg->private_data = private_data; 120 preg->private_data = private_data;
120 down(&sound_oss_mutex); 121 mutex_lock(&sound_oss_mutex);
121 snd_oss_minors[minor] = preg; 122 snd_oss_minors[minor] = preg;
122 minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); 123 minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
123 switch (minor_unit) { 124 switch (minor_unit) {
@@ -143,7 +144,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
143 goto __end; 144 goto __end;
144 snd_oss_minors[track2] = preg; 145 snd_oss_minors[track2] = preg;
145 } 146 }
146 up(&sound_oss_mutex); 147 mutex_unlock(&sound_oss_mutex);
147 return 0; 148 return 0;
148 149
149 __end: 150 __end:
@@ -152,7 +153,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
152 if (register1 >= 0) 153 if (register1 >= 0)
153 unregister_sound_special(register1); 154 unregister_sound_special(register1);
154 snd_oss_minors[minor] = NULL; 155 snd_oss_minors[minor] = NULL;
155 up(&sound_oss_mutex); 156 mutex_unlock(&sound_oss_mutex);
156 kfree(preg); 157 kfree(preg);
157 return -EBUSY; 158 return -EBUSY;
158} 159}
@@ -168,10 +169,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
168 return 0; 169 return 0;
169 if (minor < 0) 170 if (minor < 0)
170 return minor; 171 return minor;
171 down(&sound_oss_mutex); 172 mutex_lock(&sound_oss_mutex);
172 mptr = snd_oss_minors[minor]; 173 mptr = snd_oss_minors[minor];
173 if (mptr == NULL) { 174 if (mptr == NULL) {
174 up(&sound_oss_mutex); 175 mutex_unlock(&sound_oss_mutex);
175 return -ENOENT; 176 return -ENOENT;
176 } 177 }
177 unregister_sound_special(minor); 178 unregister_sound_special(minor);
@@ -191,7 +192,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
191 snd_oss_minors[track2] = NULL; 192 snd_oss_minors[track2] = NULL;
192 } 193 }
193 snd_oss_minors[minor] = NULL; 194 snd_oss_minors[minor] = NULL;
194 up(&sound_oss_mutex); 195 mutex_unlock(&sound_oss_mutex);
195 kfree(mptr); 196 kfree(mptr);
196 return 0; 197 return 0;
197} 198}
@@ -229,7 +230,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
229 int minor; 230 int minor;
230 struct snd_minor *mptr; 231 struct snd_minor *mptr;
231 232
232 down(&sound_oss_mutex); 233 mutex_lock(&sound_oss_mutex);
233 for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { 234 for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
234 if (!(mptr = snd_oss_minors[minor])) 235 if (!(mptr = snd_oss_minors[minor]))
235 continue; 236 continue;
@@ -241,7 +242,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
241 snd_iprintf(buffer, "%3i: : %s\n", minor, 242 snd_iprintf(buffer, "%3i: : %s\n", minor,
242 snd_oss_device_type_name(mptr->type)); 243 snd_oss_device_type_name(mptr->type));
243 } 244 }
244 up(&sound_oss_mutex); 245 mutex_unlock(&sound_oss_mutex);
245} 246}
246 247
247 248
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 2425b971b240..cdeeb639b675 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -25,6 +25,7 @@
25#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/time.h> 27#include <linux/time.h>
28#include <linux/mutex.h>
28#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
29#include <linux/string.h> 30#include <linux/string.h>
30#include <sound/core.h> 31#include <sound/core.h>
@@ -70,7 +71,7 @@ struct snd_timer_user {
70 struct timespec tstamp; /* trigger tstamp */ 71 struct timespec tstamp; /* trigger tstamp */
71 wait_queue_head_t qchange_sleep; 72 wait_queue_head_t qchange_sleep;
72 struct fasync_struct *fasync; 73 struct fasync_struct *fasync;
73 struct semaphore tread_sem; 74 struct mutex tread_sem;
74}; 75};
75 76
76/* list of timers */ 77/* list of timers */
@@ -82,7 +83,7 @@ static LIST_HEAD(snd_timer_slave_list);
82/* lock for slave active lists */ 83/* lock for slave active lists */
83static DEFINE_SPINLOCK(slave_active_lock); 84static DEFINE_SPINLOCK(slave_active_lock);
84 85
85static DECLARE_MUTEX(register_mutex); 86static DEFINE_MUTEX(register_mutex);
86 87
87static int snd_timer_free(struct snd_timer *timer); 88static int snd_timer_free(struct snd_timer *timer);
88static int snd_timer_dev_free(struct snd_device *device); 89static int snd_timer_dev_free(struct snd_device *device);
@@ -252,10 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
252 snd_printd("invalid slave class %i\n", tid->dev_sclass); 253 snd_printd("invalid slave class %i\n", tid->dev_sclass);
253 return -EINVAL; 254 return -EINVAL;
254 } 255 }
255 down(&register_mutex); 256 mutex_lock(&register_mutex);
256 timeri = snd_timer_instance_new(owner, NULL); 257 timeri = snd_timer_instance_new(owner, NULL);
257 if (!timeri) { 258 if (!timeri) {
258 up(&register_mutex); 259 mutex_unlock(&register_mutex);
259 return -ENOMEM; 260 return -ENOMEM;
260 } 261 }
261 timeri->slave_class = tid->dev_sclass; 262 timeri->slave_class = tid->dev_sclass;
@@ -263,37 +264,37 @@ int snd_timer_open(struct snd_timer_instance **ti,
263 timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; 264 timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
264 list_add_tail(&timeri->open_list, &snd_timer_slave_list); 265 list_add_tail(&timeri->open_list, &snd_timer_slave_list);
265 snd_timer_check_slave(timeri); 266 snd_timer_check_slave(timeri);
266 up(&register_mutex); 267 mutex_unlock(&register_mutex);
267 *ti = timeri; 268 *ti = timeri;
268 return 0; 269 return 0;
269 } 270 }
270 271
271 /* open a master instance */ 272 /* open a master instance */
272 down(&register_mutex); 273 mutex_lock(&register_mutex);
273 timer = snd_timer_find(tid); 274 timer = snd_timer_find(tid);
274#ifdef CONFIG_KMOD 275#ifdef CONFIG_KMOD
275 if (timer == NULL) { 276 if (timer == NULL) {
276 up(&register_mutex); 277 mutex_unlock(&register_mutex);
277 snd_timer_request(tid); 278 snd_timer_request(tid);
278 down(&register_mutex); 279 mutex_lock(&register_mutex);
279 timer = snd_timer_find(tid); 280 timer = snd_timer_find(tid);
280 } 281 }
281#endif 282#endif
282 if (!timer) { 283 if (!timer) {
283 up(&register_mutex); 284 mutex_unlock(&register_mutex);
284 return -ENODEV; 285 return -ENODEV;
285 } 286 }
286 if (!list_empty(&timer->open_list_head)) { 287 if (!list_empty(&timer->open_list_head)) {
287 timeri = list_entry(timer->open_list_head.next, 288 timeri = list_entry(timer->open_list_head.next,
288 struct snd_timer_instance, open_list); 289 struct snd_timer_instance, open_list);
289 if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { 290 if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
290 up(&register_mutex); 291 mutex_unlock(&register_mutex);
291 return -EBUSY; 292 return -EBUSY;
292 } 293 }
293 } 294 }
294 timeri = snd_timer_instance_new(owner, timer); 295 timeri = snd_timer_instance_new(owner, timer);
295 if (!timeri) { 296 if (!timeri) {
296 up(&register_mutex); 297 mutex_unlock(&register_mutex);
297 return -ENOMEM; 298 return -ENOMEM;
298 } 299 }
299 timeri->slave_class = tid->dev_sclass; 300 timeri->slave_class = tid->dev_sclass;
@@ -302,7 +303,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
302 timer->hw.open(timer); 303 timer->hw.open(timer);
303 list_add_tail(&timeri->open_list, &timer->open_list_head); 304 list_add_tail(&timeri->open_list, &timer->open_list_head);
304 snd_timer_check_master(timeri); 305 snd_timer_check_master(timeri);
305 up(&register_mutex); 306 mutex_unlock(&register_mutex);
306 *ti = timeri; 307 *ti = timeri;
307 return 0; 308 return 0;
308} 309}
@@ -333,9 +334,9 @@ int snd_timer_close(struct snd_timer_instance *timeri)
333 spin_lock_irq(&slave_active_lock); 334 spin_lock_irq(&slave_active_lock);
334 } 335 }
335 spin_unlock_irq(&slave_active_lock); 336 spin_unlock_irq(&slave_active_lock);
336 down(&register_mutex); 337 mutex_lock(&register_mutex);
337 list_del(&timeri->open_list); 338 list_del(&timeri->open_list);
338 up(&register_mutex); 339 mutex_unlock(&register_mutex);
339 } else { 340 } else {
340 timer = timeri->timer; 341 timer = timeri->timer;
341 /* wait, until the active callback is finished */ 342 /* wait, until the active callback is finished */
@@ -346,7 +347,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
346 spin_lock_irq(&timer->lock); 347 spin_lock_irq(&timer->lock);
347 } 348 }
348 spin_unlock_irq(&timer->lock); 349 spin_unlock_irq(&timer->lock);
349 down(&register_mutex); 350 mutex_lock(&register_mutex);
350 list_del(&timeri->open_list); 351 list_del(&timeri->open_list);
351 if (timer && list_empty(&timer->open_list_head) && 352 if (timer && list_empty(&timer->open_list_head) &&
352 timer->hw.close) 353 timer->hw.close)
@@ -362,7 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
362 slave->timer = NULL; 363 slave->timer = NULL;
363 spin_unlock_irq(&slave_active_lock); 364 spin_unlock_irq(&slave_active_lock);
364 } 365 }
365 up(&register_mutex); 366 mutex_unlock(&register_mutex);
366 } 367 }
367 if (timeri->private_free) 368 if (timeri->private_free)
368 timeri->private_free(timeri); 369 timeri->private_free(timeri);
@@ -835,7 +836,7 @@ static int snd_timer_dev_register(struct snd_device *dev)
835 !timer->hw.resolution && timer->hw.c_resolution == NULL) 836 !timer->hw.resolution && timer->hw.c_resolution == NULL)
836 return -EINVAL; 837 return -EINVAL;
837 838
838 down(&register_mutex); 839 mutex_lock(&register_mutex);
839 list_for_each(p, &snd_timer_list) { 840 list_for_each(p, &snd_timer_list) {
840 timer1 = list_entry(p, struct snd_timer, device_list); 841 timer1 = list_entry(p, struct snd_timer, device_list);
841 if (timer1->tmr_class > timer->tmr_class) 842 if (timer1->tmr_class > timer->tmr_class)
@@ -857,11 +858,11 @@ static int snd_timer_dev_register(struct snd_device *dev)
857 if (timer1->tmr_subdevice < timer->tmr_subdevice) 858 if (timer1->tmr_subdevice < timer->tmr_subdevice)
858 continue; 859 continue;
859 /* conflicts.. */ 860 /* conflicts.. */
860 up(&register_mutex); 861 mutex_unlock(&register_mutex);
861 return -EBUSY; 862 return -EBUSY;
862 } 863 }
863 list_add_tail(&timer->device_list, p); 864 list_add_tail(&timer->device_list, p);
864 up(&register_mutex); 865 mutex_unlock(&register_mutex);
865 return 0; 866 return 0;
866} 867}
867 868
@@ -871,7 +872,7 @@ static int snd_timer_unregister(struct snd_timer *timer)
871 struct snd_timer_instance *ti; 872 struct snd_timer_instance *ti;
872 873
873 snd_assert(timer != NULL, return -ENXIO); 874 snd_assert(timer != NULL, return -ENXIO);
874 down(&register_mutex); 875 mutex_lock(&register_mutex);
875 if (! list_empty(&timer->open_list_head)) { 876 if (! list_empty(&timer->open_list_head)) {
876 snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); 877 snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
877 list_for_each_safe(p, n, &timer->open_list_head) { 878 list_for_each_safe(p, n, &timer->open_list_head) {
@@ -881,7 +882,7 @@ static int snd_timer_unregister(struct snd_timer *timer)
881 } 882 }
882 } 883 }
883 list_del(&timer->device_list); 884 list_del(&timer->device_list);
884 up(&register_mutex); 885 mutex_unlock(&register_mutex);
885 return snd_timer_free(timer); 886 return snd_timer_free(timer);
886} 887}
887 888
@@ -1065,7 +1066,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1065 struct snd_timer_instance *ti; 1066 struct snd_timer_instance *ti;
1066 struct list_head *p, *q; 1067 struct list_head *p, *q;
1067 1068
1068 down(&register_mutex); 1069 mutex_lock(&register_mutex);
1069 list_for_each(p, &snd_timer_list) { 1070 list_for_each(p, &snd_timer_list) {
1070 timer = list_entry(p, struct snd_timer, device_list); 1071 timer = list_entry(p, struct snd_timer, device_list);
1071 switch (timer->tmr_class) { 1072 switch (timer->tmr_class) {
@@ -1105,7 +1106,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1105 } 1106 }
1106 spin_unlock_irqrestore(&timer->lock, flags); 1107 spin_unlock_irqrestore(&timer->lock, flags);
1107 } 1108 }
1108 up(&register_mutex); 1109 mutex_unlock(&register_mutex);
1109} 1110}
1110 1111
1111static struct snd_info_entry *snd_timer_proc_entry = NULL; 1112static struct snd_info_entry *snd_timer_proc_entry = NULL;
@@ -1269,7 +1270,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
1269 return -ENOMEM; 1270 return -ENOMEM;
1270 spin_lock_init(&tu->qlock); 1271 spin_lock_init(&tu->qlock);
1271 init_waitqueue_head(&tu->qchange_sleep); 1272 init_waitqueue_head(&tu->qchange_sleep);
1272 init_MUTEX(&tu->tread_sem); 1273 mutex_init(&tu->tread_sem);
1273 tu->ticks = 1; 1274 tu->ticks = 1;
1274 tu->queue_size = 128; 1275 tu->queue_size = 128;
1275 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), 1276 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
@@ -1325,7 +1326,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
1325 1326
1326 if (copy_from_user(&id, _tid, sizeof(id))) 1327 if (copy_from_user(&id, _tid, sizeof(id)))
1327 return -EFAULT; 1328 return -EFAULT;
1328 down(&register_mutex); 1329 mutex_lock(&register_mutex);
1329 if (id.dev_class < 0) { /* first item */ 1330 if (id.dev_class < 0) { /* first item */
1330 if (list_empty(&snd_timer_list)) 1331 if (list_empty(&snd_timer_list))
1331 snd_timer_user_zero_id(&id); 1332 snd_timer_user_zero_id(&id);
@@ -1407,7 +1408,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
1407 snd_timer_user_zero_id(&id); 1408 snd_timer_user_zero_id(&id);
1408 } 1409 }
1409 } 1410 }
1410 up(&register_mutex); 1411 mutex_unlock(&register_mutex);
1411 if (copy_to_user(_tid, &id, sizeof(*_tid))) 1412 if (copy_to_user(_tid, &id, sizeof(*_tid)))
1412 return -EFAULT; 1413 return -EFAULT;
1413 return 0; 1414 return 0;
@@ -1432,7 +1433,7 @@ static int snd_timer_user_ginfo(struct file *file,
1432 tid = ginfo->tid; 1433 tid = ginfo->tid;
1433 memset(ginfo, 0, sizeof(*ginfo)); 1434 memset(ginfo, 0, sizeof(*ginfo));
1434 ginfo->tid = tid; 1435 ginfo->tid = tid;
1435 down(&register_mutex); 1436 mutex_lock(&register_mutex);
1436 t = snd_timer_find(&tid); 1437 t = snd_timer_find(&tid);
1437 if (t != NULL) { 1438 if (t != NULL) {
1438 ginfo->card = t->card ? t->card->number : -1; 1439 ginfo->card = t->card ? t->card->number : -1;
@@ -1451,7 +1452,7 @@ static int snd_timer_user_ginfo(struct file *file,
1451 } else { 1452 } else {
1452 err = -ENODEV; 1453 err = -ENODEV;
1453 } 1454 }
1454 up(&register_mutex); 1455 mutex_unlock(&register_mutex);
1455 if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) 1456 if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
1456 err = -EFAULT; 1457 err = -EFAULT;
1457 kfree(ginfo); 1458 kfree(ginfo);
@@ -1467,7 +1468,7 @@ static int snd_timer_user_gparams(struct file *file,
1467 1468
1468 if (copy_from_user(&gparams, _gparams, sizeof(gparams))) 1469 if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
1469 return -EFAULT; 1470 return -EFAULT;
1470 down(&register_mutex); 1471 mutex_lock(&register_mutex);
1471 t = snd_timer_find(&gparams.tid); 1472 t = snd_timer_find(&gparams.tid);
1472 if (!t) { 1473 if (!t) {
1473 err = -ENODEV; 1474 err = -ENODEV;
@@ -1483,7 +1484,7 @@ static int snd_timer_user_gparams(struct file *file,
1483 } 1484 }
1484 err = t->hw.set_period(t, gparams.period_num, gparams.period_den); 1485 err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
1485_error: 1486_error:
1486 up(&register_mutex); 1487 mutex_unlock(&register_mutex);
1487 return err; 1488 return err;
1488} 1489}
1489 1490
@@ -1500,7 +1501,7 @@ static int snd_timer_user_gstatus(struct file *file,
1500 tid = gstatus.tid; 1501 tid = gstatus.tid;
1501 memset(&gstatus, 0, sizeof(gstatus)); 1502 memset(&gstatus, 0, sizeof(gstatus));
1502 gstatus.tid = tid; 1503 gstatus.tid = tid;
1503 down(&register_mutex); 1504 mutex_lock(&register_mutex);
1504 t = snd_timer_find(&tid); 1505 t = snd_timer_find(&tid);
1505 if (t != NULL) { 1506 if (t != NULL) {
1506 if (t->hw.c_resolution) 1507 if (t->hw.c_resolution)
@@ -1517,7 +1518,7 @@ static int snd_timer_user_gstatus(struct file *file,
1517 } else { 1518 } else {
1518 err = -ENODEV; 1519 err = -ENODEV;
1519 } 1520 }
1520 up(&register_mutex); 1521 mutex_unlock(&register_mutex);
1521 if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) 1522 if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
1522 err = -EFAULT; 1523 err = -EFAULT;
1523 return err; 1524 return err;
@@ -1532,7 +1533,7 @@ static int snd_timer_user_tselect(struct file *file,
1532 int err = 0; 1533 int err = 0;
1533 1534
1534 tu = file->private_data; 1535 tu = file->private_data;
1535 down(&tu->tread_sem); 1536 mutex_lock(&tu->tread_sem);
1536 if (tu->timeri) { 1537 if (tu->timeri) {
1537 snd_timer_close(tu->timeri); 1538 snd_timer_close(tu->timeri);
1538 tu->timeri = NULL; 1539 tu->timeri = NULL;
@@ -1576,7 +1577,7 @@ static int snd_timer_user_tselect(struct file *file,
1576 } 1577 }
1577 1578
1578 __err: 1579 __err:
1579 up(&tu->tread_sem); 1580 mutex_unlock(&tu->tread_sem);
1580 return err; 1581 return err;
1581} 1582}
1582 1583
@@ -1797,17 +1798,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1797 { 1798 {
1798 int xarg; 1799 int xarg;
1799 1800
1800 down(&tu->tread_sem); 1801 mutex_lock(&tu->tread_sem);
1801 if (tu->timeri) { /* too late */ 1802 if (tu->timeri) { /* too late */
1802 up(&tu->tread_sem); 1803 mutex_unlock(&tu->tread_sem);
1803 return -EBUSY; 1804 return -EBUSY;
1804 } 1805 }
1805 if (get_user(xarg, p)) { 1806 if (get_user(xarg, p)) {
1806 up(&tu->tread_sem); 1807 mutex_unlock(&tu->tread_sem);
1807 return -EFAULT; 1808 return -EFAULT;
1808 } 1809 }
1809 tu->tread = xarg ? 1 : 0; 1810 tu->tread = xarg ? 1 : 0;
1810 up(&tu->tread_sem); 1811 mutex_unlock(&tu->tread_sem);
1811 return 0; 1812 return 0;
1812 } 1813 }
1813 case SNDRV_TIMER_IOCTL_GINFO: 1814 case SNDRV_TIMER_IOCTL_GINFO: