1.driver结构
struct device_driver {
const char *name; //名字
struct bus_type *bus; //其所在的bus
int (*probe) (struct device *dev); //匹配成功时可能会调用到的函数
const struct dev_pm_ops *pm;
struct driver_private *p; //私有成员,表示driver
};
//重点看下driver的私有成员
struct driver_private {
struct kobject kobj; //代表driver自身
struct klist klist_devices; //可以操控的设备链表
struct klist_node knode_bus; //挂接到bus的节点
struct module_kobject *mkobj; //模块相关
struct device_driver *driver; //回指该driver
};
2.driver注册
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
if ((drv->bus->probe && drv->probe) || //driver和bus的同名操作函数如果同时存在,会出现警告
(drv->bus->remove && drv->remove) || //并且会优先选用bus的
(drv->bus->shutdown && drv->shutdown)) ;
other = driver_find(drv->name, drv->bus); //进入bus的driver链表,确认该driver是否已经注册
ret = bus_add_driver(drv); //如果没有注册,那么把该driver加入所在bus
ret = driver_add_groups(drv, drv->groups);
return ret;
}
跟踪一下driver_find(drv->name, drv->bus)
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); //bus->p->drivers_kset代表bus下
struct driver_private *priv; //的driver目录,此处会遍历bus的//driver链表,通过driver内嵌的
if (k) { //kobj名字比较
priv = to_driver(k);
return priv->driver; //如果找到同名的kobj那么返回该driver
}
return NULL;
}
//看一下kset_find_obj吧:
struct kobject *kset_find_obj(struct kset *kset, const char *name)
{
struct kobject *k;
struct kobject *ret = NULL;
spin_lock(&kset->list_lock);
list_for_each_entry(k, &kset->list, entry) { //遍历bus下的driver链表,如果
if (kobject_name(k) && !strcmp(kobject_name(k), name)) {//找到那么返回找到的kobj,并且把
ret = kobject_get(k); //该driver的kobj引用计数+1
break;
}
}
spin_unlock(&kset->list_lock);
return ret;
}
再来跟踪一下driver_register里面的另外一个函数
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus); //取得其所在bus的指针 //开始初始化这个driver的私有成员,//和bus类似
klist_init(&priv->klist_devices, NULL, NULL); //设备操作函数清空,设备链表初始化
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset; //kset指定到bus下面
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, //建立层次结构和属性文件
"%s", drv->name);
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) { //bus的自动匹配如果设置为真,
error = driver_attach(drv); //那么到bus的devices上去匹配设备
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); //把driver挂接到bus的driver链表
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);//以下添加该driver相关属性文件
error = driver_add_attrs(bus, drv);
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
}
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
}
× 接下来就剩下最终要的匹配函数driver_attach(drv)了,我们来看一下:
int driver_attach(struct device_driver *drv) //遍历bus的设备链表找到
{ //合适的设备就调用__driver_attach,
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); //NULL表示从头开始遍历
}
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;
klist_iter_init_node(&bus->p->klist_devices, &i, //进入bus的devices链表
(start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error) //设备存在则调用fn即__driver_attach
error = fn(dev, data); //进行匹配
klist_iter_exit(&i);
return error;
}
× 接着看一下__driver_attach这个函数
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
if (!driver_match_device(drv, dev)) //进行匹配
return 0;
if (dev->parent) /* Needed for USB */
device_lock(dev->parent);
device_lock(dev);
if (!dev->driver) //如果设备没有指定driver
driver_probe_device(drv, dev); //那么需要初始化匹配到的这个设备
device_unlock(dev);
if (dev->parent)
device_unlock(dev->parent);
return 0;
}
× 又遇到两个分支,囧,先看一下driver_match_device
static inline int driver_match_device(struct device_driver *drv, //bus的match存在就用bus的
struct device *dev) //,否则就直接匹配成功...
{ //match通常实现为首先扫描
return drv->bus->match ? drv->bus->match(dev, drv) : 1;//driver支持的id设备表,如果
} //为NULL就用名字进行匹配
再来看一下driver_probe_device这个函数
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
int ret = 0;
if (!device_is_registered(dev)) //判断该设备是否已经注册
return -ENODEV;
pm_runtime_get_noresume(dev);
pm_runtime_barrier(dev);
ret = really_probe(dev, drv); //调用really_probe
pm_runtime_put_sync(dev);
return ret;
}
看一下device_is_registered
static inline int device_is_registered(struct device *dev)
{
return dev->kobj.state_in_sysfs; //在sysfs中表示已经注册
}
再看really_probe
static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
dev->driver = drv; //device的driver初始化成该driver
if (driver_sysfs_add(dev)) {
goto probe_failed;
} //利用probe初始化设备
if (dev->bus->probe) { //如果bus的probe存在就用bus的,
ret = dev->bus->probe(dev); //如果bus的不存在driver的存在
} else if (drv->probe) {
ret = drv->probe(dev);
}
driver_bound(dev); //调用driver_bound进行绑定
}
最后跟一下driver_bound(dev)这个函数
static void driver_bound(struct device *dev)
{
if (klist_node_attached(&dev->p->knode_driver)) { //判断是否已经绑定
return;
}
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); //将设备添加 //到driver的链表
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
}
3.驱动程序属性:
struct driver_attribute
{
struct attribute attr;
ssize_t (*show)(struct device_driver* drv, char* buf);
ssize_t (*store)(struct device_driver* drv, const char* buf, size_t count);
};
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_for_each_device(struct device_driver* drv, struct device* start, void* data, int (*fn)(struct device*, void*)):遍历驱动程序所管理的所有设备;
struct device* driver_find_device(struct device_driver* drv, struct device* start, void* data, int (*match)(struct device*, void*)):查找驱动程序所使用的设备;