Chinaunix首页 | 论坛 | 博客
  • 博客访问: 51286
  • 博文数量: 19
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-27 15:16
个人简介

长期潜藏于CSDN http://blog.csdn.net/npjocj

文章分类
文章存档

2013年(1)

2012年(18)

我的朋友

分类:

2012-11-21 14:59:19

接着上一节分析,上一节讲到,把device_add(&pdev->dev);//把该设备注册到设备驱动模型中,接着该函数继续分析,看下设备驱动是怎么回事,设备是如何与驱动匹配绑定的。
int device_add(struct device *dev)
{
 if (!dev->p) {//如果dev的私有数据为空,则继续相应的初始化
  error = device_private_init(dev);
 }
 error = bus_add_device(dev);//把设备增加到设备依附的总线bus的devices链表上
 bus_probe_device(dev);//设备探测总线上的驱动
 }
void bus_probe_device(struct device *dev)
{
 if (bus && bus->p->drivers_autoprobe) {//如果bus不为空,并且是自动探测,则device_attach.
  ret = device_attach(dev);
 }
}
int device_attach(struct device *dev)
{
 int ret = 0;
 device_lock(dev);
 if (dev->driver) {//如果该device的driver不为空的话,就把该dev和该driver绑定,也就是把dev加到driver的devices链表
 } else {
   ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);//否则,用改dev去探测bus上的每一个驱动
 }
}
下面是探测的过程,针对dev和从总线上取到的每一个驱动做匹配,匹配的过程如下:
static int __device_attach(struct device_driver *drv, void *data)
{
 struct device *dev = data;
 if (!driver_match_device(drv, dev))//调用总线的match函数,去匹配该dev和driver
  return 0;
 return driver_probe_device(drv, dev);//探测成功,试图绑定device和driver
}
下面就看下,总线的match函数
static int platform_match(struct device *dev, struct device_driver *drv)
{
 struct platform_device *pdev = to_platform_device(dev);
 struct platform_driver *pdrv = to_platform_driver(drv);
 /* match against the id table first */
 if (pdrv->id_table)//如果pdrv->id_table不为空,则用pdev的名字和该id_table列表中的名字匹配
  return platform_match_id(pdrv->id_table, pdev) != NULL;
 /* fall-back to driver name match */
 return (strcmp(pdev->name, drv->name) == 0);//如果pdrv->id_table为空,则用pdev的名字和该drv的名字比较,看是否匹配
}
下面接着分析driver_probe_device(drv, dev);函数。
该函数调用int driver_probe_device(struct device_driver *drv, struct device *dev)
{
 ret = really_probe(dev, drv);
}
really_probe()函数如下
static int really_probe(struct device *dev, struct device_driver *drv)
{
 dev->driver = drv;//把drv赋值给dev的driver
 if (dev->bus->probe) {//如果总线的probe函数存在,则先调用总线的probe函数
  ret = dev->bus->probe(dev);
 } else if (drv->probe) {//否则调用驱动的probe函数
  ret = drv->probe(dev);
 }
 driver_bound(dev);//如果都探测通过,就把dev加入到该driver的device链表中
 ret = 1;
}
到此平台设备已经加入到总线上,并且找到了自己的驱动。
阅读(719) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~