Merge branch 'next' into for-linus
This commit is contained in:
@@ -87,12 +87,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass event through all open handles. This function is called with
|
||||
* Pass event 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_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
struct input_handler *handler;
|
||||
struct input_handle *handle;
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -100,11 +102,25 @@ static void input_pass_event(struct input_dev *dev,
|
||||
handle = rcu_dereference(dev->grab);
|
||||
if (handle)
|
||||
handle->handler->event(handle, type, code, value);
|
||||
else
|
||||
list_for_each_entry_rcu(handle, &dev->h_list, d_node)
|
||||
if (handle->open)
|
||||
handle->handler->event(handle,
|
||||
type, code, value);
|
||||
else {
|
||||
bool filtered = false;
|
||||
|
||||
list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
|
||||
if (!handle->open)
|
||||
continue;
|
||||
|
||||
handler = handle->handler;
|
||||
if (!handler->filter) {
|
||||
if (filtered)
|
||||
break;
|
||||
|
||||
handler->event(handle, type, code, value);
|
||||
|
||||
} else if (handler->filter(handle, type, code, value))
|
||||
filtered = true;
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -615,12 +631,12 @@ static int input_default_setkeycode(struct input_dev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
clear_bit(old_keycode, dev->keybit);
|
||||
set_bit(keycode, dev->keybit);
|
||||
__clear_bit(old_keycode, dev->keybit);
|
||||
__set_bit(keycode, dev->keybit);
|
||||
|
||||
for (i = 0; i < dev->keycodemax; i++) {
|
||||
if (input_fetch_keycode(dev, i) == old_keycode) {
|
||||
set_bit(old_keycode, dev->keybit);
|
||||
__set_bit(old_keycode, dev->keybit);
|
||||
break; /* Setting the bit twice is useless, so break */
|
||||
}
|
||||
}
|
||||
@@ -678,6 +694,9 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
/* Make sure KEY_RESERVED did not get enabled. */
|
||||
__clear_bit(KEY_RESERVED, dev->keybit);
|
||||
|
||||
/*
|
||||
* Simulate keyup event if keycode is not present
|
||||
* in the keymap anymore
|
||||
@@ -705,12 +724,13 @@ EXPORT_SYMBOL(input_set_keycode);
|
||||
if (i != BITS_TO_LONGS(max)) \
|
||||
continue;
|
||||
|
||||
static const struct input_device_id *input_match_device(const struct input_device_id *id,
|
||||
static const struct input_device_id *input_match_device(struct input_handler *handler,
|
||||
struct input_dev *dev)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
int i;
|
||||
|
||||
for (; id->flags || id->driver_info; id++) {
|
||||
for (id = handler->id_table; id->flags || id->driver_info; id++) {
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
|
||||
if (id->bustype != dev->id.bustype)
|
||||
@@ -738,7 +758,8 @@ static const struct input_device_id *input_match_device(const struct input_devic
|
||||
MATCH_BIT(ffbit, FF_MAX);
|
||||
MATCH_BIT(swbit, SW_MAX);
|
||||
|
||||
return id;
|
||||
if (!handler->match || handler->match(handler, dev))
|
||||
return id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -749,10 +770,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
|
||||
const struct input_device_id *id;
|
||||
int error;
|
||||
|
||||
if (handler->blacklist && input_match_device(handler->blacklist, dev))
|
||||
return -ENODEV;
|
||||
|
||||
id = input_match_device(handler->id_table, dev);
|
||||
id = input_match_device(handler, dev);
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -988,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v)
|
||||
union input_seq_state *state = (union input_seq_state *)&seq->private;
|
||||
|
||||
seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
|
||||
if (handler->filter)
|
||||
seq_puts(seq, " (filter)");
|
||||
if (handler->fops)
|
||||
seq_printf(seq, " Minor=%d", handler->minor);
|
||||
seq_putc(seq, '\n');
|
||||
@@ -1551,6 +1571,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
|
||||
}
|
||||
EXPORT_SYMBOL(input_set_capability);
|
||||
|
||||
#define INPUT_CLEANSE_BITMASK(dev, type, bits) \
|
||||
do { \
|
||||
if (!test_bit(EV_##type, dev->evbit)) \
|
||||
memset(dev->bits##bit, 0, \
|
||||
sizeof(dev->bits##bit)); \
|
||||
} while (0)
|
||||
|
||||
static void input_cleanse_bitmasks(struct input_dev *dev)
|
||||
{
|
||||
INPUT_CLEANSE_BITMASK(dev, KEY, key);
|
||||
INPUT_CLEANSE_BITMASK(dev, REL, rel);
|
||||
INPUT_CLEANSE_BITMASK(dev, ABS, abs);
|
||||
INPUT_CLEANSE_BITMASK(dev, MSC, msc);
|
||||
INPUT_CLEANSE_BITMASK(dev, LED, led);
|
||||
INPUT_CLEANSE_BITMASK(dev, SND, snd);
|
||||
INPUT_CLEANSE_BITMASK(dev, FF, ff);
|
||||
INPUT_CLEANSE_BITMASK(dev, SW, sw);
|
||||
}
|
||||
|
||||
/**
|
||||
* input_register_device - register device with input core
|
||||
* @dev: device to be registered
|
||||
@@ -1570,13 +1609,19 @@ int input_register_device(struct input_dev *dev)
|
||||
const char *path;
|
||||
int error;
|
||||
|
||||
/* Every input device generates EV_SYN/SYN_REPORT events. */
|
||||
__set_bit(EV_SYN, dev->evbit);
|
||||
|
||||
/* KEY_RESERVED is not supposed to be transmitted to userspace. */
|
||||
__clear_bit(KEY_RESERVED, dev->keybit);
|
||||
|
||||
/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
|
||||
input_cleanse_bitmasks(dev);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
init_timer(&dev->timer);
|
||||
if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
|
||||
dev->timer.data = (long) dev;
|
||||
@@ -1776,7 +1821,16 @@ int input_register_handle(struct input_handle *handle)
|
||||
error = mutex_lock_interruptible(&dev->mutex);
|
||||
if (error)
|
||||
return error;
|
||||
list_add_tail_rcu(&handle->d_node, &dev->h_list);
|
||||
|
||||
/*
|
||||
* Filters go to the head of the list, normal handlers
|
||||
* to the tail.
|
||||
*/
|
||||
if (handler->filter)
|
||||
list_add_rcu(&handle->d_node, &dev->h_list);
|
||||
else
|
||||
list_add_tail_rcu(&handle->d_node, &dev->h_list);
|
||||
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user