aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 2ee6c7a68bdc..054edf346e0b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -10,7 +10,8 @@
10 10
11#define EVDEV_MINOR_BASE 64 11#define EVDEV_MINOR_BASE 64
12#define EVDEV_MINORS 32 12#define EVDEV_MINORS 32
13#define EVDEV_BUFFER_SIZE 64 13#define EVDEV_MIN_BUFFER_SIZE 64U
14#define EVDEV_BUF_PACKETS 8
14 15
15#include <linux/poll.h> 16#include <linux/poll.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
@@ -23,7 +24,6 @@
23#include "input-compat.h" 24#include "input-compat.h"
24 25
25struct evdev { 26struct evdev {
26 int exist;
27 int open; 27 int open;
28 int minor; 28 int minor;
29 struct input_handle handle; 29 struct input_handle handle;
@@ -33,16 +33,18 @@ struct evdev {
33 spinlock_t client_lock; /* protects client_list */ 33 spinlock_t client_lock; /* protects client_list */
34 struct mutex mutex; 34 struct mutex mutex;
35 struct device dev; 35 struct device dev;
36 bool exist;
36}; 37};
37 38
38struct evdev_client { 39struct evdev_client {
39 struct input_event buffer[EVDEV_BUFFER_SIZE];
40 int head; 40 int head;
41 int tail; 41 int tail;
42 spinlock_t buffer_lock; /* protects access to buffer, head and tail */ 42 spinlock_t buffer_lock; /* protects access to buffer, head and tail */
43 struct fasync_struct *fasync; 43 struct fasync_struct *fasync;
44 struct evdev *evdev; 44 struct evdev *evdev;
45 struct list_head node; 45 struct list_head node;
46 int bufsize;
47 struct input_event buffer[];
46}; 48};
47 49
48static struct evdev *evdev_table[EVDEV_MINORS]; 50static struct evdev *evdev_table[EVDEV_MINORS];
@@ -52,11 +54,15 @@ static void evdev_pass_event(struct evdev_client *client,
52 struct input_event *event) 54 struct input_event *event)
53{ 55{
54 /* 56 /*
55 * Interrupts are disabled, just acquire the lock 57 * Interrupts are disabled, just acquire the lock.
58 * Make sure we don't leave with the client buffer
59 * "empty" by having client->head == client->tail.
56 */ 60 */
57 spin_lock(&client->buffer_lock); 61 spin_lock(&client->buffer_lock);
58 client->buffer[client->head++] = *event; 62 do {
59 client->head &= EVDEV_BUFFER_SIZE - 1; 63 client->buffer[client->head++] = *event;
64 client->head &= client->bufsize - 1;
65 } while (client->head == client->tail);
60 spin_unlock(&client->buffer_lock); 66 spin_unlock(&client->buffer_lock);
61 67
62 if (event->type == EV_SYN) 68 if (event->type == EV_SYN)
@@ -242,11 +248,21 @@ static int evdev_release(struct inode *inode, struct file *file)
242 return 0; 248 return 0;
243} 249}
244 250
251static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
252{
253 unsigned int n_events =
254 max(dev->hint_events_per_packet * EVDEV_BUF_PACKETS,
255 EVDEV_MIN_BUFFER_SIZE);
256
257 return roundup_pow_of_two(n_events);
258}
259
245static int evdev_open(struct inode *inode, struct file *file) 260static int evdev_open(struct inode *inode, struct file *file)
246{ 261{
247 struct evdev *evdev; 262 struct evdev *evdev;
248 struct evdev_client *client; 263 struct evdev_client *client;
249 int i = iminor(inode) - EVDEV_MINOR_BASE; 264 int i = iminor(inode) - EVDEV_MINOR_BASE;
265 unsigned int bufsize;
250 int error; 266 int error;
251 267
252 if (i >= EVDEV_MINORS) 268 if (i >= EVDEV_MINORS)
@@ -263,12 +279,17 @@ static int evdev_open(struct inode *inode, struct file *file)
263 if (!evdev) 279 if (!evdev)
264 return -ENODEV; 280 return -ENODEV;
265 281
266 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); 282 bufsize = evdev_compute_buffer_size(evdev->handle.dev);
283
284 client = kzalloc(sizeof(struct evdev_client) +
285 bufsize * sizeof(struct input_event),
286 GFP_KERNEL);
267 if (!client) { 287 if (!client) {
268 error = -ENOMEM; 288 error = -ENOMEM;
269 goto err_put_evdev; 289 goto err_put_evdev;
270 } 290 }
271 291
292 client->bufsize = bufsize;
272 spin_lock_init(&client->buffer_lock); 293 spin_lock_init(&client->buffer_lock);
273 client->evdev = evdev; 294 client->evdev = evdev;
274 evdev_attach_client(evdev, client); 295 evdev_attach_client(evdev, client);
@@ -334,7 +355,7 @@ static int evdev_fetch_next_event(struct evdev_client *client,
334 have_event = client->head != client->tail; 355 have_event = client->head != client->tail;
335 if (have_event) { 356 if (have_event) {
336 *event = client->buffer[client->tail++]; 357 *event = client->buffer[client->tail++];
337 client->tail &= EVDEV_BUFFER_SIZE - 1; 358 client->tail &= client->bufsize - 1;
338 } 359 }
339 360
340 spin_unlock_irq(&client->buffer_lock); 361 spin_unlock_irq(&client->buffer_lock);
@@ -382,10 +403,15 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
382{ 403{
383 struct evdev_client *client = file->private_data; 404 struct evdev_client *client = file->private_data;
384 struct evdev *evdev = client->evdev; 405 struct evdev *evdev = client->evdev;
406 unsigned int mask;
385 407
386 poll_wait(file, &evdev->wait, wait); 408 poll_wait(file, &evdev->wait, wait);
387 return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | 409
388 (evdev->exist ? 0 : (POLLHUP | POLLERR)); 410 mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR;
411 if (client->head != client->tail)
412 mask |= POLLIN | POLLRDNORM;
413
414 return mask;
389} 415}
390 416
391#ifdef CONFIG_COMPAT 417#ifdef CONFIG_COMPAT
@@ -665,6 +691,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
665 sizeof(struct input_absinfo)))) 691 sizeof(struct input_absinfo))))
666 return -EFAULT; 692 return -EFAULT;
667 693
694 /* We can't change number of reserved MT slots */
695 if (t == ABS_MT_SLOT)
696 return -EINVAL;
697
668 /* 698 /*
669 * Take event lock to ensure that we are not 699 * Take event lock to ensure that we are not
670 * changing device parameters in the middle 700 * changing device parameters in the middle
@@ -768,7 +798,7 @@ static void evdev_remove_chrdev(struct evdev *evdev)
768static void evdev_mark_dead(struct evdev *evdev) 798static void evdev_mark_dead(struct evdev *evdev)
769{ 799{
770 mutex_lock(&evdev->mutex); 800 mutex_lock(&evdev->mutex);
771 evdev->exist = 0; 801 evdev->exist = false;
772 mutex_unlock(&evdev->mutex); 802 mutex_unlock(&evdev->mutex);
773} 803}
774 804
@@ -817,7 +847,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
817 init_waitqueue_head(&evdev->wait); 847 init_waitqueue_head(&evdev->wait);
818 848
819 dev_set_name(&evdev->dev, "event%d", minor); 849 dev_set_name(&evdev->dev, "event%d", minor);
820 evdev->exist = 1; 850 evdev->exist = true;
821 evdev->minor = minor; 851 evdev->minor = minor;
822 852
823 evdev->handle.dev = input_get_device(dev); 853 evdev->handle.dev = input_get_device(dev);