summaryrefslogtreecommitdiffstats
path: root/drivers/sgi
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-04-24 20:14:13 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-04-24 20:14:13 +0000
commit8cd976ba68296d98ac18c0b32b28f152a5344ce4 (patch)
treef1e6ef68cdd338ed3caaab2e3d974220b34bccb4 /drivers/sgi
parentb300fe5b8a34b50493217d022bf3830d64d74656 (diff)
Get locking and semaphores right.
Diffstat (limited to 'drivers/sgi')
-rw-r--r--drivers/sgi/char/shmiq.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c
index 9b4069c37..4f0a993da 100644
--- a/drivers/sgi/char/shmiq.c
+++ b/drivers/sgi/char/shmiq.c
@@ -237,8 +237,8 @@ shmiq_ioctl (struct inode *inode, struct file *f, unsigned int cmd, unsigned lon
}
return -EINVAL;
+
bad_file:
- unlock_kernel ();
return -EBADF;
}
@@ -251,46 +251,58 @@ qcntl_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned
struct vm_area_struct *vma;
int v;
- switch (cmd){
+ switch (cmd) {
/*
* The address space is already mapped as a /dev/zero
* mapping. FIXME: check that /dev/zero is what the user
* had mapped before :-)
*/
- case QIOCATTACH: {
- unsigned long vaddr;
- int s;
-
- v = verify_area (VERIFY_READ, (void *) arg, sizeof (struct shmiqreq));
- if (v)
- return v;
- if (copy_from_user (&req, (void *) arg, sizeof (req)))
- return -EFAULT;
- /* Do not allow to attach to another region if it has been already attached */
- if (shmiqs [minor].mapped){
- printk ("SHMIQ:The thingie is already mapped\n");
- return -EINVAL;
- }
-
- vaddr = (unsigned long) req.user_vaddr;
- vma = find_vma (current->mm, vaddr);
- if (!vma){
- printk ("SHMIQ: could not find %lx the vma\n", vaddr);
- return -EINVAL;
+ case QIOCATTACH: {
+ unsigned long vaddr;
+ int s;
+
+ v = verify_area (VERIFY_READ, (void *) arg,
+ sizeof (struct shmiqreq));
+ if (v)
+ return v;
+ if (copy_from_user(&req, (void *) arg, sizeof (req)))
+ return -EFAULT;
+ /*
+ * Do not allow to attach to another region if it has
+ * already been attached
+ */
+ if (shmiqs [minor].mapped) {
+ printk("SHMIQ:The thingie is already mapped\n");
+ return -EINVAL;
+ }
+
+ vaddr = (unsigned long) req.user_vaddr;
+ vma = find_vma (current->mm, vaddr);
+ if (!vma) {
+ printk ("SHMIQ: could not find %lx the vma\n",
+ vaddr);
+ return -EINVAL;
+ }
+ s = req.arg * sizeof (struct shmqevent) +
+ sizeof (struct sharedMemoryInputQueue);
+ v = sys_munmap (vaddr, s);
+ down(&current->mmap_sem);
+ do_mmap(filp, vaddr, s, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE|MAP_FIXED, 0);
+ up(&current->mmap_sem);
+ shmiqs[minor].events = req.arg;
+ shmiqs[minor].mapped = 1;
+
+ return 0;
}
- s = req.arg * sizeof (struct shmqevent) + sizeof (struct sharedMemoryInputQueue);
- v = sys_munmap (vaddr, s);
- do_mmap (filp, vaddr, s, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 0);
- shmiqs [minor].events = req.arg;
- shmiqs [minor].mapped = 1;
- return 0;
- }
}
+
return -EINVAL;
}
unsigned long
-shmiq_nopage (struct vm_area_struct *vma, unsigned long address, int write_access)
+shmiq_nopage (struct vm_area_struct *vma, unsigned long address,
+ int write_access)
{
/* Do not allow for mremap to expand us */
return 0;
@@ -335,14 +347,12 @@ shmiq_qcntl_mmap (struct file *file, struct vm_area_struct *vma)
return error;
}
-
+
static int
shmiq_qcntl_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
int minor = MINOR (inode->i_rdev);
- lock_kernel ();
-
if (minor-- == 0)
return shmiq_ioctl (inode, filp, cmd, arg);
@@ -386,6 +396,7 @@ shmiq_qcntl_open (struct inode *inode, struct file *filp)
shmiqs [minor].opened = 1;
shmiqs [minor].shmiq_vaddr = 0;
unlock_kernel ();
+
return 0;
}
@@ -426,6 +437,7 @@ shmiq_qcntl_close (struct inode *inode, struct file *filp)
vfree (shmiqs [minor].shmiq_vaddr);
shmiqs [minor].shmiq_vaddr = 0;
unlock_kernel ();
+
return 0;
}