Linux驱动模型——kobject剖析

来源:互联网 发布:火车票网上抢票软件 编辑:程序博客网 时间:2024/05/29 15:11
/*struct kobj_type的声明*/struct kobj_type{/*用于释放kobject*/void (*release)(struct kobject *kobj);/*sys的操作表*/const struct sysfs_ops *sys_ops;/*内核对象的属性,对应于sys文件系统的文件*/struct attribute **default_attrs;};struct kobj_attribute{struct attribute attr;ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf);ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count);};struct attribute{const char *name;struct module *owner;mode_t mode;}/** *  kobject初始化 **/void kobject_init(struct kobject *kobj, struct kobj_type *ktype){char *err_str;/*参数检查*/if (!kobj) {err_str = "invalid kobject pointer!";goto error;}if (!ktype) {err_str = "must have a ktype to be initialized properly!\n";goto error;}/*不能重复初始化*/if (kobj->state_initialized) {/* do not error out as sometimes we can recover */printk(KERN_ERR "kobject (%p): tried to init an initialized "       "object, something is seriously wrong.\n", kobj);dump_stack();}/*初始化*/kobject_init_internal(kobj);/*设置类型*/kobj->ktype = ktype;return;error:printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);dump_stack();}static void kobject_init_internal(struct kobject *kobj){/*参数检查*/if (!kobj)return;/*初始化引用计数*/kref_init(&kobj->kref);/*初始化链入链表的节点*/INIT_LIST_HEAD(&kobj->entry);/*初始化kobject的状态*/kobj->state_in_sysfs = 0;kobj->state_add_uevent_sent = 0;kobj->state_remove_uevent_sent = 0;kobj->state_initialized = 1;}/*添加到sys文件系统*/int kobject_add(struct kobject *kobj, struct kobject *parent,const char *fmt, ...){va_list args;int retval;/*参数检查*/if (!kobj)return -EINVAL;/*必须已经初始化过*/if (!kobj->state_initialized) {printk(KERN_ERR "kobject '%s' (%p): tried to add an "       "uninitialized object, something is seriously wrong.\n",       kobject_name(kobj), kobj);dump_stack();return -EINVAL;}/*详见不定参数的编写*/va_start(args, fmt);/*这是本函数的一个包装*/retval = kobject_add_varg(kobj, parent, fmt, args);va_end(args);return retval;}static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,    const char *fmt, va_list vargs){int retval;/*设置kobject的名字*/retval = kobject_set_name_vargs(kobj, fmt, vargs);if (retval) {printk(KERN_ERR "kobject: can not set name properly!\n");return retval;}/*设置父kobj*/kobj->parent = parent;/*来,开始添加*/return kobject_add_internal(kobj);}/** * kobject_set_name_vargs - Set the name of an kobject * @kobj: struct kobject to set the name of * @fmt: format string used to build the name * @vargs: vargs to format the string. */int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,  va_list vargs){const char *old_name = kobj->name;char *s;/*参数检查*/if (kobj->name && !fmt)return 0;/*char *kvasprintf(gfp_t gfp, const char *fmt, va_list ap),合成字符串*/kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);/*创建失败*/if (!kobj->name)return -ENOMEM;/* ewww... some of these buggers have '/' in the name ... *//*替换路径中的'/'为'!',你懂的*/while ((s = strchr(kobj->name, '/')))s[0] = '!';/*释放老的名字*/kfree(old_name);return 0;}static int kobject_add_internal(struct kobject *kobj){int error = 0;struct kobject *parent;/*参数检查*/if (!kobj)return -ENOENT;if (!kobj->name || !kobj->name[0]) {WARN(1, "kobject: (%p): attempted to be registered with empty " "name!\n", kobj);return -EINVAL;}/*增加父kobject的引用计数*/parent = kobject_get(kobj->parent);/* join kset if set, use it as parent if we do not already have one */if (kobj->kset) {if (!parent)parent = kobject_get(&kobj->kset->kobj);//添加到ksetkobj_kset_join(kobj);kobj->parent = parent;}pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", kobject_name(kobj), kobj, __func__, parent ? kobject_name(parent) : "<NULL>", kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");//创建目录和文件error = create_dir(kobj);//创建失败,进行回滚if (error) {kobj_kset_leave(kobj);kobject_put(parent);kobj->parent = NULL;/* be noisy on error issues */if (error == -EEXIST)printk(KERN_ERR "%s failed for %s with "       "-EEXIST, don't try to register things with "       "the same name in the same directory.\n",       __func__, kobject_name(kobj));elseprintk(KERN_ERR "%s failed for %s (%d)\n",       __func__, kobject_name(kobj), error);dump_stack();} else//创建成功kobj->state_in_sysfs = 1;return error;}static int create_dir(struct kobject *kobj){int error = 0;if (kobject_name(kobj)) {//创建kobject对应的目录error = sysfs_create_dir(kobj);if (!error) {//创建kobj对应属性的文件error = populate_dir(kobj);if (error)//创建失败,进行回滚sysfs_remove_dir(kobj);}}return error;}


原创粉丝点击