class.c 添加中文注释(1)
2017-06-07 15:18
218 查看
/* * class.c - basic device class management * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs * Copyright (c) 2003-2004 Greg Kroah-Hartman * Copyright (c) 2003-2004 IBM Corp. * * This file is released under the GPLv2 * */ #include <linux/device.h> #include <linux/module.h> #include <linux/init.h> #include <linux/string.h> #include <linux/kdev_t.h> #include <linux/err.h> #include <linux/slab.h> #include "base.h" #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) #define to_class(obj) container_of(obj, struct class, subsys.kobj) static ssize_t class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) { /* [cgw]: 找出包含这个attr的struct class_attribute *指针 */ struct class_attribute * class_attr = to_class_attr(attr); /* [cgw]: 找出包含这个kobj的struct class *指针,struct class没有直接 * 包含kobj,通过subsys.kobj间接找到struct class *指针 */ struct class * dc = to_class(kobj); ssize_t ret = -EIO; /* [cgw]: class_attr->show指针不为空 */ if (class_attr->show) /* [cgw]: 调用class_attr->show这个方法 */ ret = class_attr->show(dc, buf); return ret; } static ssize_t class_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t count) { /* [cgw]: 找出包含这个attr的struct class_attribute *指针 */ struct class_attribute * class_attr = to_class_attr(attr); /* [cgw]: 找出包含这个kobj的struct class *指针,struct class没有直接 * 包含kobj,通过subsys.kobj间接找到struct class *指针 */ struct class * dc = to_class(kobj); ssize_t ret = -EIO; /* [cgw]: class_attr->store指针不为空 */ if (class_attr->store) /* [cgw]: 调用class_attr->store这个方法 */ ret = class_attr->store(dc, buf, count); return ret; } static void class_release(struct kobject * kobj) { /* [cgw]: 找出包含这个kobj的struct class *指针,struct class没有直接 * 包含kobj,通过subsys.kobj间接找到struct class *指针 */ struct class *class = to_class(kobj); pr_debug("class '%s': release.\n", class->name); /* [cgw]: 释放这个类的方法class->class_release指针不为空 */ if (class->class_release) /* [cgw]: 调用这个方法 */ class->class_release(class); else pr_debug("class '%s' does not have a release() function, " "be careful\n", class->name); } static struct sysfs_ops class_sysfs_ops = { .show = class_attr_show, .store = class_attr_store, }; static struct kobj_type ktype_class = { .sysfs_ops = &class_sysfs_ops, .release = class_release, }; /* Hotplug events for classes go to the class_obj subsys */ static decl_subsys(class, &ktype_class, NULL); int class_create_file(struct class * cls, const struct class_attribute * attr) { int error; /* [cgw]: cls指针不为空 */ if (cls) { /* [cgw]: 为cls->subsys.kobj对象创建一个属性文件 */ error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); } else error = -EINVAL; return error; } void class_remove_file(struct class * cls, const struct class_attribute * attr) { /* [cgw]: cls指针不为空 */ if (cls) /* [cgw]: 删除cls->subsys.kobj这个对象的属性文件 */ sysfs_remove_file(&cls->subsys.kobj, &attr->attr); } static struct class *class_get(struct class *cls) { /* [cgw]: cls不为空 */ if (cls) /* [cgw]: cls->subsys.kobj引用计数+1,并返回cls指针 */ return container_of(subsys_get(&cls->subsys), struct class, subsys); return NULL; } static void class_put(struct class * cls) { /* [cgw]: cls指针不为空 */ if (cls) /* [cgw]: 实际上是cls->subsys.kobj引用计数-1 */ subsys_put(&cls->subsys); } static int add_class_attrs(struct class * cls) { int i; int error = 0; /* [cgw]: cls->class_attrs指针不为空 */ if (cls->class_attrs) { /* [cgw]: cls->class_attrs指向了一个struct class_attribute数组 * 历遍这个数组,并为这个数组里的每一个元素创建一个属性 * 文件 */ for (i = 0; attr_name(cls->class_attrs[i]); i++) { /* [cgw]: 为cls->subsys.kobj创建一个属性文件 */ error = class_create_file(cls,&cls->class_attrs[i]); /* [cgw]: 创建失败 */ if (error) goto Err; } } Done: return error; Err: /* [cgw]: 逐个删除cls->subsys.kobj对应的属性文件列表 */ while (--i >= 0) class_remove_file(cls,&cls->class_attrs[i]); goto Done; } static void remove_class_attrs(struct class * cls) { int i; /* [cgw]: cls->class_attrs指针不为空 */ if (cls->class_attrs) { /* [cgw]: cls->class_attrs指向了一个struct class_attribute数组 * 历遍这个数组,并删除这个数组里的每一个元素对应的属 * 性文件 */ for (i = 0; attr_name(cls->class_attrs[i]); i++) /* [cgw]: 删除cls->subsys.kobj对应的一个属性文件 */ class_remove_file(cls,&cls->class_attrs[i]); } } int class_register(struct class * cls) { int error; pr_debug("device class '%s': registering\n", cls->name); /* [cgw]: 初始化children链表 */ INIT_LIST_HEAD(&cls->children); /* [cgw]: 初始化devices链表 */ INIT_LIST_HEAD(&cls->devices); /* [cgw]: 初始化interfaces链表 */ INIT_LIST_HEAD(&cls->interfaces); /* [cgw]: 初始化kset */ kset_init(&cls->class_dirs); /* [cgw]: 初始化一个互斥信号量 */ init_MUTEX(&cls->sem); /* [cgw]: 设置kobj的名字和类的一样 */ error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name); /* [cgw]: 设置kobj的名字失败 */ if (error) return error; /* [cgw]: cls->subsys.kobj.kset指向class_subsys (kset) * 实际上是分配了一个kset */ subsys_set_kset(cls, class_subsys); /* [cgw]: 注册子系统,实际上是注册了kset */ error = subsystem_register(&cls->subsys); /* [cgw]: 注册成功 */ if (!error) { /* [cgw]: 添加类属性 */ error = add_class_attrs(class_get(cls)); /* [cgw]: cls->subsys.kobj 引用计数-1 * why ???? */ class_put(cls); } return error; } void class_unregister(struct class * cls) { pr_debug("device class '%s': unregistering\n", cls->name); /* [cgw]: 删除这个类的所有属性文件 */ remove_class_attrs(cls); /* [cgw]: 注销这个子系统,cls->subsys.kobj */ subsystem_unregister(&cls->subsys); } static void class_create_release(struct class *cls) { pr_debug("%s called for %s\n", __FUNCTION__, cls->name); /* [cgw]: 释放这个已分配的struct class *的内存空间 */ kfree(cls); } static void class_device_create_release(struct class_device *class_dev) { pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); /* [cgw]: 释放这个已分配的struct class_device *内存空间 */ kfree(class_dev); } /* needed to allow these devices to have parent class devices */ static int class_device_create_uevent(struct class_device *class_dev, char **envp, int num_envp, char *buffer, int buffer_size) { pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); return 0; } /** * class_create - create a struct class structure * @owner: pointer to the module that is to "own" this struct class * @name: pointer to a string for the name of this class. * * This is used to create a struct class pointer that can then be used * in calls to class_device_create(). * * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). */ struct class *class_create(struct module *owner, const char *name) { struct class *cls; int retval; /* [cgw]: 分配sizeof(*cls)个字节的内存空间 */ cls = kzalloc(sizeof(*cls), GFP_KERNEL); /* [cgw]: 分配失败 */ if (!cls) { retval = -ENOMEM; goto error; } /* [cgw]: 给这个类分配一个名字 */ cls->name = name; /* [cgw]: 这个类属于哪个内核模块 */ cls->owner = owner; /* [cgw]: 分配用于释放这个struct class类的回调 * 当一个设备从这个类中移除时调用 */ cls->class_release = class_create_release; /* [cgw]: 分配用于释放这个struct class_device类的回调 * 当这个类本身被移除时调用 */ cls->release = class_device_create_release; /* [cgw]: 注册这个类 */ retval = class_register(cls); /* [cgw]: 注册失败 */ if (retval) goto error; return cls; error: /* [cgw]: 释放这个类 */ kfree(cls); return ERR_PTR(retval); } /** * class_destroy - destroys a struct class structure * @cls: pointer to the struct class that is to be destroyed * * Note, the pointer to be destroyed must have been created with a call * to class_create(). */ void class_destroy(struct class *cls) { if ((cls == NULL) || (IS_ERR(cls))) return; /* [cgw]: 注销这个类cls,这个类必须是由class_create() * 创建的 */ class_unregister(cls); }
相关文章推荐
- class.c 添加中文注释(1)
- class.c 添加中文注释(3)
- class.c 添加中文注释(2)
- class.c 添加中文注释(3)
- class.c 添加中文注释(2)
- eclipse查看jar包中class的中文注释乱码问题的解决
- Tomcat的配置文件server.xml中添加中文注释后,启动Tomcat时出现错误
- python 添加中文注释
- eclipse查看jar包中class的中文注释乱码问题的解决
- eclipse查看jar包中class的中文注释乱码问题的解决
- eclipse查看jar包中class的中文注释乱码问题的解决
- 【python3问题解决】python3代码添加中文注释报错
- SE38里行注释的添加取消与中文输入法冲突解决办法
- eclipse查看jar包中class的中文注释乱码问题的解决
- eclipse 自动为getter和setter添加中文注释
- eclipse查看jar包中class的中文注释乱码问题的解决
- python添加中文注释
- 解决svn的一个小问题:添加注释钩子echo中文字符
- sourceinsight添加中文注释的问题
- eclipse搜索中文字符并自动添加注释到行尾