aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-06-10 15:05:24 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-06-23 16:05:25 -0400
commit63a6404d8ae693e71ab27c4f9c4032aa29113e92 (patch)
treef69345910b0eafc1149adb8e8926a131e1fbea3c
parentb58f7086d52c0ac6c879ee5aaf7c276e17768e5b (diff)
Input: evdev - use driver hint to compute size of event buffer
Some devices, in particular MT devices, produce a lot of data. This may lead to overflowing of the event queues in evdev driver, which by default are fairly small. Let the drivers hint the average number of events per packet generated by the device, and use that information when computing the buffer size evdev should use for the device. Signed-off-by: Henrik Rydberg <rydberg@euromail.se> Acked-by: Chase Douglas <chase.douglas@canonical.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/evdev.c9
-rw-r--r--include/linux/input.h21
2 files changed, 28 insertions, 2 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index cff7bf9351a8..30836c05edd7 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_MIN_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>
@@ -245,7 +246,11 @@ static int evdev_release(struct inode *inode, struct file *file)
245 246
246static unsigned int evdev_compute_buffer_size(struct input_dev *dev) 247static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
247{ 248{
248 return EVDEV_MIN_BUFFER_SIZE; 249 unsigned int n_events =
250 max(dev->hint_events_per_packet * EVDEV_BUF_PACKETS,
251 EVDEV_MIN_BUFFER_SIZE);
252
253 return roundup_pow_of_two(n_events);
249} 254}
250 255
251static int evdev_open(struct inode *inode, struct file *file) 256static int evdev_open(struct inode *inode, struct file *file)
diff --git a/include/linux/input.h b/include/linux/input.h
index 6fcc9101beeb..cc524c8b6703 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1063,6 +1063,10 @@ struct ff_effect {
1063 * @sndbit: bitmap of sound effects supported by the device 1063 * @sndbit: bitmap of sound effects supported by the device
1064 * @ffbit: bitmap of force feedback effects supported by the device 1064 * @ffbit: bitmap of force feedback effects supported by the device
1065 * @swbit: bitmap of switches present on the device 1065 * @swbit: bitmap of switches present on the device
1066 * @hint_events_per_packet: average number of events generated by the
1067 * device in a packet (between EV_SYN/SYN_REPORT events). Used by
1068 * event handlers to estimate size of the buffer needed to hold
1069 * events.
1066 * @keycodemax: size of keycode table 1070 * @keycodemax: size of keycode table
1067 * @keycodesize: size of elements in keycode table 1071 * @keycodesize: size of elements in keycode table
1068 * @keycode: map of scancodes to keycodes for this device 1072 * @keycode: map of scancodes to keycodes for this device
@@ -1140,6 +1144,8 @@ struct input_dev {
1140 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; 1144 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
1141 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; 1145 unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
1142 1146
1147 unsigned int hint_events_per_packet;
1148
1143 unsigned int keycodemax; 1149 unsigned int keycodemax;
1144 unsigned int keycodesize; 1150 unsigned int keycodesize;
1145 void *keycode; 1151 void *keycode;
@@ -1408,6 +1414,21 @@ static inline void input_mt_sync(struct input_dev *dev)
1408 1414
1409void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code); 1415void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);
1410 1416
1417/**
1418 * input_set_events_per_packet - tell handlers about the driver event rate
1419 * @dev: the input device used by the driver
1420 * @n_events: the average number of events between calls to input_sync()
1421 *
1422 * If the event rate sent from a device is unusually large, use this
1423 * function to set the expected event rate. This will allow handlers
1424 * to set up an appropriate buffer size for the event stream, in order
1425 * to minimize information loss.
1426 */
1427static inline void input_set_events_per_packet(struct input_dev *dev, int n_events)
1428{
1429 dev->hint_events_per_packet = n_events;
1430}
1431
1411static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) 1432static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
1412{ 1433{
1413 dev->absmin[axis] = min; 1434 dev->absmin[axis] = min;