aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/evdev.c22
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
38struct evdev_client { 38struct 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
48static struct evdev *evdev_table[EVDEV_MINORS]; 49static 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
246static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
247{
248 return EVDEV_MIN_BUFFER_SIZE;
249}
250
245static int evdev_open(struct inode *inode, struct file *file) 251static 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);