aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-07-11 06:16:36 -0400
committerTakashi Iwai <tiwai@suse.de>2010-07-12 11:41:05 -0400
commit90dc763fef4c869e60b2a7ad92e1a7dab68575ea (patch)
treeab3757f14a6d84e36afa36ac5f325fd316d4e197 /sound
parent395c61d19621e80b763810cc988416dc1b6bfd3e (diff)
sound: push BKL into open functions
This moves the lock_kernel() call from soundcore_open to the individual OSS device drivers, where we can deal with it one driver at a time if needed, or just kill off the drivers. All core components in ALSA already provide adequate locking in their open()-functions and do not require the big kernel lock, so there is no need to add the BKL there. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/oss/au1550_ac97.c26
-rw-r--r--sound/oss/dmasound/dmasound_core.c28
-rw-r--r--sound/oss/msnd_pinnacle.c10
-rw-r--r--sound/oss/sh_dac_audio.c9
-rw-r--r--sound/oss/soundcard.c20
-rw-r--r--sound/oss/swarm_cs4297a.c17
-rw-r--r--sound/oss/vwsnd.c8
-rw-r--r--sound/sound_core.c6
8 files changed, 89 insertions, 35 deletions
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index c1070e33b32..fb913e568de 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -43,6 +43,7 @@
43#include <linux/sound.h> 43#include <linux/sound.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/soundcard.h> 45#include <linux/soundcard.h>
46#include <linux/smp_lock.h>
46#include <linux/init.h> 47#include <linux/init.h>
47#include <linux/interrupt.h> 48#include <linux/interrupt.h>
48#include <linux/kernel.h> 49#include <linux/kernel.h>
@@ -807,7 +808,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin)
807static int 808static int
808au1550_open_mixdev(struct inode *inode, struct file *file) 809au1550_open_mixdev(struct inode *inode, struct file *file)
809{ 810{
811 lock_kernel();
810 file->private_data = &au1550_state; 812 file->private_data = &au1550_state;
813 unlock_kernel();
811 return 0; 814 return 0;
812} 815}
813 816
@@ -1797,21 +1800,22 @@ au1550_open(struct inode *inode, struct file *file)
1797#endif 1800#endif
1798 1801
1799 file->private_data = s; 1802 file->private_data = s;
1803 lock_kernel();
1800 /* wait for device to become free */ 1804 /* wait for device to become free */
1801 mutex_lock(&s->open_mutex); 1805 mutex_lock(&s->open_mutex);
1802 while (s->open_mode & file->f_mode) { 1806 while (s->open_mode & file->f_mode) {
1803 if (file->f_flags & O_NONBLOCK) { 1807 ret = -EBUSY;
1804 mutex_unlock(&s->open_mutex); 1808 if (file->f_flags & O_NONBLOCK)
1805 return -EBUSY; 1809 goto out;
1806 }
1807 add_wait_queue(&s->open_wait, &wait); 1810 add_wait_queue(&s->open_wait, &wait);
1808 __set_current_state(TASK_INTERRUPTIBLE); 1811 __set_current_state(TASK_INTERRUPTIBLE);
1809 mutex_unlock(&s->open_mutex); 1812 mutex_unlock(&s->open_mutex);
1810 schedule(); 1813 schedule();
1811 remove_wait_queue(&s->open_wait, &wait); 1814 remove_wait_queue(&s->open_wait, &wait);
1812 set_current_state(TASK_RUNNING); 1815 set_current_state(TASK_RUNNING);
1816 ret = -ERESTARTSYS;
1813 if (signal_pending(current)) 1817 if (signal_pending(current))
1814 return -ERESTARTSYS; 1818 goto out2;
1815 mutex_lock(&s->open_mutex); 1819 mutex_lock(&s->open_mutex);
1816 } 1820 }
1817 1821
@@ -1840,17 +1844,21 @@ au1550_open(struct inode *inode, struct file *file)
1840 1844
1841 if (file->f_mode & FMODE_READ) { 1845 if (file->f_mode & FMODE_READ) {
1842 if ((ret = prog_dmabuf_adc(s))) 1846 if ((ret = prog_dmabuf_adc(s)))
1843 return ret; 1847 goto out;
1844 } 1848 }
1845 if (file->f_mode & FMODE_WRITE) { 1849 if (file->f_mode & FMODE_WRITE) {
1846 if ((ret = prog_dmabuf_dac(s))) 1850 if ((ret = prog_dmabuf_dac(s)))
1847 return ret; 1851 goto out;
1848 } 1852 }
1849 1853
1850 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 1854 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1851 mutex_unlock(&s->open_mutex);
1852 mutex_init(&s->sem); 1855 mutex_init(&s->sem);
1853 return 0; 1856 ret = 0;
1857out:
1858 mutex_unlock(&s->open_mutex);
1859out2:
1860 unlock_kernel();
1861 return ret;
1854} 1862}
1855 1863
1856static int 1864static int
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 3f3c3f71db4..5a4f38c0f48 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -323,9 +323,13 @@ static struct {
323 323
324static int mixer_open(struct inode *inode, struct file *file) 324static int mixer_open(struct inode *inode, struct file *file)
325{ 325{
326 if (!try_module_get(dmasound.mach.owner)) 326 lock_kernel();
327 if (!try_module_get(dmasound.mach.owner)) {
328 unlock_kernel();
327 return -ENODEV; 329 return -ENODEV;
330 }
328 mixer.busy = 1; 331 mixer.busy = 1;
332 unlock_kernel();
329 return 0; 333 return 0;
330} 334}
331 335
@@ -737,8 +741,11 @@ static int sq_open(struct inode *inode, struct file *file)
737{ 741{
738 int rc; 742 int rc;
739 743
740 if (!try_module_get(dmasound.mach.owner)) 744 lock_kernel();
745 if (!try_module_get(dmasound.mach.owner)) {
746 unlock_kernel();
741 return -ENODEV; 747 return -ENODEV;
748 }
742 749
743 rc = write_sq_open(file); /* checks the f_mode */ 750 rc = write_sq_open(file); /* checks the f_mode */
744 if (rc) 751 if (rc)
@@ -781,10 +788,11 @@ static int sq_open(struct inode *inode, struct file *file)
781 sound_set_format(AFMT_MU_LAW); 788 sound_set_format(AFMT_MU_LAW);
782 } 789 }
783#endif 790#endif
784 791 unlock_kernel();
785 return 0; 792 return 0;
786 out: 793 out:
787 module_put(dmasound.mach.owner); 794 module_put(dmasound.mach.owner);
795 unlock_kernel();
788 return rc; 796 return rc;
789} 797}
790 798
@@ -1226,12 +1234,17 @@ static int state_open(struct inode *inode, struct file *file)
1226{ 1234{
1227 char *buffer = state.buf; 1235 char *buffer = state.buf;
1228 int len = 0; 1236 int len = 0;
1237 int ret;
1229 1238
1239 lock_kernel();
1240 ret = -EBUSY;
1230 if (state.busy) 1241 if (state.busy)
1231 return -EBUSY; 1242 goto out;
1232 1243
1244 ret = -ENODEV;
1233 if (!try_module_get(dmasound.mach.owner)) 1245 if (!try_module_get(dmasound.mach.owner))
1234 return -ENODEV; 1246 goto out;
1247
1235 state.ptr = 0; 1248 state.ptr = 0;
1236 state.busy = 1; 1249 state.busy = 1;
1237 1250
@@ -1293,7 +1306,10 @@ printk("dmasound: stat buffer used %d bytes\n", len) ;
1293 printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n"); 1306 printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
1294 1307
1295 state.len = len; 1308 state.len = len;
1296 return 0; 1309 ret = 0;
1310out:
1311 unlock_kernel();
1312 return ret;
1297} 1313}
1298 1314
1299static int state_release(struct inode *inode, struct file *file) 1315static int state_release(struct inode *inode, struct file *file)
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index a1e3f9671be..153d822bf9a 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -756,12 +756,15 @@ static int dev_open(struct inode *inode, struct file *file)
756 int minor = iminor(inode); 756 int minor = iminor(inode);
757 int err = 0; 757 int err = 0;
758 758
759 lock_kernel();
759 if (minor == dev.dsp_minor) { 760 if (minor == dev.dsp_minor) {
760 if ((file->f_mode & FMODE_WRITE && 761 if ((file->f_mode & FMODE_WRITE &&
761 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) || 762 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
762 (file->f_mode & FMODE_READ && 763 (file->f_mode & FMODE_READ &&
763 test_bit(F_AUDIO_READ_INUSE, &dev.flags))) 764 test_bit(F_AUDIO_READ_INUSE, &dev.flags))) {
764 return -EBUSY; 765 err = -EBUSY;
766 goto out;
767 }
765 768
766 if ((err = dsp_open(file)) >= 0) { 769 if ((err = dsp_open(file)) >= 0) {
767 dev.nresets = 0; 770 dev.nresets = 0;
@@ -782,7 +785,8 @@ static int dev_open(struct inode *inode, struct file *file)
782 /* nothing */ 785 /* nothing */
783 } else 786 } else
784 err = -EINVAL; 787 err = -EINVAL;
785 788out:
789 unlock_kernel();
786 return err; 790 return err;
787} 791}
788 792
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index 4153752507e..8f0be4053a5 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/sound.h> 18#include <linux/sound.h>
19#include <linux/smp_lock.h>
19#include <linux/soundcard.h> 20#include <linux/soundcard.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/hrtimer.h> 22#include <linux/hrtimer.h>
@@ -216,13 +217,17 @@ static int dac_audio_open(struct inode *inode, struct file *file)
216{ 217{
217 if (file->f_mode & FMODE_READ) 218 if (file->f_mode & FMODE_READ)
218 return -ENODEV; 219 return -ENODEV;
219 if (in_use) 220
221 lock_kernel();
222 if (in_use) {
223 unlock_kernel();
220 return -EBUSY; 224 return -EBUSY;
225 }
221 226
222 in_use = 1; 227 in_use = 1;
223 228
224 dac_audio_start(); 229 dac_audio_start();
225 230 unlock_kernel();
226 return 0; 231 return 0;
227} 232}
228 233
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 2d9c5131262..92aa762ffb7 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -210,42 +210,44 @@ static int sound_open(struct inode *inode, struct file *file)
210 printk(KERN_ERR "Invalid minor device %d\n", dev); 210 printk(KERN_ERR "Invalid minor device %d\n", dev);
211 return -ENXIO; 211 return -ENXIO;
212 } 212 }
213 lock_kernel();
213 switch (dev & 0x0f) { 214 switch (dev & 0x0f) {
214 case SND_DEV_CTL: 215 case SND_DEV_CTL:
215 dev >>= 4; 216 dev >>= 4;
216 if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) { 217 if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
217 request_module("mixer%d", dev); 218 request_module("mixer%d", dev);
218 } 219 }
220 retval = -ENXIO;
219 if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL)) 221 if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
220 return -ENXIO; 222 break;
221 223
222 if (!try_module_get(mixer_devs[dev]->owner)) 224 if (!try_module_get(mixer_devs[dev]->owner))
223 return -ENXIO; 225 break;
226
227 retval = 0;
224 break; 228 break;
225 229
226 case SND_DEV_SEQ: 230 case SND_DEV_SEQ:
227 case SND_DEV_SEQ2: 231 case SND_DEV_SEQ2:
228 if ((retval = sequencer_open(dev, file)) < 0) 232 retval = sequencer_open(dev, file);
229 return retval;
230 break; 233 break;
231 234
232 case SND_DEV_MIDIN: 235 case SND_DEV_MIDIN:
233 if ((retval = MIDIbuf_open(dev, file)) < 0) 236 retval = MIDIbuf_open(dev, file);
234 return retval;
235 break; 237 break;
236 238
237 case SND_DEV_DSP: 239 case SND_DEV_DSP:
238 case SND_DEV_DSP16: 240 case SND_DEV_DSP16:
239 case SND_DEV_AUDIO: 241 case SND_DEV_AUDIO:
240 if ((retval = audio_open(dev, file)) < 0) 242 retval = audio_open(dev, file);
241 return retval;
242 break; 243 break;
243 244
244 default: 245 default:
245 printk(KERN_ERR "Invalid minor device %d\n", dev); 246 printk(KERN_ERR "Invalid minor device %d\n", dev);
246 return -ENXIO; 247 retval = -ENXIO;
247 } 248 }
248 249
250 unlock_kernel();
249 return 0; 251 return 0;
250} 252}
251 253
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 3136c88eacd..34b0838793a 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -68,6 +68,7 @@
68#include <linux/delay.h> 68#include <linux/delay.h>
69#include <linux/sound.h> 69#include <linux/sound.h>
70#include <linux/slab.h> 70#include <linux/slab.h>
71#include <linux/smp_lock.h>
71#include <linux/soundcard.h> 72#include <linux/soundcard.h>
72#include <linux/ac97_codec.h> 73#include <linux/ac97_codec.h>
73#include <linux/pci.h> 74#include <linux/pci.h>
@@ -1534,6 +1535,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1534 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, 1535 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
1535 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n")); 1536 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n"));
1536 1537
1538 lock_kernel();
1537 list_for_each(entry, &cs4297a_devs) 1539 list_for_each(entry, &cs4297a_devs)
1538 { 1540 {
1539 s = list_entry(entry, struct cs4297a_state, list); 1541 s = list_entry(entry, struct cs4297a_state, list);
@@ -1544,6 +1546,8 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1544 { 1546 {
1545 CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, 1547 CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
1546 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n")); 1548 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n"));
1549
1550 unlock_kernel();
1547 return -ENODEV; 1551 return -ENODEV;
1548 } 1552 }
1549 VALIDATE_STATE(s); 1553 VALIDATE_STATE(s);
@@ -1551,6 +1555,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1551 1555
1552 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, 1556 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
1553 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n")); 1557 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n"));
1558 unlock_kernel();
1554 1559
1555 return nonseekable_open(inode, file); 1560 return nonseekable_open(inode, file);
1556} 1561}
@@ -2369,7 +2374,7 @@ static int cs4297a_release(struct inode *inode, struct file *file)
2369 return 0; 2374 return 0;
2370} 2375}
2371 2376
2372static int cs4297a_open(struct inode *inode, struct file *file) 2377static int cs4297a_locked_open(struct inode *inode, struct file *file)
2373{ 2378{
2374 int minor = iminor(inode); 2379 int minor = iminor(inode);
2375 struct cs4297a_state *s=NULL; 2380 struct cs4297a_state *s=NULL;
@@ -2486,6 +2491,16 @@ static int cs4297a_open(struct inode *inode, struct file *file)
2486 return nonseekable_open(inode, file); 2491 return nonseekable_open(inode, file);
2487} 2492}
2488 2493
2494static int cs4297a_open(struct inode *inode, struct file *file)
2495{
2496 int ret;
2497
2498 lock_kernel();
2499 ret = cs4297a_open(inode, file);
2500 unlock_kernel();
2501
2502 return ret;
2503}
2489 2504
2490// ****************************************************************************************** 2505// ******************************************************************************************
2491// Wave (audio) file operations struct. 2506// Wave (audio) file operations struct.
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 20b3b325aa8..99c94c48558 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2921 2921
2922 DBGE("(inode=0x%p, file=0x%p)\n", inode, file); 2922 DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
2923 2923
2924 lock_kernel();
2924 INC_USE_COUNT; 2925 INC_USE_COUNT;
2925 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 2926 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
2926 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) 2927 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
@@ -2928,6 +2929,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2928 2929
2929 if (devc == NULL) { 2930 if (devc == NULL) {
2930 DEC_USE_COUNT; 2931 DEC_USE_COUNT;
2932 unlock_kernel();
2931 return -ENODEV; 2933 return -ENODEV;
2932 } 2934 }
2933 2935
@@ -2936,11 +2938,13 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2936 mutex_unlock(&devc->open_mutex); 2938 mutex_unlock(&devc->open_mutex);
2937 if (file->f_flags & O_NONBLOCK) { 2939 if (file->f_flags & O_NONBLOCK) {
2938 DEC_USE_COUNT; 2940 DEC_USE_COUNT;
2941 unlock_kernel();
2939 return -EBUSY; 2942 return -EBUSY;
2940 } 2943 }
2941 interruptible_sleep_on(&devc->open_wait); 2944 interruptible_sleep_on(&devc->open_wait);
2942 if (signal_pending(current)) { 2945 if (signal_pending(current)) {
2943 DEC_USE_COUNT; 2946 DEC_USE_COUNT;
2947 unlock_kernel();
2944 return -ERESTARTSYS; 2948 return -ERESTARTSYS;
2945 } 2949 }
2946 mutex_lock(&devc->open_mutex); 2950 mutex_lock(&devc->open_mutex);
@@ -2993,6 +2997,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2993 2997
2994 file->private_data = devc; 2998 file->private_data = devc;
2995 DBGRV(); 2999 DBGRV();
3000 unlock_kernel();
2996 return 0; 3001 return 0;
2997} 3002}
2998 3003
@@ -3062,15 +3067,18 @@ static int vwsnd_mixer_open(struct inode *inode, struct file *file)
3062 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3067 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
3063 3068
3064 INC_USE_COUNT; 3069 INC_USE_COUNT;
3070 lock_kernel();
3065 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 3071 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
3066 if (devc->mixer_minor == iminor(inode)) 3072 if (devc->mixer_minor == iminor(inode))
3067 break; 3073 break;
3068 3074
3069 if (devc == NULL) { 3075 if (devc == NULL) {
3070 DEC_USE_COUNT; 3076 DEC_USE_COUNT;
3077 unlock_kernel();
3071 return -ENODEV; 3078 return -ENODEV;
3072 } 3079 }
3073 file->private_data = devc; 3080 file->private_data = devc;
3081 unlock_kernel();
3074 return 0; 3082 return 0;
3075} 3083}
3076 3084
diff --git a/sound/sound_core.c b/sound/sound_core.c
index c8627fcd490..cb61317df50 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -629,12 +629,8 @@ static int soundcore_open(struct inode *inode, struct file *file)
629 file->f_op = new_fops; 629 file->f_op = new_fops;
630 spin_unlock(&sound_loader_lock); 630 spin_unlock(&sound_loader_lock);
631 631
632 if (file->f_op->open) { 632 if (file->f_op->open)
633 /* TODO: push down BKL into indivial open functions */
634 lock_kernel();
635 err = file->f_op->open(inode,file); 633 err = file->f_op->open(inode,file);
636 unlock_kernel();
637 }
638 634
639 if (err) { 635 if (err) {
640 fops_put(file->f_op); 636 fops_put(file->f_op);