summaryrefslogtreecommitdiffstats
path: root/drivers/sound/sonicvibes.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sound/sonicvibes.c')
-rw-r--r--drivers/sound/sonicvibes.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c
index c9c66a73f..8a082552a 100644
--- a/drivers/sound/sonicvibes.c
+++ b/drivers/sound/sonicvibes.c
@@ -108,6 +108,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -1509,29 +1510,35 @@ static int sv_mmap(struct file *file, struct vm_area_struct *vma)
{
struct sv_state *s = (struct sv_state *)file->private_data;
struct dmabuf *db;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(s, 1)) != 0)
- return ret;
+ goto out;
db = &s->dma_dac;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(s, 0)) != 0)
- return ret;
+ goto out;
db = &s->dma_adc;
} else
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
db->mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1907,6 +1914,7 @@ static int sv_release(struct inode *inode, struct file *file)
struct sv_state *s = (struct sv_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -1921,6 +1929,7 @@ static int sv_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -2167,6 +2176,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
add_wait_queue(&s->midi.owait, &wait);
for (;;) {
@@ -2200,6 +2210,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -2363,6 +2374,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
unsigned int regb;
VALIDATE_STATE(s);
+ lock_kernel();
down(&s->open_sem);
s->open_mode &= ~FMODE_DMFM;
for (regb = 0xb0; regb < 0xb9; regb++) {
@@ -2373,6 +2385,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
}
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}