From e0a20bb89ded22eec9a9dc76cd030d3f55d83051 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Thu, 13 Sep 2012 06:59:36 +0200 Subject: [PATCH 2/3] Revert "Input: Send events one packet at a time" This reverts commit b276fc1e875a51e4a9dc3322ed008bf4ae481baf. --- drivers/input/input.c | 176 +++++++++++++++---------------------------------- include/linux/input.h | 24 +------ 2 files changed, 56 insertions(+), 144 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index e4ee39f..2e96c3f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -47,8 +47,6 @@ static DEFINE_MUTEX(input_mutex); static struct input_handler *input_table[8]; -static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; - static inline int is_event_supported(unsigned int code, unsigned long *bm, unsigned int max) { @@ -92,81 +90,46 @@ static void input_stop_autorepeat(struct input_dev *dev) * filtered out, through all open handles. This function is called with * dev->event_lock held and interrupts disabled. */ -static unsigned int input_to_handler(struct input_handle *handle, - struct input_value *vals, unsigned int count) +static void input_pass_event(struct input_dev *dev, + unsigned int type, unsigned int code, int value) { - struct input_handler *handler = handle->handler; - struct input_value *end = vals; - struct input_value *v; - - for (v = vals; v != vals + count; v++) { - if (handler->filter && - handler->filter(handle, v->type, v->code, v->value)) - continue; - if (end != v) - *end = *v; - end++; - } - - count = end - vals; - if (!count) - return 0; + struct input_handler *handler; + struct input_handle *handle; - if (handler->events) - handler->events(handle, vals, count); - else - for (v = vals; v != end; v++) - handler->event(handle, v->type, v->code, v->value); + rcu_read_lock(); - return count; -} + handle = rcu_dereference(dev->grab); + if (handle) + handle->handler->event(handle, type, code, value); + else { + bool filtered = false; -/* - * Pass values first through all filters and then, if event has not been - * filtered out, through all open handles. This function is called with - * dev->event_lock held and interrupts disabled. - */ -static void input_pass_values(struct input_dev *dev, - struct input_value *vals, unsigned int count) -{ - struct input_handle *handle; - struct input_value *v; + list_for_each_entry_rcu(handle, &dev->h_list, d_node) { + if (!handle->open) + continue; - if (!count) - return; + handler = handle->handler; + if (!handler->filter) { + if (filtered) + break; - rcu_read_lock(); + handler->event(handle, type, code, value); - handle = rcu_dereference(dev->grab); - if (handle) { - count = input_to_handler(handle, vals, count); - } else { - list_for_each_entry_rcu(handle, &dev->h_list, d_node) - if (handle->open) - count = input_to_handler(handle, vals, count); + } else if (handler->filter(handle, type, code, value)) + filtered = true; + } } rcu_read_unlock(); - add_input_randomness(vals->type, vals->code, vals->value); - /* trigger auto repeat for key events */ - for (v = vals; v != vals + count; v++) { - if (v->type == EV_KEY && v->value != 2) { - if (v->value) - input_start_autorepeat(dev, v->code); - else - input_stop_autorepeat(dev); - } + if (type == EV_KEY && value != 2) { + if (value) + input_start_autorepeat(dev, code); + else + input_stop_autorepeat(dev); } -} - -static void input_pass_event(struct input_dev *dev, - unsigned int type, unsigned int code, int value) -{ - struct input_value vals[] = { { type, code, value } }; - input_pass_values(dev, vals, ARRAY_SIZE(vals)); } /* @@ -183,12 +146,18 @@ static void input_repeat_key(unsigned long data) if (test_bit(dev->repeat_key, dev->key) && is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { - struct input_value vals[] = { - { EV_KEY, dev->repeat_key, 2 }, - input_value_sync - }; - input_pass_values(dev, vals, ARRAY_SIZE(vals)); + input_pass_event(dev, EV_KEY, dev->repeat_key, 2); + + if (dev->sync) { + /* + * Only send SYN_REPORT if we are not in a middle + * of driver parsing a new hardware packet. + * Otherwise assume that the driver will send + * SYN_REPORT once it's done. + */ + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); + } if (dev->rep[REP_PERIOD]) mod_timer(&dev->timer, jiffies + @@ -201,8 +170,6 @@ static void input_repeat_key(unsigned long data) #define INPUT_IGNORE_EVENT 0 #define INPUT_PASS_TO_HANDLERS 1 #define INPUT_PASS_TO_DEVICE 2 -#define INPUT_SLOT 4 -#define INPUT_FLUSH 8 #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) static int input_handle_abs_event(struct input_dev *dev, @@ -248,14 +215,14 @@ static int input_handle_abs_event(struct input_dev *dev, /* Flush pending "slot" event */ if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); - return INPUT_PASS_TO_HANDLERS | INPUT_SLOT; + input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); } return INPUT_PASS_TO_HANDLERS; } -static int input_get_disposition(struct input_dev *dev, - unsigned int type, unsigned int code, int value) +static void input_handle_event(struct input_dev *dev, + unsigned int type, unsigned int code, int value) { int disposition = INPUT_IGNORE_EVENT; @@ -268,9 +235,13 @@ static int input_get_disposition(struct input_dev *dev, break; case SYN_REPORT: - disposition = INPUT_PASS_TO_HANDLERS | INPUT_FLUSH; + if (!dev->sync) { + dev->sync = true; + disposition = INPUT_PASS_TO_HANDLERS; + } break; case SYN_MT_REPORT: + dev->sync = false; disposition = INPUT_PASS_TO_HANDLERS; break; } @@ -355,48 +326,14 @@ static int input_get_disposition(struct input_dev *dev, break; } - return disposition; -} - -static void input_handle_event(struct input_dev *dev, - unsigned int type, unsigned int code, int value) -{ - int disposition; - - disposition = input_get_disposition(dev, type, code, value); + if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) + dev->sync = false; if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) dev->event(dev, type, code, value); - if (!dev->vals) - return; - - if (disposition & INPUT_PASS_TO_HANDLERS) { - struct input_value *v; - - if (disposition & INPUT_SLOT) { - v = &dev->vals[dev->num_vals++]; - v->type = EV_ABS; - v->code = ABS_MT_SLOT; - v->value = dev->slot; - } - - v = &dev->vals[dev->num_vals++]; - v->type = type; - v->code = code; - v->value = value; - } - - if (disposition & INPUT_FLUSH) { - if (dev->num_vals >= 2) - input_pass_values(dev, dev->vals, dev->num_vals); - dev->num_vals = 0; - } else if (dev->num_vals >= dev->max_vals - 2) { - dev->vals[dev->num_vals++] = input_value_sync; - input_pass_values(dev, dev->vals, dev->num_vals); - dev->num_vals = 0; - } - + if (disposition & INPUT_PASS_TO_HANDLERS) + input_pass_event(dev, type, code, value); } /** @@ -424,6 +361,7 @@ void input_event(struct input_dev *dev, if (is_event_supported(type, dev->evbit, EV_MAX)) { spin_lock_irqsave(&dev->event_lock, flags); + add_input_randomness(type, code, value); input_handle_event(dev, type, code, value); spin_unlock_irqrestore(&dev->event_lock, flags); } @@ -902,12 +840,10 @@ int input_set_keycode(struct input_dev *dev, if (test_bit(EV_KEY, dev->evbit) && !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && __test_and_clear_bit(old_keycode, dev->key)) { - struct input_value vals[] = { - { EV_KEY, old_keycode, 0 }, - input_value_sync - }; - input_pass_values(dev, vals, ARRAY_SIZE(vals)); + input_pass_event(dev, EV_KEY, old_keycode, 0); + if (dev->sync) + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } out: @@ -1498,7 +1434,6 @@ static void input_dev_release(struct device *device) input_ff_destroy(dev); input_mt_destroy_slots(dev); kfree(dev->absinfo); - kfree(dev->vals); kfree(dev); module_put(THIS_MODULE); @@ -1919,11 +1854,6 @@ int input_register_device(struct input_dev *dev) if (dev->hint_events_per_packet < packet_size) dev->hint_events_per_packet = packet_size; - dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; - dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); - if (!dev->vals) - return -ENOMEM; - /* * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. diff --git a/include/linux/input.h b/include/linux/input.h index 797f335..76d6788 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1169,18 +1169,6 @@ struct ff_effect { #include /** - * struct input_value - input value representation - * @type: type of value (EV_KEY, EV_ABS, etc) - * @code: the value code - * @value: the value - */ -struct input_value { - __u16 type; - __u16 code; - __s32 value; -}; - -/** * struct input_dev - represents an input device * @name: name of the device * @phys: physical path to the device in the system hierarchy @@ -1253,6 +1241,7 @@ struct input_value { * last user closes the device * @going_away: marks devices that are in a middle of unregistering and * causes input_open_device*() fail with -ENODEV. + * @sync: set to %true when there were no new events since last EV_SYN * @dev: driver model's view of this device * @h_list: list of input handles associated with the device. When * accessing the list dev->mutex must be held @@ -1318,14 +1307,12 @@ struct input_dev { unsigned int users; bool going_away; + bool sync; + struct device dev; struct list_head h_list; struct list_head node; - - unsigned int num_vals; - unsigned int max_vals; - struct input_value *vals; }; #define to_input_dev(d) container_of(d, struct input_dev, dev) @@ -1386,9 +1373,6 @@ struct input_handle; * @event: event handler. This method is being called by input core with * interrupts disabled and dev->event_lock spinlock held and so * it may not sleep - * @events: event sequence handler. This method is being called by - * input core with interrupts disabled and dev->event_lock - * spinlock held and so it may not sleep * @filter: similar to @event; separates normal event handlers from * "filters". * @match: called after comparing device's id with handler's id_table @@ -1425,8 +1409,6 @@ struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); - void (*events)(struct input_handle *handle, - const struct input_value *vals, unsigned int count); bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*match)(struct input_handler *handler, struct input_dev *dev); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); -- 1.7.9.5