教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 政务民生 >

linux设备模型深探(10)

来源:网络收集 时间:2026-08-05
导读: 代码如下: void bus_attach_device(struct device *dev) { struct bus_type *bus = dev->bus; int ret = 0; if (bus) { dev->is_registered = 1; if (bus->p->drivers_autoprobe) ret = device_attach(dev); WARN_

代码如下:

void bus_attach_device(struct device *dev) {

struct bus_type *bus = dev->bus;

int ret = 0;

if (bus) {

dev->is_registered = 1;

if (bus->p->drivers_autoprobe)

ret = device_attach(dev);

WARN_ON(ret < 0);

if (ret >= 0)

klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);

else

dev->is_registered = 0;

} }

从上面的代码我们可以看出。只有在bus->p->drivers_autoprobe为1的情况下,才会去自己匹配。这也就是bus目录下的drivers_probe 文件的作用.然后,将设备挂到总线的设备链表。

Device_attach()代码如下:

int device_attach(struct device *dev) {

int ret = 0;

down(&dev->sem);

if (dev->driver) {

ret = device_bind_driver(dev);

if (ret == 0)

ret = 1;

else {

dev->driver = NULL;

ret = 0;

}

} else {

ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);

}

up(&dev->sem);

return ret; }

对于设备自己已经指定驱动的情况,只需要将其直接和驱动绑定即可。如果没有指定驱动。就匹配总线之上的驱动。这是在bus_for_each_drv(dev->bus, NULL, dev, __device_attach);完成的。代码如下:

int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,

void *data, int (*fn)(struct device_driver *, void *)) {

struct klist_iter i;

struct device_driver *drv;

int error = 0;

if (!bus)

return -EINVAL;

klist_iter_init_node(&bus->p->klist_drivers, &i,

start ? &start->p->knode_bus : NULL);

while ((drv = next_driver(&i)) && !error)

error = fn(drv, data);

klist_iter_exit(&i);

return error; }

很明显,这个函数就是遍历总线之上的驱动。每遍历一个驱动就调用一次回调函数进行判断。如果回调函数返回不为0。就说明匹配已经成功了。不需要再匹配剩余的。退出。在这里调用的回调函数是__device_attach().在这里。完全了设备与驱动匹配的最核心的动作。代码如下:

static int __device_attach(struct device_driver *drv, void *data) {

struct device *dev = data;

return driver_probe_device(drv, dev); }

转到driver_probe_device():

int driver_probe_device(struct device_driver *drv, struct device *dev)

{

int ret = 0;

if (!device_is_registered(dev))

return -ENODEV;

if (drv->bus->match && !drv->bus->match(dev, drv))

goto done;

pr_debug(\

drv->bus->name, __FUNCTION__, dev->bus_id, drv->name);

ret = really_probe(dev, drv);

done:

return ret; }

如果设备没有注册到总线之上。即dev->is_registered不为1. 就直接返回。

然后,再调用总线的match()函数进行匹配。如果match()函数返回0.说明匹配失败。那退出此函数。如果match函数返回1.说明初步的检查已经通过了。可以进入really_probe()再进行细致的检查。如果匹配成功,这个函数会返回1.此函数比较长而且比较重要,分段列出代码:

static int really_probe(struct device *dev, struct device_driver *drv) {

int ret = 0;

atomic_inc(&probe_count);

pr_debug(\

drv->bus->name, __FUNCTION__, drv->name, dev->bus_id);

WARN_ON(!list_empty(&dev->devres_head));

dev->driver = drv;

if (driver_sysfs_add(dev)) {

printk(KERN_ERR \

__FUNCTION__, dev->bus_id);

goto probe_failed;

}

先假设驱动和设备是匹配的。为设备结构设置驱动成员。使其指向匹配的驱动。然后再调用driver_sysfs_add()建立几个符号链接。这几个链接分别为:

1:在驱动目录下建立一个到设备的同名链接

2:在设备目录下建立一个名为driver。到驱动的链接

if (dev->bus->probe) {

ret = dev->bus->probe(dev);

if (ret)

goto probe_failed;

} else if (drv->probe) {

…… 此处隐藏:496字,全部文档内容请下载后查看。喜欢就下载吧 ……
linux设备模型深探(10).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/448127.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)