Chinaunix首页 | 论坛 | 博客
  • 博客访问: 119641
  • 博文数量: 15
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 530
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-09 13:11
文章分类
文章存档

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)

{

<

阅读(3263) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~