<pre name="code" class="plain">diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index f4897c8..5fb50a3 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -61,10 +61,12 @@ struct evdev_client {
static void __pass_event(struct evdev_client *client,
const struct input_event *event)
{
+//:将事件放到一个环形队列中,每个input设备会对应一个固定大小的环形缓冲区
client->buffer[client->head++] = *event;
client->head &= client->bufsize - 1;
if (unlikely(client->head == client->tail)) {
+//:如果环形缓冲区满了,就在最后追加一个值为SYN_DROPPED的EV_SYN事件,用于告诉应用层:这里出了问题。
/*
* This effectively "drops" all unconsumed events, leaving
* EV_SYN/SYN_DROPPED plus the newest event in the queue.
@@ -1113,6 +1115,7 @@ static struct input_handler evdev_handler = {
static int __init evdev_init(void)
{
+//:evdev用于生成每个input设备的事件操作节点(eventX)
return input_register_handler(&evdev_handler);
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 6c58ff0..cfc0ea9 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -116,7 +116,7 @@ static unsigned int input_to_handler(struct input_handle *handle,
count = end - vals;
if (!count)
return 0;
-
+//显然这里的调用会把事件发送到evdev.c中,但是,在input.c中我却无法找到何时这部分代码会被执行!?????
if (handler->events)
handler->events(handle, vals, count);
else if (handler->event)
@@ -282,7 +282,7 @@ static int input_get_disposition(struct input_dev *dev,
break;
}
break;
-
+//17:本次上报的是事件类型是:EV_KEY
case EV_KEY:
if (is_event_supported(code, dev->keybit, KEY_MAX)) {
@@ -291,9 +291,10 @@ static int input_get_disposition(struct input_dev *dev,
disposition = INPUT_PASS_TO_HANDLERS;
break;
}
-
+//18:和上次该扫描码的值进行对比,如果两个值不一样,才会进一步处理,这样可以过滤驱动对同一个扫描码连续上报同样的值。
+//如果前后两次的值一样,input子系统可以在这里将本次事件忽略掉。
if (!!test_bit(code, dev->key) != !!value) {
-
+//key成员是一个bitmap,用于记录每个扫描码上次事件上报的值和上次的值不一样,则反转bitmap中的对应bit数据
__change_bit(code, dev->key);
#if defined(CONFIG_SPRD_DEBUG)
@@ -384,7 +385,7 @@ static void input_handle_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
int disposition;
-
+//16:继续……
disposition = input_get_disposition(dev, type, code, &value);
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
@@ -402,7 +403,8 @@ static void input_handle_event(struct input_dev *dev,
v->code = ABS_MT_SLOT;
v->value = dev->mt->slot;
}
-
+//19:将事件存储在input设备自身的数据缓冲队列中,到这一步,一次由驱动上报的事件(一次report)就处理结束了。
+//:剩下的就是evdev的事情了。
v = &dev->vals[dev->num_vals++];
v->type = type;
v->code = code;
@@ -446,6 +448,7 @@ void input_event(struct input_dev *dev,
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
+//15:继续深入......
input_handle_event(dev, type, code, value);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
@@ -1755,7 +1758,7 @@ EXPORT_SYMBOL_GPL(input_class);
struct input_dev *input_allocate_device(void)
{
struct input_dev *dev;
-
+//2:为一个input设备对象分配内存(分配的内存清零)
dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
if (dev) {
dev->dev.type = &input_dev_type;
@@ -1877,6 +1880,7 @@ EXPORT_SYMBOL(input_free_device);
void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)
{
switch (type) {
+//5:input设备的keybit成员也是一个bitmap,其中的每个bit代表一个特定的按键,某bit为1则表示该input设备支持该按键。
case EV_KEY:
__set_bit(code, dev->keybit);
break;
@@ -1923,7 +1927,7 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
dump_stack();
return;
}
-
+//5.1 同时,这个函数会顺便将事件类型也设置到evbit中。比如本次调用就会将EV_KEY设置到evbit中!!!
__set_bit(type, dev->evbit);
}
EXPORT_SYMBOL(input_set_capability);
@@ -1966,7 +1970,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
return events;
}
-
+//11:清除的条件是evbit中没有涉及到的事件类型对应的bitmap
#define INPUT_CLEANSE_BITMASK(dev, type, bits) \
do { \
if (!test_bit(EV_##type, dev->evbit)) \
@@ -1976,6 +1980,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
static void input_cleanse_bitmasks(struct input_dev *dev)
{
+//10:清除对应bitmap的内容
INPUT_CLEANSE_BITMASK(dev, KEY, key);
INPUT_CLEANSE_BITMASK(dev, REL, rel);
INPUT_CLEANSE_BITMASK(dev, ABS, abs);
@@ -2058,16 +2063,16 @@ int input_register_device(struct input_dev *dev)
devres->input = dev;
}
-
+//7:每个input设备都必须支持EV_SYN事件类型!所以在evbit中设置EV_SYN对应的bit
/* Every input device generates EV_SYN/SYN_REPORT events. */
__set_bit(EV_SYN, dev->evbit);
-
+//8:KEY_RESERVED按键已经不再被支持了!所以在keybit中清除KEY_RESERVED对应的bit
/* KEY_RESERVED is not supposed to be transmitted to userspace. */
__clear_bit(KEY_RESERVED, dev->keybit);
-
+//9:将evbit中未涉及到的事件类型的对应的bitmap全部清零
/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
input_cleanse_bitmasks(dev);
-
+//计算该input设备每次事件上报的数据包大小,即每次事件上报中最多可能有几组值。每个数据包都以sync包结束:input_event(dev, EV_SYN, SYN_REPORT, 0);
packet_size = input_estimate_events_per_packet(dev);
if (dev->hint_events_per_packet < packet_size)
dev->hint_events_per_packet = packet_size;
@@ -2115,7 +2120,7 @@ int input_register_device(struct input_dev *dev)
goto err_device_del;
list_add_tail(&dev->node, &input_dev_list);
-
+//note:B 而这里是遍历handler链表中的每个handler,来和本input设备匹配。(请对比:note:A)
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
@@ -2175,6 +2180,7 @@ EXPORT_SYMBOL(input_unregister_device);
* devices in the system and attaches it to all input devices that
* are compatible with the handler.
*/
+//:evdev.c在初始化时会调用到这里。从而为每个input设备关联对应的event节点
int input_register_handler(struct input_handler *handler)
{
struct input_dev *dev;
@@ -2187,7 +2193,7 @@ int input_register_handler(struct input_handler *handler)
INIT_LIST_HEAD(&handler->h_list);
list_add_tail(&handler->node, &input_handler_list);
-
+//note:A:此处是遍历input设备链表中的每个input设备,来和本handler进行匹配(请对比:note:B)
list_for_each_entry(dev, &input_dev_list, node)
input_attach_handler(dev, handler);
diff --git a/drivers/input/keyboard/gpio_keys_sprd.c b/drivers/input/keyboard/gpio_keys_sprd.c
index e6c1651..72dbf10 100644
--- a/drivers/input/keyboard/gpio_keys_sprd.c
+++ b/drivers/input/keyboard/gpio_keys_sprd.c
@@ -351,6 +351,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
if (state)
input_event(input, type, button->code, button->value);
} else {
+//14:最终调用input子系统的以下函数进行事件上报
input_event(input, type, button->code, !!state);
PRINT_INFO("Key:%s ScanCode:%d value:%d\n", button->desc, button->code, !!state);
}
@@ -361,7 +362,7 @@ static void gpio_keys_gpio_work_func(struct work_struct *work)
{
struct gpio_button_data *bdata =
container_of(work, struct gpio_button_data, work);
-
+//13:在底半部上报事件
gpio_keys_gpio_report_event(bdata);
if (bdata->button->wakeup)
@@ -387,6 +388,7 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(bdata->timer_debounce));
else
+//12:在按键中断,调用底半部
schedule_work(&bdata->work);
return IRQ_HANDLED;
@@ -510,7 +512,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
isr = gpio_keys_irq_isr;
irqflags = 0;
}
-
+//4:设置该设备支持的按键信息,每个按键对应一个bit,如果设备支持该按键,则keybit的对应bit应该被置1
+//同时,这个函数会顺便将事件类型也设置到evbit中。比如本次调用就会将EV_KEY设置到evbit中!!!
input_set_capability(input, button->type ?: EV_KEY, button->code);
/*
@@ -733,6 +736,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
pdata->nbuttons * sizeof(struct gpio_button_data),
GFP_KERNEL);
+//1:申请分配一个input设备,返回申请到的input设备的指针
input = input_allocate_device();
if (!ddata || !input) {
dev_err(dev, "failed to allocate state\n");
@@ -745,6 +749,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
mutex_init(&ddata->disable_lock);
platform_set_drvdata(pdev, ddata);
+//1.1:对该input对象的部分成员进行赋值
input_set_drvdata(input, ddata);
#ifndef CONFIG_OF
input->name = pdata->name ? pdata->name : pdev->name;
@@ -763,6 +768,8 @@ static int gpio_keys_probe(struct platform_device *pdev)
/* Enable auto repeat feature of Linux input subsystem */
if (pdata->rep)
+//3:input设备的evbit成员是一个bitmap,其中的每个bit代表一个事件类型,某bit为1则表示该input设备支持该事件类型。
+//本驱动是一个物理按键驱动,理论上应该设置EV_KEY对应的bit,这里没有看到,相信后续流程中一定会有的!(是的,请深入//4看看!)
__set_bit(EV_REP, input->evbit);
for (i = 0; i < pdata->nbuttons; i++) {
@@ -783,7 +790,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
error);
goto fail2;
}
-
+//6:注册input设备
error = input_register_device(input);
if (error) {
dev_err(dev, "Unable to register input device, error: %d\n",
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index be3a228..48dce88 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -7,6 +7,7 @@
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BITS_PER_BYTE 8
+//note:
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#endif
diff --git a/include/linux/input.h b/include/linux/input.h
index 128e0a5..b9da50c 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -128,11 +128,13 @@ struct input_dev {
struct input_id id;
unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
-
- unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
- unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
+//note:用一个长整型的数组表示一个bitmap,这是很巧妙的,将来的使用方式将是用数组名,也就是用指针方式去操作其中的每个bit,请参考__set_bit(EV_REP, input->evbit)的实现
+ unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//bitmap,每一bit代表一个事件类型,对应的bit为1表示该input设备支持该事件类型
+//evbit不同于以下的这些bitmap,evbit中的每个bit代表一个事件类型,而以下的每个bitmap代表某个事件类型所对应的所有的扫描码scancode
+//如:keybit中的每个bit表示一个按键的扫描码,bit[0]对应扫描码为0的按键,bit[255]对应扫描码为255的按键,等等。
+ unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//bitmap,每一bit代表一个按键,对应的bit为1表示该input设备支持该按键
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
- unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
+ unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];//bitmap,每一bit代表一个绝对轴。
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
@@ -161,7 +163,9 @@ struct input_dev {
struct input_mt *mt;
struct input_absinfo *absinfo;
-
+//note:the name of the array will be used as a pointer!
+//这几个bitmap用于记录设备扫描码的相关状态,如key中记录的是每个按键的键值(按下1,抬起0),input子系统会通过该bitmap记录每次事件中
+//上报的对应按键的键值,所以,该bitmap中的对应bit代表的是上次事件上报中对应按键的键值。
unsigned long key[BITS_TO_LONGS(KEY_CNT)];
unsigned long led[BITS_TO_LONGS(LED_CNT)];
unsigned long snd[BITS_TO_LONGS(SND_CNT)];
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index eabc56d..5a9b67a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -51,6 +51,7 @@
#define round_down(x, y) ((x) & ~__round_mask(x, y))
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+//note:整除,向上取整。
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define DIV_ROUND_UP_ULL(ll,d) \
({ unsigned long long _tmp = (ll)+(d)-1; do_div(_tmp, d); _tmp; })
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index cd80183..d3452b0 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -24,6 +24,7 @@ static inline void clear_bit(int nr, volatile unsigned long *addr)
static inline int test_bit(int nr, const volatile unsigned long *addr)
{
+//note:
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
/* end of stubs */
input work flow
最新推荐文章于 2024-06-28 22:46:19 发布