小结:
本文件主要是负责驱动的操作
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
函数列表:
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;
}