SH: remove superfluous warning from the serial driver
[linux-2.6.git] / drivers / input / joydev.c
index 9a1d55b..c52bec4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
@@ -285,6 +286,8 @@ static int joydev_open(struct inode *inode, struct file *file)
                goto err_free_client;
 
        file->private_data = client;
+       nonseekable_open(inode, file);
+
        return 0;
 
  err_free_client:
@@ -452,6 +455,76 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
                (joydev->exist ?  0 : (POLLHUP | POLLERR));
 }
 
+static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
+                                    void __user *argp, size_t len)
+{
+       __u8 *abspam;
+       int i;
+       int retval = 0;
+
+       len = min(len, sizeof(joydev->abspam));
+
+       /* Validate the map. */
+       abspam = kmalloc(len, GFP_KERNEL);
+       if (!abspam)
+               return -ENOMEM;
+
+       if (copy_from_user(abspam, argp, len)) {
+               retval = -EFAULT;
+               goto out;
+       }
+
+       for (i = 0; i < joydev->nabs; i++) {
+               if (abspam[i] > ABS_MAX) {
+                       retval = -EINVAL;
+                       goto out;
+               }
+       }
+
+       memcpy(joydev->abspam, abspam, len);
+
+ out:
+       kfree(abspam);
+       return retval;
+}
+
+static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
+                                     void __user *argp, size_t len)
+{
+       __u16 *keypam;
+       int i;
+       int retval = 0;
+
+       len = min(len, sizeof(joydev->keypam));
+
+       /* Validate the map. */
+       keypam = kmalloc(len, GFP_KERNEL);
+       if (!keypam)
+               return -ENOMEM;
+
+       if (copy_from_user(keypam, argp, len)) {
+               retval = -EFAULT;
+               goto out;
+       }
+
+       for (i = 0; i < joydev->nkey; i++) {
+               if (keypam[i] > KEY_MAX || keypam[i] < BTN_MISC) {
+                       retval = -EINVAL;
+                       goto out;
+               }
+       }
+
+       memcpy(joydev->keypam, keypam, len);
+
+       for (i = 0; i < joydev->nkey; i++)
+               joydev->keymap[keypam[i] - BTN_MISC] = i;
+
+ out:
+       kfree(keypam);
+       return retval;
+}
+
+
 static int joydev_ioctl_common(struct joydev *joydev,
                                unsigned int cmd, void __user *argp)
 {
@@ -512,46 +585,18 @@ static int joydev_ioctl_common(struct joydev *joydev,
        switch (cmd & ~IOCSIZE_MASK) {
 
        case (JSIOCSAXMAP & ~IOCSIZE_MASK):
-               len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
-               /*
-                * FIXME: we should not copy into our axis map before
-                * validating the data.
-                */
-               if (copy_from_user(joydev->abspam, argp, len))
-                       return -EFAULT;
-
-               for (i = 0; i < joydev->nabs; i++) {
-                       if (joydev->abspam[i] > ABS_MAX)
-                               return -EINVAL;
-                       joydev->absmap[joydev->abspam[i]] = i;
-               }
-               return 0;
+               return joydev_handle_JSIOCSAXMAP(joydev, argp, _IOC_SIZE(cmd));
 
        case (JSIOCGAXMAP & ~IOCSIZE_MASK):
                len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
-               return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
+               return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : len;
 
        case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
-               len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
-               /*
-                * FIXME: we should not copy into our keymap before
-                * validating the data.
-                */
-               if (copy_from_user(joydev->keypam, argp, len))
-                       return -EFAULT;
-
-               for (i = 0; i < joydev->nkey; i++) {
-                       if (joydev->keypam[i] > KEY_MAX ||
-                           joydev->keypam[i] < BTN_MISC)
-                               return -EINVAL;
-                       joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
-               }
-
-               return 0;
+               return joydev_handle_JSIOCSBTNMAP(joydev, argp, _IOC_SIZE(cmd));
 
        case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
                len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
-               return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
+               return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : len;
 
        case JSIOCGNAME(0):
                name = dev->name;
@@ -732,6 +777,20 @@ static void joydev_cleanup(struct joydev *joydev)
                input_close_device(handle);
 }
 
+
+static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
+{
+       /* Avoid touchpads and touchscreens */
+       if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
+               return false;
+
+       /* Avoid tablets, digitisers and similar devices */
+       if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
+               return false;
+
+       return true;
+}
+
 static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
                          const struct input_device_id *id)
 {
@@ -851,22 +910,6 @@ static void joydev_disconnect(struct input_handle *handle)
        put_device(&joydev->dev);
 }
 
-static const struct input_device_id joydev_blacklist[] = {
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
-                               INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
-       },      /* Avoid itouchpads and touchscreens */
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
-                               INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
-       },      /* Avoid tablets, digitisers and similar devices */
-       { }     /* Terminating entry */
-};
-
 static const struct input_device_id joydev_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
@@ -893,13 +936,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids);
 
 static struct input_handler joydev_handler = {
        .event          = joydev_event,
+       .match          = joydev_match,
        .connect        = joydev_connect,
        .disconnect     = joydev_disconnect,
        .fops           = &joydev_fops,
        .minor          = JOYDEV_MINOR_BASE,
        .name           = "joydev",
        .id_table       = joydev_ids,
-       .blacklist      = joydev_blacklist,
 };
 
 static int __init joydev_init(void)