// 以PCI总线驱动模型, XDMA设备源码, 2.6.26内核源码为例
// 网上通用解释如下:
static const struct pci_device_id cpi_ids[] = {
{PCI_DEVICE(0x10ee, 0x903f), },
{PCI_DEVICE(0x10ee, 0x9038), },
……
{0,},
};
static struct pci_driver pci_driver = {
.name = DRV_MODULE_NAME,
.id_table = pci_ids,
.probe = probe_one,
.remove = remove_one,
.err_handler = &xdma_err_handler,
};
// 初始化入口函数
static int __init xdma_mod_init(void)
{
int rv;
extern unsigned int desc_blen_max;
extern unsigned int sgdma_timeout;
pr_info("%s", version);
if(desc_blen_max > XDMA_DESC_BLEN_MAX)
desc_blen_max = XDMA_DESC_BLEN_MAX;
pr_info("desc_blen_max: 0x%x/%u, sgdma_timeout: %u sec.\n",
desc_blen_max, desc_blen_max, sgdma_timeout);
rv = xdma_cdev_init();
if(rv < 0)
return rv;
return pci_register_driver(&pci_driver);
}
static inline int __must_check pci_register_driver(struct pci_driver *driver)
{
return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
}
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
const char *mod_name)
{
int error;
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type;
drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
……
error = driver_register(&drv->driver);
……
}
int driver_register(struct device_driver *drv)
{
……
ret = bus_add_driver(drv);
……
}
int bus_add_driver(struct device_driver *drv)
{
……
driver_attach(drv);
……
}
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
int bus_for_each_dev(struct bus_type *bus, struct device *start,
void *data, int (*fn)(struct device *, void *))
{
struct klist_iter i;
struct device *dev;
int error = 0;
if (!bus)
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data); //这里调用__driver_attach
klist_iter_exit(&i);
return error;
}
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0;
}
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("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev->bus_id, drv->name);
ret = really_probe(dev, drv);
done:
return ret;
}
static int really_probe(struct device *dev, struct device_driver *drv)
{
……
dev->driver = drv; //将device_driver结构赋值到device中
……
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev); //此处调用驱动中的probe函数
if (ret)
goto probe_failed;
}
……
}
-
解释到这里就结束了,可我注册的驱动函数为pci_driver.probe,
-
此处调用的是pci_driver.driver.probe
-
这两个貌似并没有联系,且参数也不一样,怎么解释?
-
查看源码之后解释如下:
-
在really_probe()函数中, 先判断dev->bus->probe是否存在,
-
实际PCI、USB、IIC等标准总线,这个函数是存在的,
-
所以此处并不会执行下面的else语句,
-
dev->bus在__pci_register_driver函数中赋值为&pci_bus_type.
// pci_bus_type结构如下:
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.uevent = pci_uevent,
.probe = pci_device_probe,
.remove = pci_device_remove,
.suspend = pci_device_suspend,
.suspend_late = pci_device_suspend_late,
.resume_early = pci_device_resume_early,
.resume = pci_device_resume,
.shutdown = pci_device_shutdown,
.dev_attrs = pci_dev_attrs,
};
// 所以在really_probe中实际调用的是pci_device_probe函数。
static int pci_device_probe(struct device * dev)
{
int error = 0;
struct pci_driver *drv;
struct pci_dev *pci_dev;
drv = to_pci_driver(dev->driver); //通过device结构得到pci_driver
pci_dev = to_pci_dev(dev);
pci_dev_get(pci_dev);
error = __pci_device_probe(drv, pci_dev);
if (error)
pci_dev_put(pci_dev);
return error;
}
static int
__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
const struct pci_device_id *id;
int error = 0;
if (!pci_dev->driver && drv->probe) {
error = -ENODEV;
id = pci_match_device(drv, pci_dev);
if (id)
error = pci_call_probe(drv, pci_dev, id);
if (error >= 0) {
pci_dev->driver = drv;
error = 0;
}
}
return error;
}
static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
const struct pci_device_id *id)
{
int error;
……
error = drv->probe(dev, id); //此处调用驱动中的probe函数
……
return error;
}