diff options
Diffstat (limited to 'drivers/input/evdev.c')
| -rw-r--r-- | drivers/input/evdev.c | 177 |
1 files changed, 86 insertions, 91 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6c58bfff01a3..6ae2ac47c9c8 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -23,11 +23,11 @@ | |||
| 23 | #include <linux/input/mt.h> | 23 | #include <linux/input/mt.h> |
| 24 | #include <linux/major.h> | 24 | #include <linux/major.h> |
| 25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
| 26 | #include <linux/cdev.h> | ||
| 26 | #include "input-compat.h" | 27 | #include "input-compat.h" |
| 27 | 28 | ||
| 28 | struct evdev { | 29 | struct evdev { |
| 29 | int open; | 30 | int open; |
| 30 | int minor; | ||
| 31 | struct input_handle handle; | 31 | struct input_handle handle; |
| 32 | wait_queue_head_t wait; | 32 | wait_queue_head_t wait; |
| 33 | struct evdev_client __rcu *grab; | 33 | struct evdev_client __rcu *grab; |
| @@ -35,6 +35,7 @@ struct evdev { | |||
| 35 | spinlock_t client_lock; /* protects client_list */ | 35 | spinlock_t client_lock; /* protects client_list */ |
| 36 | struct mutex mutex; | 36 | struct mutex mutex; |
| 37 | struct device dev; | 37 | struct device dev; |
| 38 | struct cdev cdev; | ||
| 38 | bool exist; | 39 | bool exist; |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| @@ -51,19 +52,9 @@ struct evdev_client { | |||
| 51 | struct input_event buffer[]; | 52 | struct input_event buffer[]; |
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| 54 | static struct evdev *evdev_table[EVDEV_MINORS]; | 55 | static void __pass_event(struct evdev_client *client, |
| 55 | static DEFINE_MUTEX(evdev_table_mutex); | 56 | const struct input_event *event) |
| 56 | |||
| 57 | static void evdev_pass_event(struct evdev_client *client, | ||
| 58 | struct input_event *event, | ||
| 59 | ktime_t mono, ktime_t real) | ||
| 60 | { | 57 | { |
| 61 | event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? | ||
| 62 | mono : real); | ||
| 63 | |||
| 64 | /* Interrupts are disabled, just acquire the lock. */ | ||
| 65 | spin_lock(&client->buffer_lock); | ||
| 66 | |||
| 67 | client->buffer[client->head++] = *event; | 58 | client->buffer[client->head++] = *event; |
| 68 | client->head &= client->bufsize - 1; | 59 | client->head &= client->bufsize - 1; |
| 69 | 60 | ||
| @@ -86,42 +77,74 @@ static void evdev_pass_event(struct evdev_client *client, | |||
| 86 | client->packet_head = client->head; | 77 | client->packet_head = client->head; |
| 87 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 78 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
| 88 | } | 79 | } |
| 80 | } | ||
| 81 | |||
| 82 | static void evdev_pass_values(struct evdev_client *client, | ||
| 83 | const struct input_value *vals, unsigned int count, | ||
| 84 | ktime_t mono, ktime_t real) | ||
| 85 | { | ||
| 86 | struct evdev *evdev = client->evdev; | ||
| 87 | const struct input_value *v; | ||
| 88 | struct input_event event; | ||
| 89 | bool wakeup = false; | ||
| 90 | |||
| 91 | event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? | ||
| 92 | mono : real); | ||
| 93 | |||
| 94 | /* Interrupts are disabled, just acquire the lock. */ | ||
| 95 | spin_lock(&client->buffer_lock); | ||
| 96 | |||
| 97 | for (v = vals; v != vals + count; v++) { | ||
| 98 | event.type = v->type; | ||
| 99 | event.code = v->code; | ||
| 100 | event.value = v->value; | ||
| 101 | __pass_event(client, &event); | ||
| 102 | if (v->type == EV_SYN && v->code == SYN_REPORT) | ||
| 103 | wakeup = true; | ||
| 104 | } | ||
| 89 | 105 | ||
| 90 | spin_unlock(&client->buffer_lock); | 106 | spin_unlock(&client->buffer_lock); |
| 107 | |||
| 108 | if (wakeup) | ||
| 109 | wake_up_interruptible(&evdev->wait); | ||
| 91 | } | 110 | } |
| 92 | 111 | ||
| 93 | /* | 112 | /* |
| 94 | * Pass incoming event to all connected clients. | 113 | * Pass incoming events to all connected clients. |
| 95 | */ | 114 | */ |
| 96 | static void evdev_event(struct input_handle *handle, | 115 | static void evdev_events(struct input_handle *handle, |
| 97 | unsigned int type, unsigned int code, int value) | 116 | const struct input_value *vals, unsigned int count) |
| 98 | { | 117 | { |
| 99 | struct evdev *evdev = handle->private; | 118 | struct evdev *evdev = handle->private; |
| 100 | struct evdev_client *client; | 119 | struct evdev_client *client; |
| 101 | struct input_event event; | ||
| 102 | ktime_t time_mono, time_real; | 120 | ktime_t time_mono, time_real; |
| 103 | 121 | ||
| 104 | time_mono = ktime_get(); | 122 | time_mono = ktime_get(); |
| 105 | time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); | 123 | time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); |
| 106 | 124 | ||
| 107 | event.type = type; | ||
| 108 | event.code = code; | ||
| 109 | event.value = value; | ||
| 110 | |||
| 111 | rcu_read_lock(); | 125 | rcu_read_lock(); |
| 112 | 126 | ||
| 113 | client = rcu_dereference(evdev->grab); | 127 | client = rcu_dereference(evdev->grab); |
| 114 | 128 | ||
| 115 | if (client) | 129 | if (client) |
| 116 | evdev_pass_event(client, &event, time_mono, time_real); | 130 | evdev_pass_values(client, vals, count, time_mono, time_real); |
| 117 | else | 131 | else |
| 118 | list_for_each_entry_rcu(client, &evdev->client_list, node) | 132 | list_for_each_entry_rcu(client, &evdev->client_list, node) |
| 119 | evdev_pass_event(client, &event, time_mono, time_real); | 133 | evdev_pass_values(client, vals, count, |
| 134 | time_mono, time_real); | ||
| 120 | 135 | ||
| 121 | rcu_read_unlock(); | 136 | rcu_read_unlock(); |
| 137 | } | ||
| 122 | 138 | ||
| 123 | if (type == EV_SYN && code == SYN_REPORT) | 139 | /* |
| 124 | wake_up_interruptible(&evdev->wait); | 140 | * Pass incoming event to all connected clients. |
| 141 | */ | ||
| 142 | static void evdev_event(struct input_handle *handle, | ||
| 143 | unsigned int type, unsigned int code, int value) | ||
| 144 | { | ||
| 145 | struct input_value vals[] = { { type, code, value } }; | ||
| 146 | |||
| 147 | evdev_events(handle, vals, 1); | ||
| 125 | } | 148 | } |
| 126 | 149 | ||
| 127 | static int evdev_fasync(int fd, struct file *file, int on) | 150 | static int evdev_fasync(int fd, struct file *file, int on) |
| @@ -285,35 +308,16 @@ static unsigned int evdev_compute_buffer_size(struct input_dev *dev) | |||
| 285 | 308 | ||
| 286 | static int evdev_open(struct inode *inode, struct file *file) | 309 | static int evdev_open(struct inode *inode, struct file *file) |
| 287 | { | 310 | { |
| 288 | struct evdev *evdev; | 311 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); |
| 312 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); | ||
| 289 | struct evdev_client *client; | 313 | struct evdev_client *client; |
| 290 | int i = iminor(inode) - EVDEV_MINOR_BASE; | ||
| 291 | unsigned int bufsize; | ||
| 292 | int error; | 314 | int error; |
| 293 | 315 | ||
| 294 | if (i >= EVDEV_MINORS) | ||
| 295 | return -ENODEV; | ||
| 296 | |||
| 297 | error = mutex_lock_interruptible(&evdev_table_mutex); | ||
| 298 | if (error) | ||
| 299 | return error; | ||
| 300 | evdev = evdev_table[i]; | ||
| 301 | if (evdev) | ||
| 302 | get_device(&evdev->dev); | ||
| 303 | mutex_unlock(&evdev_table_mutex); | ||
| 304 | |||
| 305 | if (!evdev) | ||
| 306 | return -ENODEV; | ||
| 307 | |||
| 308 | bufsize = evdev_compute_buffer_size(evdev->handle.dev); | ||
| 309 | |||
| 310 | client = kzalloc(sizeof(struct evdev_client) + | 316 | client = kzalloc(sizeof(struct evdev_client) + |
| 311 | bufsize * sizeof(struct input_event), | 317 | bufsize * sizeof(struct input_event), |
| 312 | GFP_KERNEL); | 318 | GFP_KERNEL); |
| 313 | if (!client) { | 319 | if (!client) |
| 314 | error = -ENOMEM; | 320 | return -ENOMEM; |
| 315 | goto err_put_evdev; | ||
| 316 | } | ||
| 317 | 321 | ||
| 318 | client->bufsize = bufsize; | 322 | client->bufsize = bufsize; |
| 319 | spin_lock_init(&client->buffer_lock); | 323 | spin_lock_init(&client->buffer_lock); |
| @@ -327,13 +331,12 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
| 327 | file->private_data = client; | 331 | file->private_data = client; |
| 328 | nonseekable_open(inode, file); | 332 | nonseekable_open(inode, file); |
| 329 | 333 | ||
| 334 | get_device(&evdev->dev); | ||
| 330 | return 0; | 335 | return 0; |
| 331 | 336 | ||
| 332 | err_free_client: | 337 | err_free_client: |
| 333 | evdev_detach_client(evdev, client); | 338 | evdev_detach_client(evdev, client); |
| 334 | kfree(client); | 339 | kfree(client); |
| 335 | err_put_evdev: | ||
| 336 | put_device(&evdev->dev); | ||
| 337 | return error; | 340 | return error; |
| 338 | } | 341 | } |
| 339 | 342 | ||
| @@ -653,20 +656,22 @@ static int evdev_handle_mt_request(struct input_dev *dev, | |||
| 653 | unsigned int size, | 656 | unsigned int size, |
| 654 | int __user *ip) | 657 | int __user *ip) |
| 655 | { | 658 | { |
| 656 | const struct input_mt_slot *mt = dev->mt; | 659 | const struct input_mt *mt = dev->mt; |
| 657 | unsigned int code; | 660 | unsigned int code; |
| 658 | int max_slots; | 661 | int max_slots; |
| 659 | int i; | 662 | int i; |
| 660 | 663 | ||
| 661 | if (get_user(code, &ip[0])) | 664 | if (get_user(code, &ip[0])) |
| 662 | return -EFAULT; | 665 | return -EFAULT; |
| 663 | if (!input_is_mt_value(code)) | 666 | if (!mt || !input_is_mt_value(code)) |
| 664 | return -EINVAL; | 667 | return -EINVAL; |
| 665 | 668 | ||
| 666 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); | 669 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); |
| 667 | for (i = 0; i < dev->mtsize && i < max_slots; i++) | 670 | for (i = 0; i < mt->num_slots && i < max_slots; i++) { |
| 668 | if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i])) | 671 | int value = input_mt_get_value(&mt->slots[i], code); |
| 672 | if (put_user(value, &ip[1 + i])) | ||
| 669 | return -EFAULT; | 673 | return -EFAULT; |
| 674 | } | ||
| 670 | 675 | ||
| 671 | return 0; | 676 | return 0; |
| 672 | } | 677 | } |
| @@ -915,26 +920,6 @@ static const struct file_operations evdev_fops = { | |||
| 915 | .llseek = no_llseek, | 920 | .llseek = no_llseek, |
| 916 | }; | 921 | }; |
| 917 | 922 | ||
| 918 | static int evdev_install_chrdev(struct evdev *evdev) | ||
| 919 | { | ||
| 920 | /* | ||
| 921 | * No need to do any locking here as calls to connect and | ||
| 922 | * disconnect are serialized by the input core | ||
| 923 | */ | ||
| 924 | evdev_table[evdev->minor] = evdev; | ||
| 925 | return 0; | ||
| 926 | } | ||
| 927 | |||
| 928 | static void evdev_remove_chrdev(struct evdev *evdev) | ||
| 929 | { | ||
| 930 | /* | ||
| 931 | * Lock evdev table to prevent race with evdev_open() | ||
| 932 | */ | ||
| 933 | mutex_lock(&evdev_table_mutex); | ||
| 934 | evdev_table[evdev->minor] = NULL; | ||
| 935 | mutex_unlock(&evdev_table_mutex); | ||
| 936 | } | ||
| 937 | |||
| 938 | /* | 923 | /* |
| 939 | * Mark device non-existent. This disables writes, ioctls and | 924 | * Mark device non-existent. This disables writes, ioctls and |
| 940 | * prevents new users from opening the device. Already posted | 925 | * prevents new users from opening the device. Already posted |
| @@ -953,7 +938,8 @@ static void evdev_cleanup(struct evdev *evdev) | |||
| 953 | 938 | ||
| 954 | evdev_mark_dead(evdev); | 939 | evdev_mark_dead(evdev); |
| 955 | evdev_hangup(evdev); | 940 | evdev_hangup(evdev); |
| 956 | evdev_remove_chrdev(evdev); | 941 | |
| 942 | cdev_del(&evdev->cdev); | ||
| 957 | 943 | ||
| 958 | /* evdev is marked dead so no one else accesses evdev->open */ | 944 | /* evdev is marked dead so no one else accesses evdev->open */ |
| 959 | if (evdev->open) { | 945 | if (evdev->open) { |
| @@ -964,43 +950,47 @@ static void evdev_cleanup(struct evdev *evdev) | |||
| 964 | 950 | ||
| 965 | /* | 951 | /* |
| 966 | * Create new evdev device. Note that input core serializes calls | 952 | * Create new evdev device. Note that input core serializes calls |
| 967 | * to connect and disconnect so we don't need to lock evdev_table here. | 953 | * to connect and disconnect. |
| 968 | */ | 954 | */ |
| 969 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | 955 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, |
| 970 | const struct input_device_id *id) | 956 | const struct input_device_id *id) |
| 971 | { | 957 | { |
| 972 | struct evdev *evdev; | 958 | struct evdev *evdev; |
| 973 | int minor; | 959 | int minor; |
| 960 | int dev_no; | ||
| 974 | int error; | 961 | int error; |
| 975 | 962 | ||
| 976 | for (minor = 0; minor < EVDEV_MINORS; minor++) | 963 | minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true); |
| 977 | if (!evdev_table[minor]) | 964 | if (minor < 0) { |
| 978 | break; | 965 | error = minor; |
| 979 | 966 | pr_err("failed to reserve new minor: %d\n", error); | |
| 980 | if (minor == EVDEV_MINORS) { | 967 | return error; |
| 981 | pr_err("no more free evdev devices\n"); | ||
| 982 | return -ENFILE; | ||
| 983 | } | 968 | } |
| 984 | 969 | ||
| 985 | evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); | 970 | evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); |
| 986 | if (!evdev) | 971 | if (!evdev) { |
| 987 | return -ENOMEM; | 972 | error = -ENOMEM; |
| 973 | goto err_free_minor; | ||
| 974 | } | ||
| 988 | 975 | ||
| 989 | INIT_LIST_HEAD(&evdev->client_list); | 976 | INIT_LIST_HEAD(&evdev->client_list); |
| 990 | spin_lock_init(&evdev->client_lock); | 977 | spin_lock_init(&evdev->client_lock); |
| 991 | mutex_init(&evdev->mutex); | 978 | mutex_init(&evdev->mutex); |
| 992 | init_waitqueue_head(&evdev->wait); | 979 | init_waitqueue_head(&evdev->wait); |
| 993 | |||
| 994 | dev_set_name(&evdev->dev, "event%d", minor); | ||
| 995 | evdev->exist = true; | 980 | evdev->exist = true; |
| 996 | evdev->minor = minor; | 981 | |
| 982 | dev_no = minor; | ||
| 983 | /* Normalize device number if it falls into legacy range */ | ||
| 984 | if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS) | ||
| 985 | dev_no -= EVDEV_MINOR_BASE; | ||
| 986 | dev_set_name(&evdev->dev, "event%d", dev_no); | ||
| 997 | 987 | ||
| 998 | evdev->handle.dev = input_get_device(dev); | 988 | evdev->handle.dev = input_get_device(dev); |
| 999 | evdev->handle.name = dev_name(&evdev->dev); | 989 | evdev->handle.name = dev_name(&evdev->dev); |
| 1000 | evdev->handle.handler = handler; | 990 | evdev->handle.handler = handler; |
| 1001 | evdev->handle.private = evdev; | 991 | evdev->handle.private = evdev; |
| 1002 | 992 | ||
| 1003 | evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); | 993 | evdev->dev.devt = MKDEV(INPUT_MAJOR, minor); |
| 1004 | evdev->dev.class = &input_class; | 994 | evdev->dev.class = &input_class; |
| 1005 | evdev->dev.parent = &dev->dev; | 995 | evdev->dev.parent = &dev->dev; |
| 1006 | evdev->dev.release = evdev_free; | 996 | evdev->dev.release = evdev_free; |
| @@ -1010,7 +1000,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 1010 | if (error) | 1000 | if (error) |
| 1011 | goto err_free_evdev; | 1001 | goto err_free_evdev; |
| 1012 | 1002 | ||
| 1013 | error = evdev_install_chrdev(evdev); | 1003 | cdev_init(&evdev->cdev, &evdev_fops); |
| 1004 | error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); | ||
| 1014 | if (error) | 1005 | if (error) |
| 1015 | goto err_unregister_handle; | 1006 | goto err_unregister_handle; |
| 1016 | 1007 | ||
| @@ -1026,6 +1017,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 1026 | input_unregister_handle(&evdev->handle); | 1017 | input_unregister_handle(&evdev->handle); |
| 1027 | err_free_evdev: | 1018 | err_free_evdev: |
| 1028 | put_device(&evdev->dev); | 1019 | put_device(&evdev->dev); |
| 1020 | err_free_minor: | ||
| 1021 | input_free_minor(minor); | ||
| 1029 | return error; | 1022 | return error; |
| 1030 | } | 1023 | } |
| 1031 | 1024 | ||
| @@ -1035,6 +1028,7 @@ static void evdev_disconnect(struct input_handle *handle) | |||
| 1035 | 1028 | ||
| 1036 | device_del(&evdev->dev); | 1029 | device_del(&evdev->dev); |
| 1037 | evdev_cleanup(evdev); | 1030 | evdev_cleanup(evdev); |
| 1031 | input_free_minor(MINOR(evdev->dev.devt)); | ||
| 1038 | input_unregister_handle(handle); | 1032 | input_unregister_handle(handle); |
| 1039 | put_device(&evdev->dev); | 1033 | put_device(&evdev->dev); |
| 1040 | } | 1034 | } |
| @@ -1048,9 +1042,10 @@ MODULE_DEVICE_TABLE(input, evdev_ids); | |||
| 1048 | 1042 | ||
| 1049 | static struct input_handler evdev_handler = { | 1043 | static struct input_handler evdev_handler = { |
| 1050 | .event = evdev_event, | 1044 | .event = evdev_event, |
| 1045 | .events = evdev_events, | ||
| 1051 | .connect = evdev_connect, | 1046 | .connect = evdev_connect, |
| 1052 | .disconnect = evdev_disconnect, | 1047 | .disconnect = evdev_disconnect, |
| 1053 | .fops = &evdev_fops, | 1048 | .legacy_minors = true, |
| 1054 | .minor = EVDEV_MINOR_BASE, | 1049 | .minor = EVDEV_MINOR_BASE, |
| 1055 | .name = "evdev", | 1050 | .name = "evdev", |
| 1056 | .id_table = evdev_ids, | 1051 | .id_table = evdev_ids, |
