// 以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;

}