aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:13:17 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:16:12 -0400
commita3d52136ee8f7399859f9a0824470fd49b1d1a00 (patch)
treeac0fd3d1efc356029cbbc5e413f778f7231cd909 /drivers/input/evdev.c
parent5b339915762d30b21995aa7263e74081f2f1110a (diff)
parent84767d00a8fd54dd97866561f6e2ee246c8e1cdc (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: (65 commits) Input: gpio_keys - add support for switches (EV_SW) Input: cobalt_btns - convert to use polldev library Input: add skeleton for simple polled devices Input: update some documentation Input: wistron - fix typo in keymap for Acer TM610 Input: add input_set_capability() helper Input: i8042 - add Fujitsu touchscreen/touchpad PNP IDs Input: i8042 - add Panasonic CF-29 to nomux list Input: lifebook - split into 2 devices Input: lifebook - add signature of Panasonic CF-29 Input: lifebook - activate 6-byte protocol on select models Input: lifebook - work properly on Panasonic CF-18 Input: cobalt buttons - separate device and driver registration Input: ati_remote - make button repeat sensitivity configurable Input: pxa27x - do not use deprecated SA_INTERRUPT flag Input: ucb1400 - make delays configurable Input: misc devices - switch to using input_dev->dev.parent Input: joysticks - switch to using input_dev->dev.parent Input: touchscreens - switch to using input_dev->dev.parent Input: mice - switch to using input_dev->dev.parent ... Fixed up conflicts with core device model removal of "struct subsystem" manually. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c233
1 files changed, 132 insertions, 101 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 6e55b2c5874..1f6fcec0c6f 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -29,11 +29,11 @@ struct evdev {
29 char name[16]; 29 char name[16];
30 struct input_handle handle; 30 struct input_handle handle;
31 wait_queue_head_t wait; 31 wait_queue_head_t wait;
32 struct evdev_list *grab; 32 struct evdev_client *grab;
33 struct list_head list; 33 struct list_head client_list;
34}; 34};
35 35
36struct evdev_list { 36struct evdev_client {
37 struct input_event buffer[EVDEV_BUFFER_SIZE]; 37 struct input_event buffer[EVDEV_BUFFER_SIZE];
38 int head; 38 int head;
39 int tail; 39 int tail;
@@ -47,28 +47,28 @@ static struct evdev *evdev_table[EVDEV_MINORS];
47static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 47static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
48{ 48{
49 struct evdev *evdev = handle->private; 49 struct evdev *evdev = handle->private;
50 struct evdev_list *list; 50 struct evdev_client *client;
51 51
52 if (evdev->grab) { 52 if (evdev->grab) {
53 list = evdev->grab; 53 client = evdev->grab;
54 54
55 do_gettimeofday(&list->buffer[list->head].time); 55 do_gettimeofday(&client->buffer[client->head].time);
56 list->buffer[list->head].type = type; 56 client->buffer[client->head].type = type;
57 list->buffer[list->head].code = code; 57 client->buffer[client->head].code = code;
58 list->buffer[list->head].value = value; 58 client->buffer[client->head].value = value;
59 list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); 59 client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1);
60 60
61 kill_fasync(&list->fasync, SIGIO, POLL_IN); 61 kill_fasync(&client->fasync, SIGIO, POLL_IN);
62 } else 62 } else
63 list_for_each_entry(list, &evdev->list, node) { 63 list_for_each_entry(client, &evdev->client_list, node) {
64 64
65 do_gettimeofday(&list->buffer[list->head].time); 65 do_gettimeofday(&client->buffer[client->head].time);
66 list->buffer[list->head].type = type; 66 client->buffer[client->head].type = type;
67 list->buffer[list->head].code = code; 67 client->buffer[client->head].code = code;
68 list->buffer[list->head].value = value; 68 client->buffer[client->head].value = value;
69 list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); 69 client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1);
70 70
71 kill_fasync(&list->fasync, SIGIO, POLL_IN); 71 kill_fasync(&client->fasync, SIGIO, POLL_IN);
72 } 72 }
73 73
74 wake_up_interruptible(&evdev->wait); 74 wake_up_interruptible(&evdev->wait);
@@ -76,22 +76,23 @@ static void evdev_event(struct input_handle *handle, unsigned int type, unsigned
76 76
77static int evdev_fasync(int fd, struct file *file, int on) 77static int evdev_fasync(int fd, struct file *file, int on)
78{ 78{
79 struct evdev_client *client = file->private_data;
79 int retval; 80 int retval;
80 struct evdev_list *list = file->private_data;
81 81
82 retval = fasync_helper(fd, file, on, &list->fasync); 82 retval = fasync_helper(fd, file, on, &client->fasync);
83 83
84 return retval < 0 ? retval : 0; 84 return retval < 0 ? retval : 0;
85} 85}
86 86
87static int evdev_flush(struct file *file, fl_owner_t id) 87static int evdev_flush(struct file *file, fl_owner_t id)
88{ 88{
89 struct evdev_list *list = file->private_data; 89 struct evdev_client *client = file->private_data;
90 struct evdev *evdev = client->evdev;
90 91
91 if (!list->evdev->exist) 92 if (!evdev->exist)
92 return -ENODEV; 93 return -ENODEV;
93 94
94 return input_flush_device(&list->evdev->handle, file); 95 return input_flush_device(&evdev->handle, file);
95} 96}
96 97
97static void evdev_free(struct evdev *evdev) 98static void evdev_free(struct evdev *evdev)
@@ -100,48 +101,62 @@ static void evdev_free(struct evdev *evdev)
100 kfree(evdev); 101 kfree(evdev);
101} 102}
102 103
103static int evdev_release(struct inode * inode, struct file * file) 104static int evdev_release(struct inode *inode, struct file *file)
104{ 105{
105 struct evdev_list *list = file->private_data; 106 struct evdev_client *client = file->private_data;
107 struct evdev *evdev = client->evdev;
106 108
107 if (list->evdev->grab == list) { 109 if (evdev->grab == client) {
108 input_release_device(&list->evdev->handle); 110 input_release_device(&evdev->handle);
109 list->evdev->grab = NULL; 111 evdev->grab = NULL;
110 } 112 }
111 113
112 evdev_fasync(-1, file, 0); 114 evdev_fasync(-1, file, 0);
113 list_del(&list->node); 115 list_del(&client->node);
116 kfree(client);
114 117
115 if (!--list->evdev->open) { 118 if (!--evdev->open) {
116 if (list->evdev->exist) 119 if (evdev->exist)
117 input_close_device(&list->evdev->handle); 120 input_close_device(&evdev->handle);
118 else 121 else
119 evdev_free(list->evdev); 122 evdev_free(evdev);
120 } 123 }
121 124
122 kfree(list);
123 return 0; 125 return 0;
124} 126}
125 127
126static int evdev_open(struct inode * inode, struct file * file) 128static int evdev_open(struct inode *inode, struct file *file)
127{ 129{
128 struct evdev_list *list; 130 struct evdev_client *client;
131 struct evdev *evdev;
129 int i = iminor(inode) - EVDEV_MINOR_BASE; 132 int i = iminor(inode) - EVDEV_MINOR_BASE;
133 int error;
130 134
131 if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) 135 if (i >= EVDEV_MINORS)
132 return -ENODEV; 136 return -ENODEV;
133 137
134 if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) 138 evdev = evdev_table[i];
139
140 if (!evdev || !evdev->exist)
141 return -ENODEV;
142
143 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
144 if (!client)
135 return -ENOMEM; 145 return -ENOMEM;
136 146
137 list->evdev = evdev_table[i]; 147 client->evdev = evdev;
138 list_add_tail(&list->node, &evdev_table[i]->list); 148 list_add_tail(&client->node, &evdev->client_list);
139 file->private_data = list;
140 149
141 if (!list->evdev->open++) 150 if (!evdev->open++ && evdev->exist) {
142 if (list->evdev->exist) 151 error = input_open_device(&evdev->handle);
143 input_open_device(&list->evdev->handle); 152 if (error) {
153 list_del(&client->node);
154 kfree(client);
155 return error;
156 }
157 }
144 158
159 file->private_data = client;
145 return 0; 160 return 0;
146} 161}
147 162
@@ -243,54 +258,55 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev
243 258
244#endif /* CONFIG_COMPAT */ 259#endif /* CONFIG_COMPAT */
245 260
246static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) 261static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
247{ 262{
248 struct evdev_list *list = file->private_data; 263 struct evdev_client *client = file->private_data;
264 struct evdev *evdev = client->evdev;
249 struct input_event event; 265 struct input_event event;
250 int retval = 0; 266 int retval = 0;
251 267
252 if (!list->evdev->exist) 268 if (!evdev->exist)
253 return -ENODEV; 269 return -ENODEV;
254 270
255 while (retval < count) { 271 while (retval < count) {
256 272
257 if (evdev_event_from_user(buffer + retval, &event)) 273 if (evdev_event_from_user(buffer + retval, &event))
258 return -EFAULT; 274 return -EFAULT;
259 input_inject_event(&list->evdev->handle, event.type, event.code, event.value); 275 input_inject_event(&evdev->handle, event.type, event.code, event.value);
260 retval += evdev_event_size(); 276 retval += evdev_event_size();
261 } 277 }
262 278
263 return retval; 279 return retval;
264} 280}
265 281
266static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) 282static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
267{ 283{
268 struct evdev_list *list = file->private_data; 284 struct evdev_client *client = file->private_data;
285 struct evdev *evdev = client->evdev;
269 int retval; 286 int retval;
270 287
271 if (count < evdev_event_size()) 288 if (count < evdev_event_size())
272 return -EINVAL; 289 return -EINVAL;
273 290
274 if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) 291 if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK))
275 return -EAGAIN; 292 return -EAGAIN;
276 293
277 retval = wait_event_interruptible(list->evdev->wait, 294 retval = wait_event_interruptible(evdev->wait,
278 list->head != list->tail || (!list->evdev->exist)); 295 client->head != client->tail || !evdev->exist);
279
280 if (retval) 296 if (retval)
281 return retval; 297 return retval;
282 298
283 if (!list->evdev->exist) 299 if (!evdev->exist)
284 return -ENODEV; 300 return -ENODEV;
285 301
286 while (list->head != list->tail && retval + evdev_event_size() <= count) { 302 while (client->head != client->tail && retval + evdev_event_size() <= count) {
287 303
288 struct input_event *event = (struct input_event *) list->buffer + list->tail; 304 struct input_event *event = (struct input_event *) client->buffer + client->tail;
289 305
290 if (evdev_event_to_user(buffer + retval, event)) 306 if (evdev_event_to_user(buffer + retval, event))
291 return -EFAULT; 307 return -EFAULT;
292 308
293 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); 309 client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
294 retval += evdev_event_size(); 310 retval += evdev_event_size();
295 } 311 }
296 312
@@ -300,11 +316,12 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
300/* No kernel lock - fine */ 316/* No kernel lock - fine */
301static unsigned int evdev_poll(struct file *file, poll_table *wait) 317static unsigned int evdev_poll(struct file *file, poll_table *wait)
302{ 318{
303 struct evdev_list *list = file->private_data; 319 struct evdev_client *client = file->private_data;
320 struct evdev *evdev = client->evdev;
304 321
305 poll_wait(file, &list->evdev->wait, wait); 322 poll_wait(file, &evdev->wait, wait);
306 return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | 323 return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) |
307 (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); 324 (evdev->exist ? 0 : (POLLHUP | POLLERR));
308} 325}
309 326
310#ifdef CONFIG_COMPAT 327#ifdef CONFIG_COMPAT
@@ -387,8 +404,8 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
387static long evdev_ioctl_handler(struct file *file, unsigned int cmd, 404static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
388 void __user *p, int compat_mode) 405 void __user *p, int compat_mode)
389{ 406{
390 struct evdev_list *list = file->private_data; 407 struct evdev_client *client = file->private_data;
391 struct evdev *evdev = list->evdev; 408 struct evdev *evdev = client->evdev;
392 struct input_dev *dev = evdev->handle.dev; 409 struct input_dev *dev = evdev->handle.dev;
393 struct input_absinfo abs; 410 struct input_absinfo abs;
394 struct ff_effect effect; 411 struct ff_effect effect;
@@ -434,32 +451,21 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
434 case EVIOCGKEYCODE: 451 case EVIOCGKEYCODE:
435 if (get_user(t, ip)) 452 if (get_user(t, ip))
436 return -EFAULT; 453 return -EFAULT;
437 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) 454
438 return -EINVAL; 455 error = dev->getkeycode(dev, t, &v);
439 if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) 456 if (error)
457 return error;
458
459 if (put_user(v, ip + 1))
440 return -EFAULT; 460 return -EFAULT;
461
441 return 0; 462 return 0;
442 463
443 case EVIOCSKEYCODE: 464 case EVIOCSKEYCODE:
444 if (get_user(t, ip)) 465 if (get_user(t, ip) || get_user(v, ip + 1))
445 return -EFAULT; 466 return -EFAULT;
446 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
447 return -EINVAL;
448 if (get_user(v, ip + 1))
449 return -EFAULT;
450 if (v < 0 || v > KEY_MAX)
451 return -EINVAL;
452 if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8)))
453 return -EINVAL;
454 467
455 u = SET_INPUT_KEYCODE(dev, t, v); 468 return dev->setkeycode(dev, t, v);
456 clear_bit(u, dev->keybit);
457 set_bit(v, dev->keybit);
458 for (i = 0; i < dev->keycodemax; i++)
459 if (INPUT_KEYCODE(dev, i) == u)
460 set_bit(u, dev->keybit);
461
462 return 0;
463 469
464 case EVIOCSFF: 470 case EVIOCSFF:
465 if (copy_from_user(&effect, p, sizeof(effect))) 471 if (copy_from_user(&effect, p, sizeof(effect)))
@@ -487,10 +493,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
487 return -EBUSY; 493 return -EBUSY;
488 if (input_grab_device(&evdev->handle)) 494 if (input_grab_device(&evdev->handle))
489 return -EBUSY; 495 return -EBUSY;
490 evdev->grab = list; 496 evdev->grab = client;
491 return 0; 497 return 0;
492 } else { 498 } else {
493 if (evdev->grab != list) 499 if (evdev->grab != client)
494 return -EINVAL; 500 return -EINVAL;
495 input_release_device(&evdev->handle); 501 input_release_device(&evdev->handle);
496 evdev->grab = NULL; 502 evdev->grab = NULL;
@@ -616,23 +622,26 @@ static const struct file_operations evdev_fops = {
616 .flush = evdev_flush 622 .flush = evdev_flush
617}; 623};
618 624
619static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, 625static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
620 const struct input_device_id *id) 626 const struct input_device_id *id)
621{ 627{
622 struct evdev *evdev; 628 struct evdev *evdev;
623 struct class_device *cdev; 629 struct class_device *cdev;
630 dev_t devt;
624 int minor; 631 int minor;
632 int error;
625 633
626 for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); 634 for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
627 if (minor == EVDEV_MINORS) { 635 if (minor == EVDEV_MINORS) {
628 printk(KERN_ERR "evdev: no more free evdev devices\n"); 636 printk(KERN_ERR "evdev: no more free evdev devices\n");
629 return NULL; 637 return -ENFILE;
630 } 638 }
631 639
632 if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL))) 640 evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
633 return NULL; 641 if (!evdev)
642 return -ENOMEM;
634 643
635 INIT_LIST_HEAD(&evdev->list); 644 INIT_LIST_HEAD(&evdev->client_list);
636 init_waitqueue_head(&evdev->wait); 645 init_waitqueue_head(&evdev->wait);
637 646
638 evdev->exist = 1; 647 evdev->exist = 1;
@@ -645,21 +654,43 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
645 654
646 evdev_table[minor] = evdev; 655 evdev_table[minor] = evdev;
647 656
648 cdev = class_device_create(&input_class, &dev->cdev, 657 devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
649 MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), 658
650 dev->cdev.dev, evdev->name); 659 cdev = class_device_create(&input_class, &dev->cdev, devt,
660 dev->cdev.dev, evdev->name);
661 if (IS_ERR(cdev)) {
662 error = PTR_ERR(cdev);
663 goto err_free_evdev;
664 }
651 665
652 /* temporary symlink to keep userspace happy */ 666 /* temporary symlink to keep userspace happy */
653 sysfs_create_link(&input_class.subsys.kobj, &cdev->kobj, 667 error = sysfs_create_link(&input_class.subsys.kobj,
654 evdev->name); 668 &cdev->kobj, evdev->name);
669 if (error)
670 goto err_cdev_destroy;
671
672 error = input_register_handle(&evdev->handle);
673 if (error)
674 goto err_remove_link;
675
676 return 0;
655 677
656 return &evdev->handle; 678 err_remove_link:
679 sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
680 err_cdev_destroy:
681 class_device_destroy(&input_class, devt);
682 err_free_evdev:
683 kfree(evdev);
684 evdev_table[minor] = NULL;
685 return error;
657} 686}
658 687
659static void evdev_disconnect(struct input_handle *handle) 688static void evdev_disconnect(struct input_handle *handle)
660{ 689{
661 struct evdev *evdev = handle->private; 690 struct evdev *evdev = handle->private;
662 struct evdev_list *list; 691 struct evdev_client *client;
692
693 input_unregister_handle(handle);
663 694
664 sysfs_remove_link(&input_class.subsys.kobj, evdev->name); 695 sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
665 class_device_destroy(&input_class, 696 class_device_destroy(&input_class,
@@ -670,8 +701,8 @@ static void evdev_disconnect(struct input_handle *handle)
670 input_flush_device(handle, NULL); 701 input_flush_device(handle, NULL);
671 input_close_device(handle); 702 input_close_device(handle);
672 wake_up_interruptible(&evdev->wait); 703 wake_up_interruptible(&evdev->wait);
673 list_for_each_entry(list, &evdev->list, node) 704 list_for_each_entry(client, &evdev->client_list, node)
674 kill_fasync(&list->fasync, SIGIO, POLL_HUP); 705 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
675 } else 706 } else
676 evdev_free(evdev); 707 evdev_free(evdev);
677} 708}