linux平台设备驱动模型是什么6,Linux设备驱动编程模型之设备篇

下面为一些辅助函数的实现

[cpp]

intdevice_private_init(structdevice *dev)

{

/*从cache中分配private的空间*/

dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);

if(!dev->p)

return-ENOMEM;

dev->p->device = dev;/*设置dev private属性的device为自身*/

/*初始化klist_children属性,后面传入的两个参数为

get和put函数的实现,分别为对引用计数的增加和

减少*/

klist_init(&dev->p->klist_children, klist_children_get,

klist_children_put);

return0;

}

[cpp]

staticstructkobject *get_device_parent(structdevice *dev,

structdevice *parent)

{

intretval;

if(dev->class) {/*如果device存在class*/

structkobject *kobj = NULL;

structkobject *parent_kobj;

structkobject *k;

/*

* If we have no parent, we live in "virtual".

* Class-devices with a non class-device as parent, live

* in a "glue" directory to prevent namespace collisions.

*/

if(parent == NULL)/*如果没有父设备,创建一个

'virtual'的kobj,这里可以看出,当没有父设备

时,class设备可以用'virtual'(即非class设备)

作为父节点kobj的树

而非class设备不行

*/

parent_kobj = virtual_device_parent(dev);

elseif(parent->class)/*当父设备也是class设备时,直接返回其kobj*/

return&parent->kobj;

else/*父设备存在,但是不是class设备*/

parent_kobj = &parent->kobj;

/* find our class-directory at the parent and reference it */

spin_lock(&dev->class->p->class_dirs.list_lock);

list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)

if(k->parent == parent_kobj) {/*遍历同类中的kobj,找到符合的*/

kobj = kobject_get(k);/*递增其引用计数*/

break;

}

spin_unlock(&dev->class->p->class_dirs.list_lock);

if(kobj)

returnkobj;

/* or create a new class-directory at the parent device */

/*程序运行到这里表示没有在dev->class中找到

k->parent==parent_kobj的kobj,所以创建他*/

k = kobject_create();

if(!k)

returnNULL;

/*初始化创建kobj的kset为dev中class->p->class_dirs*/

k->kset = &dev->class->p->class_dirs;

/*添加kobj到其parent的kobj树中,parent字段设置为parent_kobj*/

retval = kobject_add(k, parent_kobj,"%s", dev->class->name);

if(retval 

kobject_put(k);

returnNULL;

}

/* do not emit an uevent for this simple "glue" directory */

returnk;

}

if(parent)/*如果parent存在,返回父设备的kobj*/

return&parent->kobj;

returnNULL;

}

[cpp]

staticstructkobject *virtual_device_parent(structdevice *dev)

{

staticstructkobject *virtual_dir = NULL;

if(!virtual_dir)/*创建名为virtual的kobj加入到设备的集合树中*/

virtual_dir = kobject_create_and_add("virtual",

&devices_kset->kobj);

/*返回创建的kobj*/

returnvirtual_dir;

}

我们看看具体在Linux下的相关目录:

6d69854713b86c550ea38407756c4ecb.gif

b5476aa4cdc0189921e74b775cfd4d38.gif

设备与class关联

static int device_add_class_symlinks(struct device *dev)

{

int error;

/*没有class的情况直接返回*/

if (!dev->class)

return 0;

/*在dev->kobj目录下生成一个名为'subsystem'的链接文件,指向其所属的class的sys的目录/sys/class/***,例如,接着上面的例子

*/

error = sysfs_create_link(&dev->kobj,

&dev->class->p->class_subsys.kobj,

"subsystem");

生成下图:

e4c70f061dedee7b3495f9d0d3db211d.gif

……

}

device关联bus

int bus_add_device(struct device *dev)

{

struct bus_type *bus = bus_get(dev->bus);

int error = 0;

/*如果bus存在,才执行下面部分*/

if (bus) {

pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));

/*添加属性文件,该属性文件问bus的属性*/

error = device_add_attrs(bus, dev);

if (error)

goto out_put;

/*在bus的devices目录下生成到dev->kobj的链接,名称为dev->kobj的名称*/

error = sysfs_create_link(&bus->p->devices_kset->kobj,

&dev->kobj, dev_name(dev));

例如,我们看/sys/devices/platform/devices/下的serial8250,为链接到/sys/devices/platform/serial8250

6a5c458d701f46fba3f3282f8e4db224.gif

if (error)

goto out_id;

/*dev->kobj目录下subsystem为生成的到bus下相关

目录的链接*/

error = sysfs_create_link(&dev->kobj,

&dev->bus->p->subsys.kobj, "subsystem");0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值