-
static struct pci_driver hamachi_driver = {
-
.name = DRV_NAME,
-
.id_table = hamachi_pci_tbl,
-
.probe = hamachi_init_one,
-
.remove = __devexit_p(hamachi_remove_one),
-
};
-
-
static int __init hamachi_init (void)
-
{
-
-
#ifdef MODULE
-
printk(version);
-
#endif
-
return pci_register_driver(&hamachi_driver);
-
}
-
-
static void __exit hamachi_exit (void)
-
{
-
pci_unregister_driver(&hamachi_driver);
-
}
-
-
-
module_init(hamachi_init);
-
module_exit(hamachi_exit);
-
static struct pci_driver hamachi_driver = {
-
.name = DRV_NAME,
-
.id_table = hamachi_pci_tbl,
-
.probe = hamachi_init_one,
-
.remove = __devexit_p(hamachi_remove_one),
-
};
-
-
static int __init hamachi_init (void)
-
{
-
-
#ifdef MODULE
-
printk(version);
-
#endif
-
return pci_register_driver(&hamachi_driver);
-
}
-
-
static void __exit hamachi_exit (void)
-
{
-
pci_unregister_driver(&hamachi_driver);
-
}
-
-
-
module_init(hamachi_init);
-
module_exit(hamachi_exit);
首先,实现了一个pci_driver结构体,名为hamachi_driver,
在hamachi_init函数中,直接调用pci_register_driver,追踪该函数:
-
-
-
-
#define pci_register_driver(driver) \
-
__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
-
-
-
-
#define pci_register_driver(driver) \
-
__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
发现pci_register_driver实际上是一个macro,使用宏的目的是扩展参数,实际调用的是__pci_register_driver,继续追踪:
-
-
-
-
-
-
-
-
-
-
-
-
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
-
const char *mod_name)
-
{
-
int error;
-
-
-
drv->driver.name = drv->name;
-
drv->driver.bus = &pci_bus_type;
-
drv->driver.owner = owner;
-
drv->driver.mod_name = mod_name;
-
-
if (drv->pm)
-
drv->driver.pm = &drv->pm->base;
-
-
spin_lock_init(&drv->dynids.lock);
-
INIT_LIST_HEAD(&drv->dynids.list);
-
-
-
error = driver_register(&drv->driver);
-
if (error)
-
return error;
-
-
error = pci_create_newid_file(drv);
-
if (error)
-
driver_unregister(&drv->driver);
-
-
return error;
-
-
-
-
-
-
-
-
-
-
-
-
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
-
const char *mod_name)
-
{
-
int error;
-
-
-
drv->driver.name = drv->name;
-
drv->driver.bus = &pci_bus_type;
-
drv->driver.owner = owner;
-
drv->driver.mod_name = mod_name;
-
-
if (drv->pm)
-
drv->driver.pm = &drv->pm->base;
-
-
spin_lock_init(&drv->dynids.lock);
-
INIT_LIST_HEAD(&drv->dynids.list);
-
-
-
error = driver_register(&drv->driver);
-
if (error)
-
return error;
-
-
error = pci_create_newid_file(drv);
-
if (error)
-
driver_unregister(&drv->driver);
-
-
return error;
}
前面填充了drv->driver结构,然后调用spin_lock_init来初始化自旋锁,调用INIT_LIST_HEAD来初始化一个双向链表,核心是调用了driver_register函数,继续追踪:
-
int driver_register(struct device_driver *drv)
-
{
-
int ret;
-
struct device_driver *other;
-
-
if ((drv->bus->probe && drv->probe) ||
-
(drv->bus->remove && drv->remove) ||
-
(drv->bus->shutdown && drv->shutdown))
-
printk(KERN_WARNING "Driver '%s' needs updating - please use "
-
"bus_type methods\n", drv->name);
-
-
other = driver_find(drv->name, drv->bus);
-
if (other) {
-
put_driver(other);
-
printk(KERN_ERR "Error: Driver '%s' is already registered, "
-
"aborting...\n", drv->name);
-
return -EBUSY;
-
}
-
-
ret = bus_add_driver(drv);
-
if (ret)
-
return ret;
-
ret = driver_add_groups(drv, drv->groups);
-
if (ret)
-
bus_remove_driver(drv);
-
return ret;
-
}
-
int driver_register(struct device_driver *drv)
-
{
-
int ret;
-
struct device_driver *other;
-
-
if ((drv->bus->probe && drv->probe) ||
-
(drv->bus->remove && drv->remove) ||
-
(drv->bus->shutdown && drv->shutdown))
-
printk(KERN_WARNING "Driver '%s' needs updating - please use "
-
"bus_type methods\n", drv->name);
-
-
other = driver_find(drv->name, drv->bus);
-
if (other) {
-
put_driver(other);
-
printk(KERN_ERR "Error: Driver '%s' is already registered, "
-
"aborting...\n", drv->name);
-
return -EBUSY;
-
}
-
-
ret = bus_add_driver(drv);
-
if (ret)
-
return ret;
-
ret = driver_add_groups(drv, drv->groups);
-
if (ret)
-
bus_remove_driver(drv);
-
return ret;
-
}
该函数首先做了一些检查,实际上是重点是调用了bus_add_drvier函数,进入该函数:
-
-
-
-
-
int bus_add_driver(struct device_driver *drv)
-
{
-
struct bus_type *bus;
-
struct driver_private *priv;
-
int error = 0;
-
-
bus = bus_get(drv->bus);
-
if (!bus)
-
return -EINVAL;
-
-
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
-
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-
if (!priv) {
-
error = -ENOMEM;
-
goto out_put_bus;
-
}
-
klist_init(&priv->klist_devices, NULL, NULL);
-
priv->driver = drv;
-
drv->p = priv;
-
priv->kobj.kset = bus->p->drivers_kset;
-
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
-
"%s", drv->name);
-
if (error)
-
goto out_unregister;
-
-
if (drv->bus->p->drivers_autoprobe) {
-
error = driver_attach(drv);
-
if (error)
-
goto out_unregister;
-
}
-
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
-
module_add_driver(drv->owner, drv);
-
-
error = driver_create_file(drv, &driver_attr_uevent);
-
if (error) {
-
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
-
__func__, drv->name);
-
}
-
error = driver_add_attrs(bus, drv);
-
if (error) {
-
-
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
-
__func__, drv->name);
-
}
-
error = add_bind_files(drv);
-
if (error) {
-
-
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
-
__func__, drv->name);
-
}
-
-
kobject_uevent(&priv->kobj, KOBJ_ADD);
-
return error;
-
out_unregister:
-
kobject_put(&priv->kobj);
-
out_put_bus:
-
bus_put(bus);
-
return error;
-
}
-
-
-
-
-
int bus_add_driver(struct device_driver *drv)
-
{
-
struct bus_type *bus;
-
struct driver_private *priv;
-
int error = 0;
-
-
bus = bus_get(drv->bus);
-
if (!bus)
-
return -EINVAL;
-
-
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
-
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-
if (!priv) {
-
error = -ENOMEM;
-
goto out_put_bus;
-
}
-
klist_init(&priv->klist_devices, NULL, NULL);
-
priv->driver = drv;
-
drv->p = priv;
-
priv->kobj.kset = bus->p->drivers_kset;
-
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
-
"%s", drv->name);
-
if (error)
-
goto out_unregister;
-
-
if (drv->bus->p->drivers_autoprobe) {
-
error = driver_attach(drv);
-
if (error)
-
goto out_unregister;
-
}
-
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
-
module_add_driver(drv->owner, drv);
-
-
error = driver_create_file(drv, &driver_attr_uevent);
-
if (error) {
-
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
-
__func__, drv->name);
-
}
-
error = driver_add_attrs(bus, drv);
-
if (error) {
-
-
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
-
__func__, drv->name);
-
}
-
error = add_bind_files(drv);
-
if (error) {
-
-
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
-
__func__, drv->name);
-
}
-
-
kobject_uevent(&priv->kobj, KOBJ_ADD);
-
return error;
-
out_unregister:
-
kobject_put(&priv->kobj);
-
out_put_bus:
-
bus_put(bus);
-
return error;
-
}
该函数前面还是一些分配资源和初始化的工作,直到driver_attach函数,该函数的作用是遍历总线上所有的设备,将驱动与设备绑定:
-
int driver_attach(struct device_driver *drv)
-
{
-
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
-
}
-
int driver_attach(struct device_driver *drv)
-
{
-
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
-
}
进入bus_for_each_dev函数中,
-
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);
-
klist_iter_exit(&i);
-
return error;
-
}
-
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);
-
klist_iter_exit(&i);
-
return error;
-
}
该函数的重点是调用了fn这个函数指针实现回调,回调函数为__driver_attach,进入该函数:
-
static int __driver_attach(struct device *dev, void *data)
-
{
-
struct device_driver *drv = data;
-
-
-
-
-
-
-
-
-
-
-
-
if (dev->parent)
-
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;
-
}
-
static int __driver_attach(struct device *dev, void *data)
-
{
-
struct device_driver *drv = data;
-
-
-
-
-
-
-
-
-
-
-
-
if (dev->parent)
-
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;
-
}
重点进入driver_probe_device函数,
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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;
-
}
该函数的作用是将设备和驱动程序绑定,首先调用match函数指针,检查设备和驱动是否匹配,然后调用了really_probe,真正的probe:
-
static int really_probe(struct device *dev, struct device_driver *drv)
-
{
-
int ret = 0;
-
-
atomic_inc(&probe_count);
-
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
-
drv->bus->name, __func__, drv->name, dev->bus_id);
-
WARN_ON(!list_empty(&dev->devres_head));
-
-
dev->driver = drv;
-
if (driver_sysfs_add(dev)) {
-
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
-
__func__, dev->bus_id);
-
goto probe_failed;
-
}
-
-
if (dev->bus->probe) {
-
ret = dev->bus->probe(dev);
-
if (ret)
-
goto probe_failed;
-
} 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->bus_id, drv->name);
-
goto done;
-
-
probe_failed:
-
devres_release_all(dev);
-
driver_sysfs_remove(dev);
-
dev->driver = NULL;
-
-
if (ret != -ENODEV && ret != -ENXIO) {
-
-
printk(KERN_WARNING
-
"%s: probe of %s failed with error %d\n",
-
drv->name, dev->bus_id, ret);
-
}
-
-
-
-
-
ret = 0;
-
done:
-
atomic_dec(&probe_count);
-
wake_up(&probe_waitqueue);
-
return ret;
-
}
-
static int really_probe(struct device *dev, struct device_driver *drv)
-
{
-
int ret = 0;
-
-
atomic_inc(&probe_count);
-
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
-
drv->bus->name, __func__, drv->name, dev->bus_id);
-
WARN_ON(!list_empty(&dev->devres_head));
-
-
dev->driver = drv;
-
if (driver_sysfs_add(dev)) {
-
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
-
__func__, dev->bus_id);
-
goto probe_failed;
-
}
-
-
if (dev->bus->probe) {
-
ret = dev->bus->probe(dev);
-
if (ret)
-
goto probe_failed;
-
} 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->bus_id, drv->name);
-
goto done;
-
-
probe_failed:
-
devres_release_all(dev);
-
driver_sysfs_remove(dev);
-
dev->driver = NULL;
-
-
if (ret != -ENODEV && ret != -ENXIO) {
-
-
printk(KERN_WARNING
-
"%s: probe of %s failed with error %d\n",
-
drv->name, dev->bus_id, ret);
-
}
-
-
-
-
-
ret = 0;
-
done:
-
atomic_dec(&probe_count);
-
wake_up(&probe_waitqueue);
-
return ret;
-
}
直到这里才利用drv->probe指针,该指针指向的是:
-
struct device_driver {
-
const char *name;
-
struct bus_type *bus;
-
-
struct module *owner;
-
const char *mod_name;
-
-
int (*probe) (struct device *dev);
-
int (*remove) (struct device *dev);
-
void (*shutdown) (struct device *dev);
-
int (*suspend) (struct device *dev, pm_message_t state);
-
int (*resume) (struct device *dev);
-
struct attribute_group **groups;
-
-
struct pm_ops *pm;
-
-
struct driver_private *p;
-
};
-
struct device_driver {
-
const char *name;
-
struct bus_type *bus;
-
-
struct module *owner;
-
const char *mod_name;
-
-
int (*probe) (struct device *dev);
-
int (*remove) (struct device *dev);
-
void (*shutdown) (struct device *dev);
-
int (*suspend) (struct device *dev, pm_message_t state);
-
int (*resume) (struct device *dev);
-
struct attribute_group **groups;
-
-
struct pm_ops *pm;
-
-
struct driver_private *p;
-
};
中的probe函数指针,该结构体是需要你在register之前实现的,直到此时才
真正的调用了hamachi.c中你实现的probe函数。