Linux驱动 probe函数调用
来源:互联网 发布:阿里云服务器好吗 编辑:程序博客网 时间:2024/05/20 02:26
参考:
http://blog.chinaunix.net/space.php?uid=15887868&do=blog&id=2758294
http://www.cnblogs.com/hoys/archive/2011/04/01/2002299.html
1,driver_register把驱动注册到总线
/** * driver_register - register driver with bus * @drv: driver to register * We pass off most of the work to the bus_add_driver() call, * since most of the things we have to do deal with the bus * structures. */int driver_register(struct device_driver *drv){……………………if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown))ret = bus_add_driver(drv);//把drv驱动,注册到总线……………………}
2,驱动注册到总线的实现函数
/** * bus_add_driver - Add a driver to the bus. -----在总线上加入一个驱动 * @drv: driver. */int bus_add_driver(struct device_driver *drv){………………if (drv->bus->p->drivers_autoprobe) {error = driver_attach(drv); //驱动的匹配函数………………}3,driver_attach()
/** * driver_attach - try to bind driver to devices. * @drv: driver. * * Walk the list of devices that the bus has on it and try to * match the driver with each one. If driver_probe_device() * returns 0 and the @dev->driver is set, we've found a * compatible pair. */int driver_attach(struct device_driver *drv){return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//注意这里的__driver_attach}EXPORT_SYMBOL_GPL(driver_attach);上面真正起作用的是__driver_attach:
static int __driver_attach(struct device *dev, void *data){struct device_driver *drv = data;/* * Lock device and try to bind to it. We drop the error * here and always return 0, because we need to keep trying * to bind to devices and some drivers will return an error * simply if it didn't support the device. * * driver_probe_device() will spit a warning if there * is an error. */if (!driver_match_device(drv, dev))return 0;if (dev->parent)/* Needed for USB */device_lock(dev->parent);device_lock(dev);if (!dev->driver)driver_probe_device(drv, dev);//看下这个函数的实现过程device_unlock(dev);if (dev->parent)device_unlock(dev->parent);return 0;}int driver_probe_device(structdevice_driver *drv, struct device *dev){...//1.先是判断bus是否match:if (drv->bus->match && !drv->bus->match(dev, drv)) goto done;//2.再具体执行probe:ret = really_probe(dev, drv);...}4,really_probe是我们真正要找的函数
static int really_probe(struct device *dev, struct device_driver *drv){……………………//1.先是调用的驱动所属总线的probe函数:if (dev->bus->probe) {ret = dev->bus->probe(dev);if (ret)goto probe_failed;} //2.再调用的驱动中的probe函数:else if (drv->probe) {ret = drv->probe(dev);if (ret)goto probe_failed;}driver_bound(dev);ret = 1;pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name);//这个信息可以看到我们注册的总 驱动、设备和总线 信息goto done;………………}
5.drv->bus->match(dev, drv)
driver_probe_device(struct device_driver *drv, struct device *dev)会通过drv->bus->match()来匹配PCIE设备与相应的设备驱动。对于内核为2.6.27的bus驱动“pci_express”来说,是通过调用pcie_port_bus_match()实现驱动match的。
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv){struct pcie_device *pciedev;struct pcie_port_service_driver *driver;if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)return 0;pciedev = to_pcie_device(dev);driver = to_service_driver(drv);if ( (driver->id_table->vendor != PCI_ANY_ID && driver->id_table->vendor != pciedev->id.vendor) || (driver->id_table->device != PCI_ANY_ID &&driver->id_table->device != pciedev->id.device) || (driver->id_table->port_type != PCIE_ANY_PORT &&driver->id_table->port_type != pciedev->id.port_type) ||driver->id_table->service_type != pciedev->id.service_type )return 0; // driver与pciedev的id_table匹配成功,才match成功;return 1;}
// id_table的结构定义如下,match时只关注vendor,device,port_type,service_typestruct pcie_port_service_id {__u32 vendor, device;/* Vendor and device ID or PCI_ANY_ID*/__u32 subvendor, subdevice;/* Subsystem ID's or PCI_ANY_ID */__u32 class, class_mask;/* (class,subclass,prog-if) triplet */__u32 port_type, service_type;/* Port Entity */kernel_ulong_t driver_data;};
打印出的驱动设备信息如:
………………
[ 0.588087] bus: 'platform': really_probe: bound device power.0to driverpower //总线:platform 设备:power.0 驱动:power[ 0.661226] bus: 'platform': really_probe: bound device s3c24xx-pwm.0 to driver s3c24xx-pwm
[ 0.678552] bus: 'platform': really_probe: bound device s3c24xx-pwm.1 to driver s3c24xx-pwm
[ 0.695971] bus: 'platform': really_probe: bound device s3c24xx-pwm.2 to driver s3c24xx-pwm
[ 0.713389 bus: 'platform': really_probe: bound device s3c24xx-pwm.3 to driver
……………………
- Linux驱动 probe函数调用
- Linux驱动 probe函数调用
- Linux驱动probe函数调用
- linux驱动probe函数调用路程
- linux驱动中probe函数如何调用
- Linux驱动中,probe函数何时被调用
- 【整理】Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- 【整理】Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- linux驱动中probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- Linux驱动中,probe函数何时被调用
- 为什么很多人工作都不开心?
- 驱动之module_init/module_exit
- android 对话框
- 股份与期权的分配示例
- Servlet 3.0 新特性概述
- Linux驱动 probe函数调用
- 微软安全新闻聚焦-双周刊第二十七期
- USB枚举过程
- QT messageBox
- MySQL安装教程图解
- linux 下路由配置
- 详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名及手工脚本创建oracle数据库
- 怎样区分汽车脚垫和汽车地胶?
- RTMP中FLV流到标准h264、aac的转换