系统的每一个驱动程序都由struct device_driver,定义在/include/linux/device.h:
struct device_driver {
        const char              * name; 

 /*设备驱动程序的名称。在调用driver_register()往设备驱动程序模型中插入一个新的device_driver对象时,driver_register()函数会调用bus_add_driver()函数,bus_add_driver()调用kobject_set_name()函数将name赋给drv>kobj.name或者drv->kobj.k_name。注:drv为要调用driver_register()注册的device_driver类型的对象。*/
        struct bus_type         * bus;   //指向总线描述符的指针,总线连接所支持的设备
        struct kobject          kobj;     //内嵌的kobject结构,主要用于计数
        struct klist            klist_devices; 
        struct klist_node       knode_bus;
        struct module           * owner;
        const char              * mod_name;    
        struct module_kobject   * mkobj;
        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);   //将挂起的驱动恢复运行
};

调用函数:

1、driver_register()函数:/linux/drivers/base/driver.c
int driver_register(struct device_driver * drv)
 {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);}
klist_init(&drv->klist_devices, NULL, NULL);
return bus_add_driver(drv);}
函数首先是检查device_driver类型的drv对象和其bus域的回调函数是否已经被赋值,如果为空,则打印警告。核心的注册是调用bus_add_driver()函数实现。在bus_add_driver()函数中,首先是检查drv->bus,如果为空可立即返回EINVAL(无效的变量),注册失败,可见bus域必须提前初始化好才行。接下来是对kobj域进行初始化,检查bus域等。最后调用add_bind_files()函数(实际上是由add_bind_files()函数调用driver_create_file()函数)在sys文件系统下为其创建一个新的目录。

 

2、driver_unregister()函数:/linux/drivers/base/driver.c/linux/drivers/base/driver.c
void driver_unregister(struct device_driver * drv)
{
        bus_remove_driver(drv);
}
调用bus_remove_driver在/linux/drivers/base/bus.c:
void bus_remove_driver(struct device_driver * drv)
{
        if (!drv->bus)
                return;

        remove_bind_files(drv);
        driver_remove_attrs(drv->bus, drv);
        klist_remove(&drv->knode_bus);
        pr_debug("bus %s: remove driver %s/n", drv->bus->name, drv->name);
        driver_detach(drv);
        module_remove_driver(drv);
        kobject_unregister(&drv->kobj);
        put_bus(drv->bus);
}

 

在bus_remove_driver()函数中首先是检查要卸载的device_driver类型的对象drv的bus域,如果为空则返回。此种情况会发生在调用driver_register()函数注册drv时没有检查返回值,注册失败,但程序依然向下运行,到driver_unregister()时就会到688行处返回。接下来会删除在调用driver_register()函数注册时在sys文件系统中创建的目录,然后删除drv对象的属性,(属性是记录在文件中的,删除属性其实是删除记录drv->bus属性的文件),删除驱动模块,减少对drv->bus的引用计数等。

 

3、get_driver()和put_driver()函数:分别是增加和减少对该device_drvier类型的对象的引用计数。

 

4、int driver_create_file(struct device_driver * drv, struct driver_attribute * attr); 

    void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr);

分别是在sys文件系统中为device_driver对象创建和删除目录

 

 

Logo

更多推荐