注释仅代表个人理解,仅供参考。
1 /* 2 * class.c - basic device class management 3 * 4 * Copyright (c) 2002-3 Patrick Mochel 5 * Copyright (c) 2002-3 Open Source Development Labs 6 * Copyright (c) 2003-2004 Greg Kroah-Hartman 7 * Copyright (c) 2003-2004 IBM Corp. 8 * 9 * This file is released under the GPLv2 10 * 11 */ 12 13 #include <linux/device.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/string.h> 17 #include <linux/kdev_t.h> 18 #include <linux/err.h> 19 #include <linux/slab.h> 20 #include "base.h" 21 22 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) 23 #define to_class(obj) container_of(obj, struct class, subsys.kobj) 24 25 static ssize_t 26 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 27 { 28 /* [cgw]: 找出包含这个attr的struct class_attribute *指针 */ 29 struct class_attribute * class_attr = to_class_attr(attr); 30 /* [cgw]: 找出包含这个kobj的struct class *指针,struct class没有直接 31 * 包含kobj,通过subsys.kobj间接找到struct class *指针 32 */ 33 struct class * dc = to_class(kobj); 34 ssize_t ret = -EIO; 35 /* [cgw]: class_attr->show指针不为空 */ 36 if (class_attr->show) 37 /* [cgw]: 调用class_attr->show这个方法 */ 38 ret = class_attr->show(dc, buf); 39 return ret; 40 } 41 42 static ssize_t 43 class_attr_store(struct kobject * kobj, struct attribute * attr, 44 const char * buf, size_t count) 45 { 46 /* [cgw]: 找出包含这个attr的struct class_attribute *指针 */ 47 struct class_attribute * class_attr = to_class_attr(attr); 48 /* [cgw]: 找出包含这个kobj的struct class *指针,struct class没有直接 49 * 包含kobj,通过subsys.kobj间接找到struct class *指针 50 */ 51 struct class * dc = to_class(kobj); 52 ssize_t ret = -EIO; 53 54 /* [cgw]: class_attr->store指针不为空 */ 55 if (class_attr->store) 56 /* [cgw]: 调用class_attr->store这个方法 */ 57 ret = class_attr->store(dc, buf, count); 58 return ret; 59 } 60 61 static void class_release(struct kobject * kobj) 62 { 63 /* [cgw]: 找出包含这个kobj的struct class *指针,struct class没有直接 64 * 包含kobj,通过subsys.kobj间接找到struct class *指针 65 */ 66 struct class *class = to_class(kobj); 67 68 pr_debug("class '%s': release.\n", class->name); 69 70 /* [cgw]: 释放这个类的方法class->class_release指针不为空 */ 71 if (class->class_release) 72 /* [cgw]: 调用这个方法 */ 73 class->class_release(class); 74 else 75 pr_debug("class '%s' does not have a release() function, " 76 "be careful\n", class->name); 77 } 78 79 static struct sysfs_ops class_sysfs_ops = { 80 .show = class_attr_show, 81 .store = class_attr_store, 82 }; 83 84 static struct kobj_type ktype_class = { 85 .sysfs_ops = &class_sysfs_ops, 86 .release = class_release, 87 }; 88 89 /* Hotplug events for classes go to the class_obj subsys */ 90 static decl_subsys(class, &ktype_class, NULL); 91 92 93 int class_create_file(struct class * cls, const struct class_attribute * attr) 94 { 95 int error; 96 /* [cgw]: cls指针不为空 */ 97 if (cls) { 98 /* [cgw]: 为cls->subsys.kobj对象创建一个属性文件 */ 99 error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);100 } else101 error = -EINVAL;102 return error;103 }104 105 void class_remove_file(struct class * cls, const struct class_attribute * attr)106 {107 /* [cgw]: cls指针不为空 */108 if (cls)109 /* [cgw]: 删除cls->subsys.kobj这个对象的属性文件 */110 sysfs_remove_file(&cls->subsys.kobj, &attr->attr);111 }112 113 static struct class *class_get(struct class *cls)114 {115 /* [cgw]: cls不为空 */116 if (cls)117 /* [cgw]: cls->subsys.kobj引用计数+1,并返回cls指针 */118 return container_of(subsys_get(&cls->subsys), struct class, subsys);119 return NULL;120 }121 122 static void class_put(struct class * cls)123 {124 /* [cgw]: cls指针不为空 */125 if (cls)126 /* [cgw]: 实际上是cls->subsys.kobj引用计数-1 */127 subsys_put(&cls->subsys);128 }129 130 131 static int add_class_attrs(struct class * cls)132 {133 int i;134 int error = 0;135 136 /* [cgw]: cls->class_attrs指针不为空 */137 if (cls->class_attrs) {138 /* [cgw]: cls->class_attrs指向了一个struct class_attribute数组139 * 历遍这个数组,并为这个数组里的每一个元素创建一个属性140 * 文件141 */142 for (i = 0; attr_name(cls->class_attrs[i]); i++) {143 /* [cgw]: 为cls->subsys.kobj创建一个属性文件 */144 error = class_create_file(cls,&cls->class_attrs[i]);145 /* [cgw]: 创建失败 */146 if (error)147 goto Err;148 }149 }150 Done:151 return error;152 Err:153 /* [cgw]: 逐个删除cls->subsys.kobj对应的属性文件列表 */154 while (--i >= 0)155 class_remove_file(cls,&cls->class_attrs[i]);156 goto Done;157 }158 159 static void remove_class_attrs(struct class * cls)160 {161 int i;162 163 /* [cgw]: cls->class_attrs指针不为空 */164 if (cls->class_attrs) {165 /* [cgw]: cls->class_attrs指向了一个struct class_attribute数组166 * 历遍这个数组,并删除这个数组里的每一个元素对应的属167 * 性文件168 */169 for (i = 0; attr_name(cls->class_attrs[i]); i++)170 /* [cgw]: 删除cls->subsys.kobj对应的一个属性文件 */171 class_remove_file(cls,&cls->class_attrs[i]);172 }173 }174 175 int class_register(struct class * cls)176 {177 int error;178 179 pr_debug("device class '%s': registering\n", cls->name);180 181 /* [cgw]: 初始化children链表 */182 INIT_LIST_HEAD(&cls->children);183 /* [cgw]: 初始化devices链表 */184 INIT_LIST_HEAD(&cls->devices);185 /* [cgw]: 初始化interfaces链表 */186 INIT_LIST_HEAD(&cls->interfaces);187 /* [cgw]: 初始化kset */188 kset_init(&cls->class_dirs);189 /* [cgw]: 初始化一个互斥信号量 */190 init_MUTEX(&cls->sem);191 /* [cgw]: 设置kobj的名字和类的一样 */192 error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);193 /* [cgw]: 设置kobj的名字失败 */194 if (error)195 return error;196 /* [cgw]: cls->subsys.kobj.kset指向class_subsys (kset)197 * 实际上是分配了一个kset198 */199 subsys_set_kset(cls, class_subsys);200 /* [cgw]: 注册子系统,实际上是注册了kset */201 error = subsystem_register(&cls->subsys);202 /* [cgw]: 注册成功 */203 if (!error) {204 /* [cgw]: 添加类属性 */205 error = add_class_attrs(class_get(cls));206 /* [cgw]: cls->subsys.kobj 引用计数-1207 * why ???? 208 */209 class_put(cls);210 }211 return error;212 }213 214 void class_unregister(struct class * cls)215 {216 pr_debug("device class '%s': unregistering\n", cls->name);217 /* [cgw]: 删除这个类的所有属性文件 */218 remove_class_attrs(cls);219 /* [cgw]: 注销这个子系统,cls->subsys.kobj */220 subsystem_unregister(&cls->subsys);221 }222 223 static void class_create_release(struct class *cls)224 {225 pr_debug("%s called for %s\n", __FUNCTION__, cls->name);226 /* [cgw]: 释放这个已分配的struct class *的内存空间 */227 kfree(cls);228 }229 230 static void class_device_create_release(struct class_device *class_dev)231 {232 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);233 /* [cgw]: 释放这个已分配的struct class_device *内存空间 */234 kfree(class_dev);235 }236 237 /* needed to allow these devices to have parent class devices */238 static int class_device_create_uevent(struct class_device *class_dev,239 char **envp, int num_envp,240 char *buffer, int buffer_size)241 {242 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);243 return 0;244 }245 246 /**247 * class_create - create a struct class structure248 * @owner: pointer to the module that is to "own" this struct class249 * @name: pointer to a string for the name of this class.250 *251 * This is used to create a struct class pointer that can then be used252 * in calls to class_device_create().253 *254 * Note, the pointer created here is to be destroyed when finished by255 * making a call to class_destroy().256 */257 struct class *class_create(struct module *owner, const char *name)258 {259 struct class *cls;260 int retval;261 262 /* [cgw]: 分配sizeof(*cls)个字节的内存空间 */263 cls = kzalloc(sizeof(*cls), GFP_KERNEL);264 /* [cgw]: 分配失败 */265 if (!cls) {266 retval = -ENOMEM;267 goto error;268 }269 270 /* [cgw]: 给这个类分配一个名字 */271 cls->name = name;272 /* [cgw]: 这个类属于哪个内核模块 */273 cls->owner = owner;274 /* [cgw]: 分配用于释放这个struct class类的回调 275 * 当一个设备从这个类中移除时调用276 */277 cls->class_release = class_create_release;278 /* [cgw]: 分配用于释放这个struct class_device类的回调279 * 当这个类本身被移除时调用280 */281 cls->release = class_device_create_release;282 /* [cgw]: 注册这个类 */283 retval = class_register(cls);284 /* [cgw]: 注册失败 */285 if (retval)286 goto error;287 288 return cls;289 290 error:291 /* [cgw]: 释放这个类 */292 kfree(cls);293 return ERR_PTR(retval);294 }295 296 /**297 * class_destroy - destroys a struct class structure298 * @cls: pointer to the struct class that is to be destroyed299 *300 * Note, the pointer to be destroyed must have been created with a call301 * to class_create().302 */303 void class_destroy(struct class *cls)304 {305 if ((cls == NULL) || (IS_ERR(cls)))306 return;307 /* [cgw]: 注销这个类cls,这个类必须是由class_create()308 * 创建的309 */310 class_unregister(cls);311 }
原标题:class.c 添加中文注释(1)
关键词: