diff options
| -rw-r--r-- | Documentation/input/event-codes.txt | 6 | ||||
| -rw-r--r-- | drivers/input/evdev.c | 33 | ||||
| -rw-r--r-- | include/linux/input.h | 1 |
3 files changed, 28 insertions, 12 deletions
diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt index f13aee550409..23fcb05175be 100644 --- a/Documentation/input/event-codes.txt +++ b/Documentation/input/event-codes.txt | |||
| @@ -85,6 +85,12 @@ sent in the evdev event stream. | |||
| 85 | - Used to synchronize and separate touch events. See the | 85 | - Used to synchronize and separate touch events. See the |
| 86 | multi-touch-protocol.txt document for more information. | 86 | multi-touch-protocol.txt document for more information. |
| 87 | 87 | ||
| 88 | * SYN_DROPPED: | ||
| 89 | - Used to indicate buffer overrun in the evdev client's event queue. | ||
| 90 | Client should ignore all events up to and including next SYN_REPORT | ||
| 91 | event and query the device (using EVIOCG* ioctls) to obtain its | ||
| 92 | current state. | ||
| 93 | |||
| 88 | EV_KEY: | 94 | EV_KEY: |
| 89 | ---------- | 95 | ---------- |
| 90 | EV_KEY events take the form KEY_<name> or BTN_<name>. For example, KEY_A is used | 96 | EV_KEY events take the form KEY_<name> or BTN_<name>. For example, KEY_A is used |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 7f42d3a454d2..88d8e4cb419a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -39,13 +39,13 @@ struct evdev { | |||
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | struct evdev_client { | 41 | struct evdev_client { |
| 42 | int head; | 42 | unsigned int head; |
| 43 | int tail; | 43 | unsigned int tail; |
| 44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
| 45 | struct fasync_struct *fasync; | 45 | struct fasync_struct *fasync; |
| 46 | struct evdev *evdev; | 46 | struct evdev *evdev; |
| 47 | struct list_head node; | 47 | struct list_head node; |
| 48 | int bufsize; | 48 | unsigned int bufsize; |
| 49 | struct input_event buffer[]; | 49 | struct input_event buffer[]; |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| @@ -55,16 +55,25 @@ static DEFINE_MUTEX(evdev_table_mutex); | |||
| 55 | static void evdev_pass_event(struct evdev_client *client, | 55 | static void evdev_pass_event(struct evdev_client *client, |
| 56 | struct input_event *event) | 56 | struct input_event *event) |
| 57 | { | 57 | { |
| 58 | /* | 58 | /* Interrupts are disabled, just acquire the lock. */ |
| 59 | * Interrupts are disabled, just acquire the lock. | ||
| 60 | * Make sure we don't leave with the client buffer | ||
| 61 | * "empty" by having client->head == client->tail. | ||
| 62 | */ | ||
| 63 | spin_lock(&client->buffer_lock); | 59 | spin_lock(&client->buffer_lock); |
| 64 | do { | 60 | |
| 65 | client->buffer[client->head++] = *event; | 61 | client->buffer[client->head++] = *event; |
| 66 | client->head &= client->bufsize - 1; | 62 | client->head &= client->bufsize - 1; |
| 67 | } while (client->head == client->tail); | 63 | |
| 64 | if (unlikely(client->head == client->tail)) { | ||
| 65 | /* | ||
| 66 | * This effectively "drops" all unconsumed events, leaving | ||
| 67 | * EV_SYN/SYN_DROPPED plus the newest event in the queue. | ||
| 68 | */ | ||
| 69 | client->tail = (client->head - 2) & (client->bufsize - 1); | ||
| 70 | |||
| 71 | client->buffer[client->tail].time = event->time; | ||
| 72 | client->buffer[client->tail].type = EV_SYN; | ||
| 73 | client->buffer[client->tail].code = SYN_DROPPED; | ||
| 74 | client->buffer[client->tail].value = 0; | ||
| 75 | } | ||
| 76 | |||
| 68 | spin_unlock(&client->buffer_lock); | 77 | spin_unlock(&client->buffer_lock); |
| 69 | 78 | ||
| 70 | if (event->type == EV_SYN) | 79 | if (event->type == EV_SYN) |
diff --git a/include/linux/input.h b/include/linux/input.h index 0cc25e4ce2ab..73a8c6ee595b 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -167,6 +167,7 @@ struct input_keymap_entry { | |||
| 167 | #define SYN_REPORT 0 | 167 | #define SYN_REPORT 0 |
| 168 | #define SYN_CONFIG 1 | 168 | #define SYN_CONFIG 1 |
| 169 | #define SYN_MT_REPORT 2 | 169 | #define SYN_MT_REPORT 2 |
| 170 | #define SYN_DROPPED 3 | ||
| 170 | 171 | ||
| 171 | /* | 172 | /* |
| 172 | * Keys and buttons | 173 | * Keys and buttons |
