设备驱动模型之:kobject,kset,ktype(五)

在《设备驱动模型之:kobject,kset,ktype(四)》这篇博文里面已经详细介绍了kset的操作以及kset与kobject的关系,下面则是对于这篇博文的一些实际操作:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/slab.h>

static struct kset * first_kset = NULL;
static struct kset * second_kset = NULL;
static struct kset third_kset;
#define FIRST_KSET_NAME "first"
#define SECOND_KSET_NAME "second"
#define THIRD_KSET "third"

static int filter(struct kset *kset, struct kobject *kobj)
{
        printk("this is %s , and kset is : %s , and kobj is %s\n", __func__, kset->kobj.name, kobj->name);
        return 1;
}
static const char *name(struct kset *kset, struct kobject *kobj)
{
        printk("this is %s , and kset is : %s , and kobj is %s\n", __func__, kset->kobj.name, kobj->name);
        return kset->kobj.name;
}
static int uevent(struct kset *kset, struct kobject *kobj,
                      struct kobj_uevent_env *env)
{
        printk("this is %s , and kset is : %s , and kobj is %s\n", __func__, kset->kobj.name, kobj->name);
        return 0;
}

static struct kset_uevent_ops uevent_ops = {
        .filter = filter,
        .name  = name,
        .uevent = uevent
};

static ssize_t  kshow(struct kobject *kobj, struct attribute * attr,char *buff)
{
        printk("this is %s, and kboj : %s and attr: %s\n", __func__, kobj->name, attr->name);
        return 0;
}
static ssize_t  kstore(struct kobject *kobj,struct attribute *attr,const char * buff, size_t count)
{
        printk("this is %s, and kboj : %s and attr: %s\n", __func__, kobj->name, attr->name);
        printk("store buff: %s\n", buff);
        return 0;
}
static struct sysfs_ops sysfs_ops=  {
        .show = kshow,
        .store = kstore
};
static struct attribute attr1 = {.name = "alex1", .mode=S_IRWXUGO};
static struct attribute attr2 = {.name = "alex2", .mode=S_IRWXUGO};
static struct attribute *default_attrs[] = {
        &attr1,
        &attr2,
        NULL
};

static struct kobj_type third_ktype = {
        .sysfs_ops = &sysfs_ops,
        .default_attrs = default_attrs
};



static inline int __init
kset_test_init(void)
{
        int ret = 0;
        first_kset = kset_create_and_add(FIRST_KSET_NAME, & uevent_ops,NULL);
        if (NULL == first_kset){
                ret = -ENOMEM;
                goto out;
        }
        second_kset = kset_create_and_add(SECOND_KSET_NAME, &uevent_ops, &(first_kset->kobj));
        if (NULL == second_kset){
                ret = -ENOMEM;
                goto create_second_kset_failed;
        }

        kobject_set_name(&(third_kset.kobj), THIRD_KSET);
        third_kset.kobj.parent = &(second_kset->kobj);
        third_kset.kobj.ktype = &third_ktype;
        third_kset.uevent_ops = &uevent_ops;
        third_kset.kobj.kset = second_kset;
        ret = kset_register(&third_kset);
        if (ret){
                goto third_kset_register_failed;
        }
        return ret;
third_kset_register_failed:
        kset_unregister(second_kset);
create_second_kset_failed:
        kset_unregister(first_kset);
out:
        return ret;
}

static inline void __exit
kset_test_exit(void)
{
        kset_unregister(&third_kset);
        kset_unregister(second_kset);
        kset_unregister(first_kset);
}

module_init(kset_test_init);
module_exit(kset_test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexander");

下一篇博客则是介绍kset与kobject和kset的的关系的,可能介绍的不好有遗漏的地方请大家谅解。

猜你喜欢

转载自blog.csdn.net/weixin_37867857/article/details/84780162