Linux Device和Driver注册过程中的Probe时机

2024-02-14 18:20

本文主要是介绍Linux Device和Driver注册过程中的Probe时机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载本文解释linux下设备和驱动的不同注册顺序时设备probe的时机;增加两个case以解决PCI/USB等可热插拔设备不同插入过程的probe时机的疑问。

Linux 2.6的设备驱动模型中,所有的device都是通过Bus相连。device_register() / driver_register()执行时通过枚举BUS上的Driver/Device来实现绑定,本文详解这一过程。这是整个LINUX设备驱动的基础,PLATFORM设备,I2C上的设备等诸设备的注册最终也是调用本文讲述的注册函数来实现的。

Linux Device的注册最终都是通过device_register()实现,Driver的注册最终都是通过driver_register()实现。下图对照说明了Device和Driver的注册过程。

 

上面的图解一目了然,详细过程不再赘述。注意以下几点说明:

  • BUS的p->drivers_autoprobe;1默认是true。
  • bus_for_each_drv()是对BUS上所有的Driver都进行__device_attach()操作;同样的,bus_for_each_dev()是对BUS上所有的Device都进行__driver_attach()操作。
  • BUS上实现的.match()函数,定义了Device和Driver绑定时的规则。比如Platform实现的就是先比较id_table,然后比较name的规则。如果BUS的match()函数没实现,认为BUS上的所有的Device和Driver都是match的,具体后续过程要看probe()的实现了。
  • Probe的规则是:如果BUS上实现了probe就用BUS的probe;否则才会用driver的probe。

Device一般是先于Driver注册,但也不全是这样的顺序。

Linux的Device和Driver的注册过程分别枚举挂在该BUS上所有的Driver和Device实现了这种时序无关性。

[增加两个例子以解惑]

1 一个设备A已经attach驱动,不管两个注册的顺序如何,完成这一步,说明driver已经加载;同类设备B再次hot pluggin加入,则device_attach仅为设备B与驱动attach上,不会重做设备A的attach;

2 一个设备A注册,但是没有找到驱动,用户也不加载驱动;同类设备B hot pluggin,这时用户加载驱动,驱动注册,driver_attach,针对总线上的每个设备扫描,此时匹配的设备肯定没有加载驱动(如果没有一个设备对应同层次两个驱动的情况),则对设备A和B都attach该driver;

3 如果一个设备可以对应同层次两个驱动,是否允许,什么策略?需要时研究代码。

[附really_probe的代码]

250static int really_probe(struct device *dev, struct device_driver *drv)
251{
252	int ret = 0;
253
254	atomic_inc(&probe_count);
255	pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
256		 drv->bus->name, __func__, drv->name, dev_name(dev));
257	WARN_ON(!list_empty(&dev->devres_head));
258
259	dev->driver = drv; // 已经bus->match上, 所以可以将该device和driver关联起来
260	if (driver_sysfs_add(dev)) {
261		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
262			__func__, dev_name(dev));
263		goto probe_failed;
264	}
265
266	if (dev->bus->probe) {  // 调用bus->probe, 由bus->probe调用'具体'dev_drv->probe
267		ret = dev->bus->probe(dev);
268		if (ret)
269			goto probe_failed;
270	} else if (drv->probe) { // 使用'顶层'驱动device_driver的probe
271		ret = drv->probe(dev);
272		if (ret)
273			goto probe_failed;
274	}
275
276	driver_bound(dev);		// 设备与驱动已经关联好了
277	ret = 1;
278	pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
279		 drv->bus->name, __func__, dev_name(dev), drv->name);
280	goto done;
281
282probe_failed:
283	devres_release_all(dev);
284	driver_sysfs_remove(dev);
285	dev->driver = NULL;
286
287	if (ret == -EPROBE_DEFER) {
288		/* Driver requested deferred probing */
289		dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
290		driver_deferred_probe_add(dev);
291	} else if (ret != -ENODEV && ret != -ENXIO) {
292		/* driver matched but the probe failed */
293		printk(KERN_WARNING
294		       "%s: probe of %s failed with error %d\n",
295		       drv->name, dev_name(dev), ret);
296	} else {
297		pr_debug("%s: probe of %s rejects match %d\n",
298		       drv->name, dev_name(dev), ret);
299	}
300	/*
301	 * Ignore errors returned by ->probe so that the next driver can try
302	 * its luck.
303	 */
304	ret = 0;
305done:
306	atomic_dec(&probe_count);
307	wake_up(&probe_waitqueue);
308	return ret;
309}


 

这篇关于Linux Device和Driver注册过程中的Probe时机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/709234

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

oracle 11g导入\导出(expdp impdp)之导入过程

《oracle11g导入导出(expdpimpdp)之导入过程》导出需使用SEC.DMP格式,无分号;建立expdir目录(E:/exp)并确保存在;导入在cmd下执行,需sys用户权限;若需修... 目录准备文件导入(impdp)1、建立directory2、导入语句 3、更改密码总结上一个环节,我们讲了

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

Java Kafka消费者实现过程

《JavaKafka消费者实现过程》Kafka消费者通过KafkaConsumer类实现,核心机制包括偏移量管理、消费者组协调、批量拉取消息及多线程处理,手动提交offset确保数据可靠性,自动提交... 目录基础KafkaConsumer类分析关键代码与核心算法2.1 订阅与分区分配2.2 拉取消息2.3

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet