浅析linux 2.6.23驱动注册函数driver_register()

文章来源:http://gliethttp.cublog.cn

int driver_register(struct device_driver * drv)
{
    if ((drv->bus->probe && drv->probe) ||
//drv和drv所属的bus之中只要1个提供该函数即可,否则也只能调用bus的函数,而不理会drv的
     (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);//将drv驱动上的设备链表清空
    return bus_add_driver(drv);//将本drv驱动注册登记到drv->bus所在的总线上
}
void klist_init(struct klist * k, void (*get)(struct klist_node *),
        void (*put)(struct klist_node *))
{
    INIT_LIST_HEAD(&k->k_list);//链表初始化
    spin_lock_init(&k->k_lock);//锁初始化
    k->get = get;//引用计数操作自定义函数
    k->put = put;
}
int bus_add_driver(struct device_driver *drv)
{
    struct bus_type * bus = get_bus(drv->bus);
    int error = 0;

if (!bus)
        return -EINVAL;

pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
    //kboj->name[KOBJ_NAME_LEN],如果KOBJ_NAME_LEN长度不够,会调用kmalloc申请
    //之后kobj->k_name指针或者指向kboj->name或者指向kmalloc返回地址
    error = kobject_set_name(&drv->kobj, "%s", drv->name);
    if (error)
        goto out_put_bus;
    //bus->drivers为kset集合类型,也正是管理本drv->kobj的kset集合
    drv->kobj.kset = &bus->drivers;
    //gliethttp_20071025 kobject_register()简单理解
    //把drv的kobj大张旗鼓的登记到管理它的kset集合上去,同时再根据层级关系创建相应的目录文件
    //gliethttp_20071026
    //注册登记该kobj,如果该kobj属于某个kset,那么将自己的entry节点挂接到该kset的list链表上,
    //以示自己需要该kset的滋润,同时kobj->parent=&kset->kobj,parent指向kset用来管理自己的kobj
    //如果该kobj不属于kset,而属于parent,那么简单的将parent的引用计数加1
    //对于kobj属于某个kset的情况,可以实现kset向下查找kobj,也可以实现kobj向上查找kset
    //对于kobj属于某个parent的情况,查找只能是单向的,只能kobj找到parent,parent不能查找
    //该parent挂接的kobj们
    //parent是用来明显建立亲子关系图的标志性变量,当然在kset也能若隐若现的显露出这种关系,
    //但总不如parent正宗和高效
    //之后调用create_dir()创建该kobj在sysfs中的目录文件
    //最后调用kobject_uevent()将KOBJ_ADD事件通知到用户空间的守护进程
    error = kobject_register(&drv->kobj);
    if (error)
        goto out_put_bus;

if (drv->bus->drivers_autoprobe) {
    //gliethttp_20071025
    //driver提供自动匹配函数,那么现在就遍历所有设备
    //尝试将本driver匹配到相应设备上去
        error = driver_attach(drv);
        if (error)
            goto out_unregister;
    }
    //将本driver链接到bus总线上的klist_drivers的klist链表结尾处
    klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
    module_add_driver(drv->owner, drv);

//gliethttp_20071026
//所以一个驱动需要维持住1个klist链条和一个kobj层次结构--驱动drv->kobj对象,内核一方面使用该kobj在sysfs中建立
//统一的与该kobj对应的目录对象供用户空间访问,另一方面使用该kobj的引用计数来获悉该kobj设备的繁忙与空闲情况,
//当本kobj对象的引用计数到达0时,只要其他条件允许,那么说明集成本kobj的结构体对象不再使用,内核得知这个情况很重要,
//因为这对内核进行进一步的决策提供了详细的证据资料,进而对物理设备进行细致的电源管理成了可能,
//如:当hub1上的所有端口设备都被拔掉之后,hub1就可以安全的进入省电模式了,而这个功能在2.4内核中是找不到的.
//如果从面向对象的角度来看待kset、kobj和driver的话,并不能清晰的说明问题,因为面向对象本身提供的封装、继承和多态
//并不能很好的说明kset、kobj和driver之间存在的实际关系,多少都有一些出入,因为linux毕竟不是用c++写的,不像eCos那样,
//虽然大家都努力借鉴面向对象的光辉思想来设计自己的程序,但是面向对象固有的若干弊端因素也是我们必须要剔除的,
//所以剥丝抽茧之后,呈现出来的东西,大多将处于中间态,当然不排除走极端的少数,所以我觉得使用单纯的面向对象思想来理解
//kset、kobj和driver这3者,最终都会带来理解上的麻烦,因为渗透在他们3者之间的设计思想与封装、继承、多态、类、
//虚函数、属性、方法、类属性和类方法等只是相似,而且"仅仅相似,有些影子,但并不是!"
//因此对于正常理解,最好抛弃单纯的面向对象方式(开始我就使用单纯的面向对象方式来理解,结果在若干单元上卡了壳儿,
//现在想来很是可笑,因为那些单元根本就不是面向对象所具有的,硬是要用面向对象来解决,那完全是在牵强)
//而是采用面向对象和c数据结构相结合的方式,
//而且在结合过程中,为了减少麻烦,最好偏向c数据结构多一点(gliethttp_20071026小感).
    //创建属性目录文件
    error = driver_add_attrs(bus, drv);
    if (error) {
       
        printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
            __FUNCTION__, drv->name);
    }
    error = add_bind_files(drv);
    if (error) {
       
        printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
            __FUNCTION__, drv->name);
    }

return error;
out_unregister:
    kobject_unregister(&drv->kobj);
out_put_bus:
    put_bus(bus);
    return error;
}

浅析linuxnbsp;2.6.23驱动注册函数driv…相关推荐

  1. linux spi主机控制器pl022驱动注册以及匹配设备过程

    最近看海思的spi比较多,海思3519的spi ip使用的时ARM提供的pl022,这里对pl022驱动注册和匹配设备树中的设备这个过程捋一下. pl022是ARM提供的片内外设,很多厂商都用了这个i ...

  2. Linux驱动开发 -- touch驱动注册

    Linux i2c驱动开发 – touch 驱动 文章目录 Linux i2c驱动开发 -- touch 驱动 前言 一.i2c 驱动框架 二.Linux的MODULE声明 1. MODULE相关声明 ...

  3. 驱动注册和设备注册分析-1

    1.驱动注册 以i2c驱动注册为例分析驱动注册的代码,弄清楚两点东西 (1)都知道对应的驱动和设备匹配上了会跑它们总线bus_type 的match函数,但这是什么个逻辑呢? (2)驱动和设备匹配上了 ...

  4. linux注册函数机制,Linux可信计算机制模块详细分析之函数实现机制(1)字符设备驱动...

    原标题:Linux可信计算机制模块详细分析之函数实现机制(1)字符设备驱动 2.3 函数实现机制 2.3.1 Linux 字符设备驱动 在linux 3.5.4中,用结构体cdev描述字符设备,cde ...

  5. 浅析alsa声卡驱动snd_pcm_start函数-将音频数据真实的发送到外部音频接口硬件

    转载自链接:浅析alsa声卡驱动snd_pcm_start函数-将音频数据真实的发送到外部音频接口硬件-gliethttp-ChinaUnix博客 http://blog.chinaunix.net/ ...

  6. [驱动注册]platform_driver_register()与platform_device_register()

    [驱动注册]platform_driver_register()与platform_device_register()      设备与驱动的两种绑定方式:在设备注册时进行绑定及在驱动注册时进行绑定. ...

  7. 七、linux驱动注册

    一.驱动注册结构体 驱动注册使用结构体platform_driver,该结构体在头文件"vim include/linux/platform_device.h"中,和刚刚那个设备注 ...

  8. linux设备和驱动注册,Linux驱动第五篇-----驱动注册和生成设备节点

    加载驱动的指令是:insmod xx.ko 查看驱动的指令是: lsmod 卸载驱动的指令是:rmmod xx 在include/linux/platform_device.h这个文件中定义了平台驱动 ...

  9. 【cocos2d-x从c++到js】14:注册函数

    前面的文章中讲过,在游戏启动时,会调用大量的addRegisterCallback函数,向SpiderMonkey注册Cocos2d-x引擎的函数. 1 2 3 4 5 6 7 8 9 10 11 1 ...

最新文章

  1. 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】
  2. 算法-------三角形最小路径和(Java版本)
  3. [译]以PostgreSQL为例,谈join计算的代价
  4. MacBook Pro新版上市
  5. iOS学习 plist读取和写入文件
  6. 开箱即用——用模板快速生成《客户意见反馈表》
  7. 通过流进行字符集编码转换
  8. Learning to rank的讲解,单文档方法(Pointwise),文档对方法(Pairwise),文档列表方法(Listwise)
  9. 阿帕奇跨域_阿帕奇光束
  10. python快速接手别人的代码_十步教你如何接手别人的代码!
  11. 【超强、超详细Redis入门教程】
  12. android投影到创维电视,创维Miracast,手机怎么投屏到创维电视,
  13. [网络应用]winrar主题之Vista Ultimate篇
  14. 人工智能AI系列 - 音频搜索之声纹搜索
  15. 快速消费品行业的营销费用的管理分类
  16. css背景颜色如何铺满屏幕
  17. php创建微信公众号管理系统-序言
  18. 2020中国汽车后市场白皮书
  19. 【请直接拿走~】历年IJCAI顶会论文整理/下载(2016-2021)
  20. 【CSS】三行实现一个黑白网格背景(渐变)

热门文章

  1. 写一个监控路由器下局域网内所有终端的上网情况的脚本
  2. 问题1:解决Pycharm中的terminal无法打字问题
  3. Linux:tslib的编译及使用(触摸屏校准)
  4. css font字体瘦身
  5. resty-mongol3的简单封装
  6. 露天矿卡车数学建模_鼓风机和露天GPU散热器之间有何区别?
  7. 中国人工智能大会报告现场速记-基本情况(一)
  8. 宜信OCR技术探索与实践​|直播速记
  9. Processing——动态条形码
  10. JAVAWEB第六天schema约束