drivers\base\driver.c

 

小结:

 

本文件主要是负责驱动的操作

 

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

函数列表:

 

int   driver_for_each_device(struct device_driver * drv, struct device * start,

                        void * data, int (*fn)(struct device *, void *))

遍历挂在drv驱动上的设备链表,执行fn函数

 

struct device * driver_find_device(struct device_driver *drv,

                               struct device * start, void * data,

                               int (*match)(struct device *, void *))

同上,只是match成功后就退出循环

 

@@@@@@

int   driver_create_file(struct device_driver * drv, struct driver_attribute * attr)

为驱动创建指定的属性文件

 

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

删除驱动的属性文件

 

@@@@@@

int   driver_register(struct device_driver * drv)

驱动的注册,先将drv->klist_devices设备链表挂空,然后调用bus.c文件的bus_add_driver函数进行设置

 

void       driver_unregister(struct device_driver * drv)

驱动的反注册

 

struct device_driver *driver_find(const char *name, struct bus_type *bus)

根据名字从指定总线上找寻设备,返回驱动的结构体

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//根据节点获取设备,根据obj获取设备驱动

#define   to_dev(node)         container_of(node, struct device, driver_list)

#define   to_drv(obj)           container_of(obj, struct device_driver, kobj)

 

//通过节点获取下一个设备

static      struct device *       next_device(struct klist_iter * i)

{

       struct klist_node    *n = klist_next(i);

       //根据节点获取设备宿主

       return     n ? container_of(n, struct device, knode_driver) : NULL;

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//遍历驱动的设备链表,执行fn函数

int   driver_for_each_device(

       struct device_driver      * drv,

       struct device                 * start,

       void                            * data,

       int (*fn)(struct device *, void *))

{

       struct klist_iter i;

       struct device * dev;

       int error = 0;

 

       if (!drv)         return -EINVAL;                  //驱动不存在,返回错误

 

       //初始化容器

       klist_iter_init_node(&drv->klist_devices, &i,

                          start ? &start->knode_driver : NULL);

 

       //遍历链表,执行fn函数

       while ((dev = next_device(&i)) && !error)

              error = fn(dev, data);

 

       //退出容器

       klist_iter_exit(&i);

       return error;

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//这个函数就不COPY了,和上一个函数一样,区别是匹配成功后就会退出

//分析bus.c文件时也有类型的函数结构

struct device   * driver_find_device(

       struct device_driver      *drv,

       struct device                 * start,

       void                            * data,

       int (*match)(struct device *, void *))

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

int   driver_create_file(struct device_driver * drv,      struct driver_attribute * attr)

{

       int error;

       if (get_driver(drv)) {            //驱动引用计数加1

              error = sysfs_create_file(&drv->kobj, &attr->attr);     //创建属性文件

              put_driver(drv);

       } else                                  //引用失败,错误返回

              error = -EINVAL;

       return error;

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//删除驱动的属性文件

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

{

       if (get_driver(drv)) {

              sysfs_remove_file(&drv->kobj, &attr->attr);

              put_driver(drv);

       }

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//驱动引用计数

struct device_driver      * get_driver(struct device_driver * drv)

{

       return drv ? to_drv(kobject_get(&drv->kobj)) : NULL;

}

 

//驱动释放计数

void put_driver(struct device_driver * drv)

{

       kobject_put(&drv->kobj);

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//驱动注册,核心函数是bus_add_driver(drv)

int   driver_register(struct device_driver * drv)

{

       if ((drv->bus->probe && drv->probe) ||

           (drv->bus->remove && drv->remove) ||

           (drv->bus->shutdown && drv->shutdown)) {

              //打印警告:驱动和总线都定义了函数,将调用总线上的函数

       }

       klist_init(&drv->klist_devices, NULL, NULL);   //初始化驱动的设备链表

       return     bus_add_driver(drv);                          //驱动添加到总线上,实现在bus.c中

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//从总线上移除驱动

void       driver_unregister(struct device_driver * drv)

{

       bus_remove_driver(drv);

}

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

struct device_driver      *driver_find(const char *name,    struct bus_type *bus)

{

       //根据名字在总线的驱动链表中查找obj

       struct kobject        *k = kset_find_obj(&bus->drivers, name);

       if (k)      

              return     to_drv(k);       //找到目标,返回该obj的驱动结构体宿主

 

       return NULL;

}

 

你可能感兴趣的:(struct,list,File,null,each)