你的位置:首页 > 操作系统

[操作系统]class.c 添加中文注释(1)


注释仅代表个人理解,仅供参考。

 

 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 }