2010年(15)
分类: LINUX
2010-01-22 15:54:33
Eric Fang 2010-01-22
--------------------------------------------------------------
本站分析linux内核源码,版本号为2.6.32.3
转载请注明出处:http://ericfang.cublog.cn/
--------------------------------------------------------------
接上一篇文章:
我们在分析platform总线时已经知道platform_driver_probe(&i8042_driver, i8042_probe)函数注册驱动并进行一次设备的匹配,而以后注册设备时时不会再匹配驱动的,换句话说我们确信系统不会再添加同类型的设备,这里我们要看一下i8042_probe函数做了什么事。
static int __init i8042_probe(struct platform_device *dev)
{
int error;
error = i8042_controller_selftest();
if (error)
return error;
error = i8042_controller_init();
if (error)
return error;
#ifdef CONFIG_X86
if (i8042_dritek)
i8042_dritek_enable();
#endif
if (!i8042_noaux) {
error = i8042_setup_aux();
if (error && error != -ENODEV && error != -EBUSY)
goto out_fail;
}
if (!i8042_nokbd) {
error = i8042_setup_kbd();
if (error)
goto out_fail;
}
/*
* Ok, everything is ready, let's register all serio ports
*/
i8042_register_ports();
return 0;
out_fail:
i8042_free_aux_ports(); /* in case KBD failed but AUX not */
i8042_free_irqs();
i8042_controller_reset();
return error;
}
一眼扫过去一共调用了这几个函数:
i8042_controller_selftest();
i8042_controller_init();
i8042_dritek_enable();
i8042_setup_aux();
i8042_setup_kbd();
i8042_register_ports();
逐个进行分析:
static int i8042_controller_selftest(void)
{
unsigned char param;
int i = 0;
if (!i8042_reset)
return 0;
在前面已经知道了i8042_reset被设为1。
/*
* We try this 5 times; on some really fragile systems this does not
* take the first time...
*/
do {
if (i8042_command(¶m, I8042_CMD_CTL_TEST)) {
printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
return -ENODEV;
}
if (param == I8042_RET_CTL_TEST)
return 0;
printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
param, I8042_RET_CTL_TEST);
msleep(50);
} while (i++ < 5);
#ifdef CONFIG_X86
/*
* On x86, we don't fail entire i8042 initialization if controller
* reset fails in hopes that keyboard port will still be functional
* and user will still get a working keyboard. This is especially
* important on netbooks. On other arches we trust hardware more.
*/
printk(KERN_INFO
"i8042: giving up on controller selftest, continuing anyway...\n");
return 0;
#else
return -EIO;
#endif
}
该函数连续5次向i8042发送自检命令,每次间隔50毫秒,如果每次i8042都反馈自测通过信息就成功跳出。
我们来看一下这个发送命令的函数:
int i8042_command(unsigned char *param, int command)
{
<