]> Git Repo - linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <[email protected]>
Sat, 7 Jan 2006 19:29:51 +0000 (11:29 -0800)
committerLinus Torvalds <[email protected]>
Sat, 7 Jan 2006 19:29:51 +0000 (11:29 -0800)
1  2 
drivers/input/evdev.c

diff --combined drivers/input/evdev.c
index a1e660e3531d381dc5fbb930d65bbb4b94ade3a1,0270d1ec9425b27a329774a3eb9625a5c808c760..f7490a015d18a667e979cb68e0654d6a1e49c370
@@@ -146,6 -146,7 +146,7 @@@ static int evdev_open(struct inode * in
  }
  
  #ifdef CONFIG_COMPAT
  struct input_event_compat {
        struct compat_timeval time;
        __u16 type;
  #  define COMPAT_TEST test_thread_flag(TIF_IA32)
  #elif defined(CONFIG_IA64)
  #  define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
 -#elif defined(CONFIG_ARCH_S390)
 +#elif defined(CONFIG_S390)
  #  define COMPAT_TEST test_thread_flag(TIF_31BIT)
  #elif defined(CONFIG_MIPS)
  #  define COMPAT_TEST (current->thread.mflags & MF_32BIT_ADDR)
  #  define COMPAT_TEST test_thread_flag(TIF_32BIT)
  #endif
  
- static ssize_t evdev_write_compat(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
+ static inline size_t evdev_event_size(void)
  {
-       struct evdev_list *list = file->private_data;
-       struct input_event_compat event;
-       int retval = 0;
+       return COMPAT_TEST ?
+               sizeof(struct input_event_compat) : sizeof(struct input_event);
+ }
  
-       while (retval < count) {
-               if (copy_from_user(&event, buffer + retval, sizeof(struct input_event_compat)))
+ static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
+ {
+       if (COMPAT_TEST) {
+               struct input_event_compat compat_event;
+               if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat)))
+                       return -EFAULT;
+               event->time.tv_sec = compat_event.time.tv_sec;
+               event->time.tv_usec = compat_event.time.tv_usec;
+               event->type = compat_event.type;
+               event->code = compat_event.code;
+               event->value = compat_event.value;
+       } else {
+               if (copy_from_user(event, buffer, sizeof(struct input_event)))
                        return -EFAULT;
-               input_event(list->evdev->handle.dev, event.type, event.code, event.value);
-               retval += sizeof(struct input_event_compat);
        }
  
-       return retval;
+       return 0;
  }
- #endif
  
- static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
+ static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
  {
-       struct evdev_list *list = file->private_data;
-       struct input_event event;
-       int retval = 0;
-       if (!list->evdev->exist) return -ENODEV;
+       if (COMPAT_TEST) {
+               struct input_event_compat compat_event;
  
- #ifdef CONFIG_COMPAT
-       if (COMPAT_TEST)
-               return evdev_write_compat(file, buffer, count, ppos);
- #endif
+               compat_event.time.tv_sec = event->time.tv_sec;
+               compat_event.time.tv_usec = event->time.tv_usec;
+               compat_event.type = event->type;
+               compat_event.code = event->code;
+               compat_event.value = event->value;
  
-       while (retval < count) {
+               if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat)))
+                       return -EFAULT;
  
-               if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
+       } else {
+               if (copy_to_user(buffer, event, sizeof(struct input_event)))
                        return -EFAULT;
-               input_event(list->evdev->handle.dev, event.type, event.code, event.value);
-               retval += sizeof(struct input_event);
        }
  
-       return retval;
+       return 0;
  }
  
- #ifdef CONFIG_COMPAT
- static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
+ #else
+ static inline size_t evdev_event_size(void)
  {
-       struct evdev_list *list = file->private_data;
-       int retval;
+       return sizeof(struct input_event);
+ }
  
-       if (count < sizeof(struct input_event_compat))
-               return -EINVAL;
+ static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
+ {
+       if (copy_from_user(event, buffer, sizeof(struct input_event)))
+               return -EFAULT;
  
-       if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
-               return -EAGAIN;
+       return 0;
+ }
  
-       retval = wait_event_interruptible(list->evdev->wait,
-               list->head != list->tail || (!list->evdev->exist));
+ static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
+ {
+       if (copy_to_user(buffer, event, sizeof(struct input_event)))
+               return -EFAULT;
  
-       if (retval)
-               return retval;
+       return 0;
+ }
+ #endif /* CONFIG_COMPAT */
+ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
+ {
+       struct evdev_list *list = file->private_data;
+       struct input_event event;
+       int retval = 0;
  
        if (!list->evdev->exist)
                return -ENODEV;
  
-       while (list->head != list->tail && retval + sizeof(struct input_event_compat) <= count) {
-               struct input_event *event = (struct input_event *) list->buffer + list->tail;
-               struct input_event_compat event_compat;
-               event_compat.time.tv_sec = event->time.tv_sec;
-               event_compat.time.tv_usec = event->time.tv_usec;
-               event_compat.type = event->type;
-               event_compat.code = event->code;
-               event_compat.value = event->value;
-               if (copy_to_user(buffer + retval, &event_compat,
-                       sizeof(struct input_event_compat))) return -EFAULT;
-               list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
-               retval += sizeof(struct input_event_compat);
+       while (retval < count) {
+               if (evdev_event_from_user(buffer + retval, &event))
+                       return -EFAULT;
+               input_event(list->evdev->handle.dev, event.type, event.code, event.value);
+               retval += evdev_event_size();
        }
  
        return retval;
  }
- #endif
  
  static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
  {
        struct evdev_list *list = file->private_data;
        int retval;
  
- #ifdef CONFIG_COMPAT
-       if (COMPAT_TEST)
-               return evdev_read_compat(file, buffer, count, ppos);
- #endif
-       if (count < sizeof(struct input_event))
+       if (count < evdev_event_size())
                return -EINVAL;
  
        if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
        if (!list->evdev->exist)
                return -ENODEV;
  
-       while (list->head != list->tail && retval + sizeof(struct input_event) <= count) {
-               if (copy_to_user(buffer + retval, list->buffer + list->tail,
-                       sizeof(struct input_event))) return -EFAULT;
+       while (list->head != list->tail && retval + evdev_event_size() <= count) {
+               struct input_event *event = (struct input_event *) list->buffer + list->tail;
+               if (evdev_event_to_user(buffer + retval, event))
+                       return -EFAULT;
                list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
-               retval += sizeof(struct input_event);
+               retval += evdev_event_size();
        }
  
        return retval;
@@@ -290,17 -304,95 +304,95 @@@ static unsigned int evdev_poll(struct f
                (list->evdev->exist ? 0 : (POLLHUP | POLLERR));
  }
  
- static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ #ifdef CONFIG_COMPAT
+ #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
+ #define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
+ #ifdef __BIG_ENDIAN
+ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
+                       unsigned int maxlen, void __user *p, int compat)
+ {
+       int len, i;
+       if (compat) {
+               len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
+               if (len < maxlen)
+                       len = maxlen;
+               for (i = 0; i < len / sizeof(compat_long_t); i++)
+                       if (copy_to_user((compat_long_t __user *) p + i,
+                                        (compat_long_t *) bits +
+                                               i + 1 - ((i % 2) << 1),
+                                        sizeof(compat_long_t)))
+                               return -EFAULT;
+       } else {
+               len = NBITS(maxbit) * sizeof(long);
+               if (len > maxlen)
+                       len = maxlen;
+               if (copy_to_user(p, bits, len))
+                       return -EFAULT;
+       }
+       return len;
+ }
+ #else
+ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
+                       unsigned int maxlen, void __user *p, int compat)
+ {
+       int len = compat ?
+                       NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
+                       NBITS(maxbit) * sizeof(long);
+       if (len > maxlen)
+               len = maxlen;
+       return copy_to_user(p, bits, len) ? -EFAULT : len;
+ }
+ #endif /* __BIG_ENDIAN */
+ #else
+ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
+                       unsigned int maxlen, void __user *p, int compat)
+ {
+       int len = NBITS(maxbit) * sizeof(long);
+       if (len > maxlen)
+               len = maxlen;
+       return copy_to_user(p, bits, len) ? -EFAULT : len;
+ }
+ #endif /* CONFIG_COMPAT */
+ static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
+ {
+       int len;
+       if (!str)
+               return -ENOENT;
+       len = strlen(str) + 1;
+       if (len > maxlen)
+               len = maxlen;
+       return copy_to_user(p, str, len) ? -EFAULT : len;
+ }
+ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
+                               void __user *p, int compat_mode)
  {
        struct evdev_list *list = file->private_data;
        struct evdev *evdev = list->evdev;
        struct input_dev *dev = evdev->handle.dev;
        struct input_absinfo abs;
-       void __user *p = (void __user *)arg;
-       int __user *ip = (int __user *)arg;
+       int __user *ip = (int __user *)p;
        int i, t, u, v;
  
-       if (!evdev->exist) return -ENODEV;
+       if (!evdev->exist)
+               return -ENODEV;
  
        switch (cmd) {
  
                        return put_user(EV_VERSION, ip);
  
                case EVIOCGID:
-                       return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0;
+                       if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
+                               return -EFAULT;
+                       return 0;
  
                case EVIOCGKEYCODE:
-                       if (get_user(t, ip)) return -EFAULT;
-                       if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
-                       if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) return -EFAULT;
+                       if (get_user(t, ip))
+                               return -EFAULT;
+                       if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
+                               return -EINVAL;
+                       if (put_user(INPUT_KEYCODE(dev, t), ip + 1))
+                               return -EFAULT;
                        return 0;
  
                case EVIOCSKEYCODE:
-                       if (get_user(t, ip)) return -EFAULT;
-                       if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
-                       if (get_user(v, ip + 1)) return -EFAULT;
-                       if (v < 0 || v > KEY_MAX) return -EINVAL;
-                       if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) return -EINVAL;
+                       if (get_user(t, ip))
+                               return -EFAULT;
+                       if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
+                               return -EINVAL;
+                       if (get_user(v, ip + 1))
+                               return -EFAULT;
+                       if (v < 0 || v > KEY_MAX)
+                               return -EINVAL;
+                       if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8)))
+                               return -EINVAL;
                        u = SET_INPUT_KEYCODE(dev, t, v);
                        clear_bit(u, dev->keybit);
                        set_bit(v, dev->keybit);
                        for (i = 0; i < dev->keycodemax; i++)
-                               if (INPUT_KEYCODE(dev,i) == u)
+                               if (INPUT_KEYCODE(dev, i) == u)
                                        set_bit(u, dev->keybit);
                        return 0;
  
                case EVIOCSFF:
                                if (copy_from_user(&effect, p, sizeof(effect)))
                                        return -EFAULT;
                                err = dev->upload_effect(dev, &effect);
-                               if (put_user(effect.id, &(((struct ff_effect __user *)arg)->id)))
+                               if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
                                        return -EFAULT;
                                return err;
-                       }
-                       else return -ENOSYS;
+                       } else
+                               return -ENOSYS;
  
                case EVIOCRMFF:
-                       if (dev->erase_effect) {
-                               return dev->erase_effect(dev, (int)arg);
-                       }
-                       else return -ENOSYS;
+                       if (!dev->erase_effect)
+                               return -ENOSYS;
+                       return dev->erase_effect(dev, (int)(unsigned long) p);
  
                case EVIOCGEFFECTS:
                        if (put_user(dev->ff_effects_max, ip))
                        return 0;
  
                case EVIOCGRAB:
-                       if (arg) {
+                       if (p) {
                                if (evdev->grab)
                                        return -EBUSY;
                                if (input_grab_device(&evdev->handle))
                                                case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;
                                                default: return -EINVAL;
                                        }
-                                       len = NBITS(len) * sizeof(long);
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, bits, len) ? -EFAULT : len;
+                                       return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
                                }
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
-                                       int len;
-                                       len = NBITS(KEY_MAX) * sizeof(long);
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->key, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
+                                       return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
+                                                           p, compat_mode);
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
-                                       int len;
-                                       len = NBITS(LED_MAX) * sizeof(long);
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->led, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
+                                       return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
+                                                           p, compat_mode);
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
-                                       int len;
-                                       len = NBITS(SND_MAX) * sizeof(long);
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
+                                       return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
+                                                           p, compat_mode);
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) {
-                                       int len;
-                                       len = NBITS(SW_MAX) * sizeof(long);
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->sw, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
+                                       return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
+                                                           p, compat_mode);
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
-                                       int len;
-                                       if (!dev->name) return -ENOENT;
-                                       len = strlen(dev->name) + 1;
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->name, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
+                                       return str_to_user(dev->name, _IOC_SIZE(cmd), p);
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
-                                       int len;
-                                       if (!dev->phys) return -ENOENT;
-                                       len = strlen(dev->phys) + 1;
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
+                                       return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
  
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
-                                       int len;
-                                       if (!dev->uniq) return -ENOENT;
-                                       len = strlen(dev->uniq) + 1;
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
-                               }
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
+                                       return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
  
                                if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
  
        return -EINVAL;
  }
  
- #ifdef CONFIG_COMPAT
- #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
- #define NBITS_COMPAT(x) ((((x)-1)/BITS_PER_LONG_COMPAT)+1)
- #define OFF_COMPAT(x)  ((x)%BITS_PER_LONG_COMPAT)
- #define BIT_COMPAT(x)  (1UL<<OFF_COMPAT(x))
- #define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT)
- #define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1)
- #ifdef __BIG_ENDIAN
- #define bit_to_user(bit, max) \
- do { \
-       int i; \
-       int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
-       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
-       for (i = 0; i < len / sizeof(compat_long_t); i++) \
-               if (copy_to_user((compat_long_t __user *) p + i, \
-                                (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
-                                sizeof(compat_long_t))) \
-                       return -EFAULT; \
-       return len; \
- } while (0)
- #else
- #define bit_to_user(bit, max) \
- do { \
-       int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
-       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
-       return copy_to_user(p, (bit), len) ? -EFAULT : len; \
- } while (0)
- #endif
+ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+       return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0);
+ }
  
+ #ifdef CONFIG_COMPAT
  static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
  {
-       struct evdev_list *list = file->private_data;
-       struct evdev *evdev = list->evdev;
-       struct input_dev *dev = evdev->handle.dev;
-       struct input_absinfo abs;
-       void __user *p = compat_ptr(arg);
-       if (!evdev->exist) return -ENODEV;
-       switch (cmd) {
-               case EVIOCGVERSION:
-               case EVIOCGID:
-               case EVIOCGKEYCODE:
-               case EVIOCSKEYCODE:
-               case EVIOCSFF:
-               case EVIOCRMFF:
-               case EVIOCGEFFECTS:
-               case EVIOCGRAB:
-                       return evdev_ioctl(file, cmd, (unsigned long) p);
-               default:
-                       if (_IOC_TYPE(cmd) != 'E')
-                               return -EINVAL;
-                       if (_IOC_DIR(cmd) == _IOC_READ) {
-                               if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
-                                       long *bits;
-                                       int max;
-                                       switch (_IOC_NR(cmd) & EV_MAX) {
-                                               case      0: bits = dev->evbit;  max = EV_MAX;  break;
-                                               case EV_KEY: bits = dev->keybit; max = KEY_MAX; break;
-                                               case EV_REL: bits = dev->relbit; max = REL_MAX; break;
-                                               case EV_ABS: bits = dev->absbit; max = ABS_MAX; break;
-                                               case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break;
-                                               case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
-                                               case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
-                                               case EV_FF:  bits = dev->ffbit;  max = FF_MAX;  break;
-                                               case EV_SW:  bits = dev->swbit;  max = SW_MAX;  break;
-                                               default: return -EINVAL;
-                                       }
-                                       bit_to_user(bits, max);
-                               }
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
-                                       bit_to_user(dev->key, KEY_MAX);
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
-                                       bit_to_user(dev->led, LED_MAX);
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
-                                       bit_to_user(dev->snd, SND_MAX);
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
-                                       bit_to_user(dev->sw, SW_MAX);
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
-                                       int len;
-                                       if (!dev->name) return -ENOENT;
-                                       len = strlen(dev->name) + 1;
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->name, len) ? -EFAULT : len;
-                               }
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
-                                       int len;
-                                       if (!dev->phys) return -ENOENT;
-                                       len = strlen(dev->phys) + 1;
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
-                               }
-                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
-                                       int len;
-                                       if (!dev->uniq) return -ENOENT;
-                                       len = strlen(dev->uniq) + 1;
-                                       if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                                       return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
-                               }
-                               if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
-                                       int t = _IOC_NR(cmd) & ABS_MAX;
-                                       abs.value = dev->abs[t];
-                                       abs.minimum = dev->absmin[t];
-                                       abs.maximum = dev->absmax[t];
-                                       abs.fuzz = dev->absfuzz[t];
-                                       abs.flat = dev->absflat[t];
-                                       if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
-                                               return -EFAULT;
-                                       return 0;
-                               }
-                       }
-                       if (_IOC_DIR(cmd) == _IOC_WRITE) {
-                               if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
-                                       int t = _IOC_NR(cmd) & ABS_MAX;
-                                       if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
-                                               return -EFAULT;
-                                       dev->abs[t] = abs.value;
-                                       dev->absmin[t] = abs.minimum;
-                                       dev->absmax[t] = abs.maximum;
-                                       dev->absfuzz[t] = abs.fuzz;
-                                       dev->absflat[t] = abs.flat;
-                                       return 0;
-                               }
-                       }
-       }
-       return -EINVAL;
+       return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1);
  }
  #endif
  
This page took 0.080018 seconds and 4 git commands to generate.