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之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Linux命令之firewalld的用法

《Linux命令之firewalld的用法》:本文主要介绍Linux命令之firewalld的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux命令之firewalld1、程序包2、启动firewalld3、配置文件4、firewalld规则定义的九大

Linux之计划任务和调度命令at/cron详解

《Linux之计划任务和调度命令at/cron详解》:本文主要介绍Linux之计划任务和调度命令at/cron的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux计划任务和调度命令at/cron一、计划任务二、命令{at}介绍三、命令语法及功能 :at

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro