summaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-05-26 11:25:20 +0200
committerJiri Kosina <jkosina@suse.cz>2008-07-23 15:21:54 +0200
commit7961df16819085b8a357720d89d0239036e6af2a (patch)
tree3578e14f300bbfc78f1658801e850b2cd0f2cca9 /drivers/hid
parent6f0168d2dacd7972d887e1ca27943ef8af7512a5 (diff)
HID: Switch hiddev to unlocked_ioctl
Push down the BKL. In some cases compat_ioctl already doesn't take the BKL so we don't either. Some of the locking here seems already dubious and object lifetimes want documenting Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/usbhid/hiddev.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 95cc192bc7af..fe4f36472cb7 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
if (!uref_multi)
return -ENOMEM;
+ lock_kernel();
uref = &uref_multi->uref;
if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
if (copy_from_user(uref_multi, user_arg,
@@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
}
goodreturn:
+ unlock_kernel();
kfree(uref_multi);
return 0;
fault:
+ unlock_kernel();
kfree(uref_multi);
return -EFAULT;
inval:
+ unlock_kernel();
kfree(uref_multi);
return -EINVAL;
}
@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd,
return len;
}
-static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct hiddev_list *list = file->private_data;
struct hiddev *hiddev = list->hiddev;
@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct usbhid_device *usbhid = hid->driver_data;
void __user *user_arg = (void __user *)arg;
int i;
+
+ /* Called without BKL by compat methods so no BKL taken */
+ /* FIXME: Who or what stop this racing with a disconnect ?? */
if (!hiddev->exist)
return -EIO;
@@ -768,7 +775,7 @@ static const struct file_operations hiddev_fops = {
.poll = hiddev_poll,
.open = hiddev_open,
.release = hiddev_release,
- .ioctl = hiddev_ioctl,
+ .unlocked_ioctl = hiddev_ioctl,
.fasync = hiddev_fasync,
#ifdef CONFIG_COMPAT
.compat_ioctl = hiddev_compat_ioctl,