diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2010-06-23 18:17:56 +0200 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-06-23 22:04:42 +0200 |
commit | b58f7086d52c0ac6c879ee5aaf7c276e17768e5b (patch) | |
tree | b4dc1d1b516f36bdf5cda18af3a8a28d5706068a /drivers/input/evdev.c | |
parent | Input: tps6507x-ts - remove unneeded NULL test (diff) | |
download | linux-b58f7086d52c0ac6c879ee5aaf7c276e17768e5b.tar.xz linux-b58f7086d52c0ac6c879ee5aaf7c276e17768e5b.zip |
Input: evdev - convert to dynamic event buffer
Allocate the event buffer dynamically, and prepare to compute the
buffer size in a separate function. This patch defines the size
computation to be identical to the current code, and does not contain
any logical changes.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/evdev.c')
-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 @@ #define EVDEV_MINOR_BASE 64 #define EVDEV_MINORS 32 -#define EVDEV_BUFFER_SIZE 64 +#define EVDEV_MIN_BUFFER_SIZE 64 #include <linux/poll.h> #include <linux/sched.h> @@ -36,13 +36,14 @@ struct evdev { }; struct evdev_client { - struct input_event buffer[EVDEV_BUFFER_SIZE]; int head; int tail; spinlock_t buffer_lock; /* protects access to buffer, head and tail */ struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; + int bufsize; + struct input_event buffer[]; }; static struct evdev *evdev_table[EVDEV_MINORS]; @@ -56,7 +57,7 @@ static void evdev_pass_event(struct evdev_client *client, */ spin_lock(&client->buffer_lock); client->buffer[client->head++] = *event; - client->head &= EVDEV_BUFFER_SIZE - 1; + client->head &= client->bufsize - 1; spin_unlock(&client->buffer_lock); if (event->type == EV_SYN) @@ -242,11 +243,17 @@ static int evdev_release(struct inode *inode, struct file *file) return 0; } +static unsigned int evdev_compute_buffer_size(struct input_dev *dev) +{ + return EVDEV_MIN_BUFFER_SIZE; +} + static int evdev_open(struct inode *inode, struct file *file) { struct evdev *evdev; struct evdev_client *client; int i = iminor(inode) - EVDEV_MINOR_BASE; + unsigned int bufsize; int error; if (i >= EVDEV_MINORS) @@ -263,12 +270,17 @@ static int evdev_open(struct inode *inode, struct file *file) if (!evdev) return -ENODEV; - client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); + bufsize = evdev_compute_buffer_size(evdev->handle.dev); + + client = kzalloc(sizeof(struct evdev_client) + + bufsize * sizeof(struct input_event), + GFP_KERNEL); if (!client) { error = -ENOMEM; goto err_put_evdev; } + client->bufsize = bufsize; spin_lock_init(&client->buffer_lock); client->evdev = evdev; evdev_attach_client(evdev, client); @@ -334,7 +346,7 @@ static int evdev_fetch_next_event(struct evdev_client *client, have_event = client->head != client->tail; if (have_event) { *event = client->buffer[client->tail++]; - client->tail &= EVDEV_BUFFER_SIZE - 1; + client->tail &= client->bufsize - 1; } spin_unlock_irq(&client->buffer_lock); |