pci总线驱动及pci设备驱动注册

一、PCI总线注册

1、pci总线注册对应构造函数

static int __init pci_driver_init(void)
{
    return bus_register(&pci_bus_type);
}

postcore_initcall(pci_driver_init);

#define postcore_initcall(fn)        __define_initcall("2",fn)

#define __define_initcall(level,fn) \
    static initcall_t __initcall_##fn __attribute_used__ \
    __attribute__((__section__(".initcall" level ".init"))) = fn

start_kernel  -->rest_init() -->kernel_init()  --> do_basic_setup()  -->do_initcalls()----》遍历.initcall" level ".init,执行.initcall" level ".init对应的fn,最终pci_driver_init被执行

2、执行注册

pci总线的ops结构体:

struct bus_type pci_bus_type = {
    .name        = "pci",
    .match        = pci_bus_match,
    .hotplug    = pci_hotplug,
    .suspend    = pci_device_suspend,
    .resume        = pci_device_resume,
    .dev_attrs    = pci_dev_attrs,
};

注册pci驱动
int bus_register(struct bus_type * bus)
{
    int retval;

    retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);       //设置pci_bus_type->subsys.kset.kobj->k_name为pci

    subsys_set_kset(bus, bus_subsys);           //pci_bus_type->subsys.kset.kobj.kset = &bus_subsys.kset (bus_subsys由buses_init调subsystem_register进行初始化)
    retval = subsystem_register(&bus->subsys);       //初始化X.kobj.entry、X.list链表头部、将X.kobj->entry添加到X.kobj->kset->list,创建sys/bus目录下pci目录(X为pci_bus_type->subsys.kset)

    kobject_set_name(&bus->devices.kobj, "devices");   
    bus->devices.subsys = &bus->subsys;
    retval = kset_register(&bus->devices);    //初始化X.kobj.entry、X.list链表头部,X->kobj.parent为pci_bus_type->subsys.kset.kobj,创建sys/bus/pci目录下devices目录(X为pci_bus_type->devices)

    kobject_set_name(&bus->drivers.kobj, "drivers");
    bus->drivers.subsys = &bus->subsys;
    bus->drivers.ktype = &ktype_driver;
    retval = kset_register(&bus->drivers);    //初始化X.kobj.entry、X.list链表头部,X->kobj.parent为pci_bus_type->subsys.kset.kobj,创建sys/bus/pci目录下drivers目录(X为pci_bus_type->drivers)
      .......

二、注册pci设备驱动

int pci_register_driver(struct pci_driver *drv)
{
    int error;

    /* initialize common driver fields */
    drv->driver.name = drv->name;
    drv->driver.bus = &pci_bus_type;
    drv->driver.probe = pci_device_probe;
    drv->driver.remove = pci_device_remove;
    drv->driver.owner = drv->owner;
    drv->driver.kobj.ktype = &pci_driver_kobj_type;
    pci_init_dynids(&drv->dynids);

    /* register with core */
    error = driver_register(&drv->driver);
}

int driver_register(struct device_driver * drv)
{
    INIT_LIST_HEAD(&drv->devices);     //初始化pci设备驱动的devices链表
    init_MUTEX_LOCKED(&drv->unload_sem);
    return bus_add_driver(drv);
}

int bus_add_driver(struct device_driver * drv)
{
    struct bus_type * bus = get_bus(drv->bus);
    int error = 0;

    if (bus) {
        pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
        error = kobject_set_name(&drv->kobj, "%s", drv->name);   //设置drv->driver.kobj.name为pci设备驱动名字
        drv->kobj.kset = &bus->drivers;          //drv->kobj.kset为pci_bus_type->drivers
       error = kobject_register(&drv->kobj));      //初始化drv->kobj->entry链表、drv->kobj.parent为pci_bus_type->drivers->list,将drv->kobj->entry添加到pci_bus_type->drivers->list,以sys/bus/pci/drivers为目录创建pci设备驱动名的目录

        down_write(&bus->subsys.rwsem);
        driver_attach(drv);               //1、遍历pci_bus_type->devices->list上的device调driver_probe_device,该函数调drv->driver.bus.match = &pci_bus_type.match =pci_bus_match将device的pci id与driver注册的pci id进行匹配, 若匹配成功,调driver的probe函数

                                                      2、调device_bind_driver:dev->driver_list添加到dev->driver->devices,将sys/bus/pci/drivers/驱动名/pci_id与sys/bus/pci/devices/pci_id创建软链接

                                                       注:subsys_initcall(pcibios_init)注册pci初始化回调,subsys_initcall也是__define_initcall的宏定义,在系统初始化时回调被调用,??该回调执行pci_scan_bus进行pci设备的bar空间读取并添加设备到pci_bus_type->devices->list??
        up_write(&bus->subsys.rwsem);
        module_add_driver(drv->owner, drv);      //创建driver与module的软链接

        driver_add_attrs(bus, drv);                 //根据pci_dev_attrs创建软链接
}

猜你喜欢

转载自blog.csdn.net/qq_29044159/article/details/111501035