diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-07 11:29:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-07 11:29:51 -0800 |
commit | b9abaa3fb7328851bdeaad19e694048f0ff71d9a (patch) | |
tree | de56cda929b837c6b2e421b57c723939ec7df5da /drivers | |
parent | 8995b161eb142b843094dd614b80e4cce1d66352 (diff) | |
parent | 736ce43295682d060f2b93624b4a339f9af6aab1 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/evdev.c | 493 | ||||
-rw-r--r-- | drivers/input/gameport/Kconfig | 7 | ||||
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/m68kspkr.c | 102 | ||||
-rw-r--r-- | drivers/input/misc/pcspkr.c | 86 | ||||
-rw-r--r-- | drivers/input/misc/sparcspkr.c | 162 | ||||
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 133 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 1 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.c | 7 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 15 | ||||
-rw-r--r-- | drivers/input/mousedev.c | 10 | ||||
-rw-r--r-- | drivers/input/serio/ct82c710.c | 89 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 15 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 116 | ||||
-rw-r--r-- | drivers/input/serio/maceps2.c | 68 | ||||
-rw-r--r-- | drivers/input/serio/q40kbd.c | 89 | ||||
-rw-r--r-- | drivers/misc/ibmasm/ibmasm.h | 6 | ||||
-rw-r--r-- | drivers/misc/ibmasm/remote.c | 76 | ||||
-rw-r--r-- | drivers/usb/input/appletouch.c | 145 | ||||
-rw-r--r-- | drivers/usb/input/hid-debug.h | 15 |
21 files changed, 1025 insertions, 614 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index a1e660e3531..f7490a015d1 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -146,6 +146,7 @@ static int evdev_open(struct inode * inode, struct file * file) } #ifdef CONFIG_COMPAT + struct input_event_compat { struct compat_timeval time; __u16 type; @@ -165,98 +166,107 @@ struct input_event_compat { # 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)) @@ -271,11 +281,15 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count 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 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait) (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) { @@ -308,26 +400,39 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 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: @@ -338,17 +443,17 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 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)) @@ -356,7 +461,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return 0; case EVIOCGRAB: - if (arg) { + if (p) { if (evdev->grab) return -EBUSY; if (input_grab_device(&evdev->handle)) @@ -395,62 +500,33 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 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))) { @@ -492,158 +568,15 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 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 diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig index 7524bd7d8b8..d279454a5c9 100644 --- a/drivers/input/gameport/Kconfig +++ b/drivers/input/gameport/Kconfig @@ -52,5 +52,12 @@ config GAMEPORT_EMU10K1 config GAMEPORT_FM801 tristate "ForteMedia FM801 gameport support" depends on PCI + help + Say Y here if you have ForteMedia FM801 PCI audio controller + (Abit AU10, Genius Sound Maker, HP Workstation zx2000, + and others), and want to use its gameport. + + To compile this driver as a module, choose M here: the + module will be called fm801-gp. endif diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index a0256f8de8e..ffacf6eca5f 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -321,7 +321,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, switch (code) { case ATKBD_RET_BAT: atkbd->enabled = 0; - serio_rescan(atkbd->ps2dev.serio); + serio_reconnect(atkbd->ps2dev.serio); goto out; case ATKBD_RET_EMUL0: atkbd->emul = 1; diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index 04489ad7702..8d6c3837bad 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/input.h> +#include <linux/platform_device.h> #include <asm/machdep.h> #include <asm/io.h> @@ -24,7 +25,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>"); MODULE_DESCRIPTION("m68k beeper driver"); MODULE_LICENSE("GPL"); -static struct input_dev *m68kspkr_dev; +static struct platform_device *m68kspkr_platform_device; static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { @@ -47,36 +48,103 @@ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int return 0; } +static int __devinit m68kspkr_probe(struct platform_device *dev) +{ + struct input_dev *input_dev; + int err; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + input_dev->name = "m68k beeper"; + input_dev->phys = "m68k/generic"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x001f; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &dev->dev; + + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + input_dev->event = m68kspkr_event; + + err = input_register_device(input_dev); + if (err) { + input_free_device(input_dev); + return err; + } + + platform_set_drvdata(dev, input_dev); + + return 0; +} + +static int __devexit m68kspkr_remove(struct platform_device *dev) +{ + struct input_dev *input_dev = platform_get_drvdata(dev); + + input_unregister_device(input_dev); + platform_set_drvdata(dev, NULL); + /* turn off the speaker */ + m68kspkr_event(NULL, EV_SND, SND_BELL, 0); + + return 0; +} + +static void m68kspkr_shutdown(struct platform_device *dev) +{ + /* turn off the speaker */ + m68kspkr_event(NULL, EV_SND, SND_BELL, 0); +} + +static struct platform_driver m68kspkr_platform_driver = { + .driver = { + .name = "m68kspkr", + .owner = THIS_MODULE, + }, + .probe = m68kspkr_probe, + .remove = __devexit_p(m68kspkr_remove), + .shutdown = m68kspkr_shutdown, +}; + static int __init m68kspkr_init(void) { - if (!mach_beep) { + int err; + + if (!mach_beep) { printk(KERN_INFO "m68kspkr: no lowlevel beep support\n"); return -ENODEV; } - m68kspkr_dev = input_allocate_device(); - if (!m68kspkr_dev) - return -ENOMEM; - - m68kspkr_dev->name = "m68k beeper"; - m68kspkr_dev->phys = "m68k/generic"; - m68kspkr_dev->id.bustype = BUS_HOST; - m68kspkr_dev->id.vendor = 0x001f; - m68kspkr_dev->id.product = 0x0001; - m68kspkr_dev->id.version = 0x0100; + err = platform_driver_register(&m68kspkr_platform_driver); + if (err) + return err; - m68kspkr_dev->evbit[0] = BIT(EV_SND); - m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - m68kspkr_dev->event = m68kspkr_event; + m68kspkr_platform_device = platform_device_alloc("m68kspkr", -1); + if (!m68kspkr_platform_device) { + err = -ENOMEM; + goto err_unregister_driver; + } - input_register_device(m68kspkr_dev); + err = platform_device_add(m68kspkr_platform_device); + if (err) + goto err_free_device; return 0; + + err_free_device: + platform_device_put(m68kspkr_platform_device); + err_unregister_driver: + platform_driver_unregister(&m68kspkr_platform_driver); + + return err; } static void __exit m68kspkr_exit(void) { - input_unregister_device(m68kspkr_dev); + platform_device_unregister(m68kspkr_platform_device); + platform_driver_unregister(&m68kspkr_platform_driver); } module_init(m68kspkr_init); diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 68ac97f101b..1ef477f4469 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/input.h> +#include <linux/platform_device.h> #include <asm/8253pit.h> #include <asm/io.h> @@ -23,8 +24,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("PC Speaker beeper driver"); MODULE_LICENSE("GPL"); -static struct input_dev *pcspkr_dev; - +static struct platform_device *pcspkr_platform_device; static DEFINE_SPINLOCK(i8253_beep_lock); static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) @@ -64,8 +64,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c return 0; } -static int __init pcspkr_init(void) +static int __devinit pcspkr_probe(struct platform_device *dev) { + struct input_dev *pcspkr_dev; + int err; + pcspkr_dev = input_allocate_device(); if (!pcspkr_dev) return -ENOMEM; @@ -76,22 +79,93 @@ static int __init pcspkr_init(void) pcspkr_dev->id.vendor = 0x001f; pcspkr_dev->id.product = 0x0001; pcspkr_dev->id.version = 0x0100; + pcspkr_dev->cdev.dev = &dev->dev; pcspkr_dev->evbit[0] = BIT(EV_SND); pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); pcspkr_dev->event = pcspkr_event; - input_register_device(pcspkr_dev); + err = input_register_device(pcspkr_dev); + if (err) { + input_free_device(pcspkr_dev); + return err; + } + + platform_set_drvdata(dev, pcspkr_dev); return 0; } -static void __exit pcspkr_exit(void) +static int __devexit pcspkr_remove(struct platform_device *dev) +{ + struct input_dev *pcspkr_dev = platform_get_drvdata(dev); + + input_unregister_device(pcspkr_dev); + platform_set_drvdata(dev, NULL); + /* turn off the speaker */ + pcspkr_event(NULL, EV_SND, SND_BELL, 0); + + return 0; +} + +static int pcspkr_suspend(struct platform_device *dev, pm_message_t state) +{ + pcspkr_event(NULL, EV_SND, SND_BELL, 0); + + return 0; +} + +static void pcspkr_shutdown(struct platform_device *dev) { - input_unregister_device(pcspkr_dev); /* turn off the speaker */ pcspkr_event(NULL, EV_SND, SND_BELL, 0); } +static struct platform_driver pcspkr_platform_driver = { + .driver = { + .name = "pcspkr", + .owner = THIS_MODULE, + }, + .probe = pcspkr_probe, + .remove = __devexit_p(pcspkr_remove), + .suspend = pcspkr_suspend, + .shutdown = pcspkr_shutdown, +}; + + +static int __init pcspkr_init(void) +{ + int err; + + err = platform_driver_register(&pcspkr_platform_driver); + if (err) + return err; + + pcspkr_platform_device = platform_device_alloc("pcspkr", -1); + if (!pcspkr_platform_device) { + err = -ENOMEM; + goto err_unregister_driver; + } + + err = platform_device_add(pcspkr_platform_device); + if (err) + goto err_free_device; + + return 0; + + err_free_device: + platform_device_put(pcspkr_platform_device); + err_unregister_driver: + platform_driver_unregister(&pcspkr_platform_driver); + + return err; +} + +static void __exit pcspkr_exit(void) +{ + platform_device_unregister(pcspkr_platform_device); + platform_driver_unregister(&pcspkr_platform_driver); +} + module_init(pcspkr_init); module_exit(pcspkr_exit); diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 29d97b12be7..f0fd2c4740f 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/ |