driver

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*)):查找驱动程序所使用的设备;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值