diff options
Diffstat (limited to 'drivers/sound/sonicvibes.c')
-rw-r--r-- | drivers/sound/sonicvibes.c | 29 |
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; } |