浅析linux 2.6.23驱动注册函数driver_register()
来源:互联网 发布:java 通过ip获取mac 编辑:程序博客网 时间:2024/05/16 18:54
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 ) {
/* How the hell do we get out of this pickle? Give up */
printk( KERN_ERR "%s: driver_add_attrs(%s) failed/n" ,
__FUNCTION__ , drv- > name) ;
}
error = add_bind_files( drv) ;
if ( error ) {
/* Ditto */
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 ;
}
- 浅析linux 2.6.23驱动注册函数driver_register()
- 浅析linux 2.6.23驱动注册函数driver_register()
- 浅析linux 2.6.23驱动注册函数driver_register()
- 浅析linux 2.6.23驱动注册函数driver_register()
- 浅析linux 2.6.23驱动注册函数driver_register()
- Linux 驱动注册(driver_register)流程probe方法的选择
- linux驱动注册过程分析--driver_register(一)
- linux I2C 驱动之----i2c驱动的注册过程(i2c_register_driver->driver_register(&driver->driver)->driver_find)
- linux I2C 驱动之----i2c驱动的注册过程(i2c_register_driver->driver_register(&driver->driver)->driver_find)
- linux I2C 驱动之----i2c驱动的注册过程(i2c_register_driver->driver_register(&driver->driver)->driver_find)
- linux I2C 驱动之----i2c驱动的注册过程(i2c_register_driver->driver_register(&driver->driver)->driver_find)
- linux下设备device_register和驱动driver_register先后注册的影响和关系
- linux下设备device_register和驱动driver_register先后注册的影响和关系
- linux下设备device_register和驱动driver_register先后注册的影响和关系
- linux下设备device_register和驱动driver_register先后注册的影响和关系
- 浅析linux 2.6.23驱动自动匹配设备driver_attach()函数
- 浅析linux 2.6.23驱动自动匹配设备driver_attach()函数
- Linux AMBA设备驱动注册过程浅析
- 食疗歌
- Deploying an Application to Weblogic using WLST
- 什么是STL?
- 安装VS2008的问题——Microsoft Visual Studio Web创作组件安装失败
- 《Sikuli: Using GUI Screenshots for Search and Automation》
- 浅析linux 2.6.23驱动注册函数driver_register()
- oracle物化视图
- pku1679 The Unique MST
- 传智播客-多线程(6)-jdk5里的concurrent与atomic包
- HOME - Research Highlights & Publications
- 软件架构学习小结
- 死锁演示代码
- 唱自己的歌(摘自 A Cup Of Comfort)
- 安装SQL SERVER 2000 后更改服务器名的解决。