diff options
-rw-r--r-- | drivers/input/evdev.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 2ee6c7a68bdc..cff7bf9351a8 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -10,7 +10,7 @@ | |||
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 64 |
14 | 14 | ||
15 | #include <linux/poll.h> | 15 | #include <linux/poll.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
@@ -36,13 +36,14 @@ struct evdev { | |||
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct evdev_client { | 38 | struct evdev_client { |
39 | struct input_event buffer[EVDEV_BUFFER_SIZE]; | ||
40 | int head; | 39 | int head; |
41 | int tail; | 40 | int tail; |
42 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 41 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
43 | struct fasync_struct *fasync; | 42 | struct fasync_struct *fasync; |
44 | struct evdev *evdev; | 43 | struct evdev *evdev; |
45 | struct list_head node; | 44 | struct list_head node; |
45 | int bufsize; | ||
46 | struct input_event buffer[]; | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | static struct evdev *evdev_table[EVDEV_MINORS]; | 49 | static struct evdev *evdev_table[EVDEV_MINORS]; |
@@ -56,7 +57,7 @@ static void evdev_pass_event(struct evdev_client *client, | |||
56 | */ | 57 | */ |
57 | spin_lock(&client->buffer_lock); | 58 | spin_lock(&client->buffer_lock); |
58 | client->buffer[client->head++] = *event; | 59 | client->buffer[client->head++] = *event; |
59 | client->head &= EVDEV_BUFFER_SIZE - 1; | 60 | client->head &= client->bufsize - 1; |
60 | spin_unlock(&client->buffer_lock); | 61 | spin_unlock(&client->buffer_lock); |
61 | 62 | ||
62 | if (event->type == EV_SYN) | 63 | if (event->type == EV_SYN) |
@@ -242,11 +243,17 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
242 | return 0; | 243 | return 0; |
243 | } | 244 | } |
244 | 245 | ||
246 | static unsigned int evdev_compute_buffer_size(struct input_dev *dev) | ||
247 | { | ||
248 | return EVDEV_MIN_BUFFER_SIZE; | ||
249 | } | ||
250 | |||
245 | static int evdev_open(struct inode *inode, struct file *file) | 251 | static int evdev_open(struct inode *inode, struct file *file) |
246 | { | 252 | { |
247 | struct evdev *evdev; | 253 | struct evdev *evdev; |
248 | struct evdev_client *client; | 254 | struct evdev_client *client; |
249 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 255 | int i = iminor(inode) - EVDEV_MINOR_BASE; |
256 | unsigned int bufsize; | ||
250 | int error; | 257 | int error; |
251 | 258 | ||
252 | if (i >= EVDEV_MINORS) | 259 | if (i >= EVDEV_MINORS) |
@@ -263,12 +270,17 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
263 | if (!evdev) | 270 | if (!evdev) |
264 | return -ENODEV; | 271 | return -ENODEV; |
265 | 272 | ||
266 | client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); | 273 | bufsize = evdev_compute_buffer_size(evdev->handle.dev); |
274 | |||
275 | client = kzalloc(sizeof(struct evdev_client) + | ||
276 | bufsize * sizeof(struct input_event), | ||
277 | GFP_KERNEL); | ||
267 | if (!client) { | 278 | if (!client) { |
268 | error = -ENOMEM; | 279 | error = -ENOMEM; |
269 | goto err_put_evdev; | 280 | goto err_put_evdev; |
270 | } | 281 | } |
271 | 282 | ||
283 | client->bufsize = bufsize; | ||
272 | spin_lock_init(&client->buffer_lock); | 284 | spin_lock_init(&client->buffer_lock); |
273 | client->evdev = evdev; | 285 | client->evdev = evdev; |
274 | evdev_attach_client(evdev, client); | 286 | evdev_attach_client(evdev, client); |
@@ -334,7 +346,7 @@ static int evdev_fetch_next_event(struct evdev_client *client, | |||
334 | have_event = client->head != client->tail; | 346 | have_event = client->head != client->tail; |
335 | if (have_event) { | 347 | if (have_event) { |
336 | *event = client->buffer[client->tail++]; | 348 | *event = client->buffer[client->tail++]; |
337 | client->tail &= EVDEV_BUFFER_SIZE - 1; | 349 | client->tail &= client->bufsize - 1; |
338 | } | 350 | } |
339 | 351 | ||
340 | spin_unlock_irq(&client->buffer_lock); | 352 | spin_unlock_irq(&client->buffer_lock); |