input子系统四:输入事件是如何上报的
我们在输入设备驱动中利用函数input_event()函数来上报事件,接下来我们就来看看,内核拿到我们上报的数据之后是如何继续上报到用户空间的
/**
* input_event() - report new input event
* @dev: device that generated the event
* @type: type of the event
* @code: event code
* @value: value of the event
*
* This function should be used by drivers implementing various input
* devices to report input events. See also input_inject_event().
*
* NOTE: input_event() may be safely used right after input device was
* allocated with input_allocate_device(), even before it is registered
* with input_register_device(), but the event will not reach any of the
* input handlers. Such early invocation of input_event() may be used
* to 'seed' initial state of a switch or initial position of absolute
* axis, etc.
*/
void input_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
unsigned long flags;
if (is_event_supported(type, dev->evbit, EV_MAX)) {
//判断设备是否支持这类事件,这也就是我们为什么要在注册设备之前要设置设备的能力了
spin_lock_irqsave(&dev->event_lock, flags);
input_handle_event(dev, type, code, value); //上报事件
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}
--------------------------------------------------------------------
static void input_handle_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
int disposition = input_get_disposition(dev, type, code, &value); //获取如何处理这个事件的方式
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
add_input_randomness(type, code, value);
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->mt->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;
}
}
可以看到事件如何处理跟函数input_get_disposition()有很大的关系,那就先来分析它
static int input_get_disposition(