Linux輸入子系統分析 (1) -- 輸入子系統初始化
[linux-3.0 http://lxr.linux.no/#linux+v3.0]
輸入子系統:
2173subsys_initcall(input_init);
其原始碼如下:
2133static const struct file_operations input_fops = {
2134 .owner = THIS_MODULE,
2135 .open = input_open_file,
2136 .llseek = noop_llseek,
2137};
2138
2139static int __init input_init(void)
2140{
2141 int err;
2142
2143 err = class_register(&input_class);
2144 if (err) {
2145 pr_err("unable to register input_dev class\n");
2146 return err;
2147 }
2148
2149 err = input_proc_init();
2150 if (err)
2151 goto fail1;
2152
2153 err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
2154 if (err) {
2155 pr_err("unable to register char major %d", INPUT_MAJOR);
2156 goto fail2;
2157 }
2158
2159 return 0;
2160
2161 fail2: input_proc_exit();
2162 fail1: class_unregister(&input_class);
2163 return err;
2164}
input_init的主要作用:
2143行,建立“input"類,即在/sys/classs/下面建一個input的子目錄。
input_class的定義如下:
1632struct class input_class = {
1633 .name = "input",
1634 .devnode = input_devnode,
1635};
1636EXPORT_SYMBOL_GPL(input_class);
2149行,建立proc檔案系統中建立input目錄,存放於/proc/bus/下面(/proc/bus/input),而後在此目錄下建立devices和handlers檔案
通過讀取devices,可以知道系統中的輸入裝置。
-------------------------------------------------------------------------------------------
# cat /proc/bus/input/devices
I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="AT42QT1070 QTouch Sensor"
P: Phys=
S: Sysfs=/devices/platform/i2c-gpio.0/i2c-0/0-001b/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=8fc
I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="Atmel maXTouch Touchscreen"
P: Phys=
S: Sysfs=/devices/platform/i2c-gpio.0/i2c-0/0-004a/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: PROP=0
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=610000 1000003
-------------------------------------------------------------------------------------------
通過讀取handlers,可以知道系統中註冊了那些處理函數。
-------------------------------------------------------------------------------------------
# cat /proc/bus/input/handlers
N: Number=0 Name=kbd
N: Number=1 Name=mousedev Minor=32
N: Number=2 Name=evdev Minor=64
-------------------------------------------------------------------------------------------
2153行,註冊一個字元類型裝置及其操作函數。
2159行,如果上面操作沒有錯誤,完美退出。
Linux輸入子系統分析 (2) -- evdev handler初始化
[Linux 3.0 http://lxr.linux.no/#linux+v3.0]
前面介紹了輸入子系統的初始化,前面提及到/proc/bus/input/handlers,當讀取此檔案時,其中有一行是
N: Number=2 Name=evdev Minor=64
這一行是如何來的呢。
下面來解開這個迷底,介紹handler ------ evdev的註冊過程
988static struct input_handler evdev_handler = {
989 .event = evdev_event,
990 .connect = evdev_connect,
991 .disconnect = evdev_disconnect,
992 .fops = &evdev_fops,
993 .minor = EVDEV_MINOR_BASE,
994 .name = "evdev",
995 .id_table = evdev_ids,
996};
997
998static int __init evdev_init(void)
999{
1000 return input_register_handler(&evdev_handler);
1001}
988 ~ 996行, 定義了一個evdev handler.
1000行,調用input_register_handler去註冊這個evdev handler
下面具體看看,input_register_handler是如果去註冊evdev這個hanlder的。
/**
* input_register_handler - register a new input handler
* @handler: handler to be registered
*
* This function registers a new input handler (interface) for input
* devices in the system and attaches it to all input devices that
* are compatible with the handler.
*/
1923int input_register_handler(struct input_handler *handler)
1924{
1925 struct input_dev *dev;
1926 int retval;
1927
1928 retval = mutex_lock_interruptible(&input_mutex);
1929 if (retval)
1930 return retval;
1931
1932 INIT_LIST_HEAD(&handler->h_list);
1933
1934 if (handler->fops != NULL) {
1935 if (input_table[handler->minor >> 5]) {
1936 retval = -EBUSY;
1937 goto out;
1938 }
1939 input_table[handler->minor >> 5] = handler;
1940 }
1941
1942 list_add_tail(&handler->node, &input_handler_list);
1943
1944 list_for_each_entry(dev, &input_dev_list, node)
1945 input_attach_handler(dev, handler);
1946
1947 input_wakeup_procfs_readers();
1948
1949 out:
1950 mutex_unlock(&input_mutex);
1951 return retval;
1952}
1953EXPORT_SYMBOL(input_register_handler);
1928行,此處加一個可被中斷的鎖。
1932行,初始化handler的h_list鏈表(h_list的定義:list of input handles associated with the handler)
1934 ~1940行,判斷此handler的操作函數是否為空白,非空,通過其minor值,判斷此handler是否已經存在(註冊過),如果否,將其加入input_table中。
input_table定義:static struct input_handler *input_table[8]; 說明在linux系統中,最多隻能有8個輸入handler。
1942行,將此handler加入到input_handler_list的鏈表中。其定義:static LIST_HEAD(input_handler_list); (lin38 in input.c)
1944行,掃描input_dev_list鏈表,看是否輸入裝置需要此handler的支援。 其定義:static LIST_HEAD(input_dev_list); (lin37 in input.c)
input_attach_handler(line 895, in input.c)--> input_match_device(line 854, in input.c) ,此過程沒有找到match的裝置, 返回NULL。
1947行,proc檔案系統操作。此處需要進一步研究。
1950行,釋放鎖並返回