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脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

Linux系统中的firewall-offline-cmd详解(收藏版)

《Linux系统中的firewall-offline-cmd详解(收藏版)》firewall-offline-cmd是firewalld的一个命令行工具,专门设计用于在没有运行firewalld服务的... 目录主要用途基本语法选项1. 状态管理2. 区域管理3. 服务管理4. 端口管理5. ICMP 阻断

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

Linux使用scp进行远程目录文件复制的详细步骤和示例

《Linux使用scp进行远程目录文件复制的详细步骤和示例》在Linux系统中,scp(安全复制协议)是一个使用SSH(安全外壳协议)进行文件和目录安全传输的命令,它允许在远程主机之间复制文件和目录,... 目录1. 什么是scp?2. 语法3. 示例示例 1: 复制本地目录到远程主机示例 2: 复制远程主