zoukankan      html  css  js  c++  java
  • 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.
    ", 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
    ", 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     } else
    101         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
    ", 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           * 实际上是分配了一个kset
    198           */
    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 引用计数-1
    207           * 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
    ", 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
    ", __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
    ", __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
    ", __FUNCTION__, class_dev->class_id);
    243     return 0;
    244 }
    245 
    246 /**
    247  * class_create - create a struct class structure
    248  * @owner: pointer to the module that is to "own" this struct class
    249  * @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 used
    252  * in calls to class_device_create().
    253  *
    254  * Note, the pointer created here is to be destroyed when finished by
    255  * 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 structure
    298  * @cls: pointer to the struct class that is to be destroyed
    299  *
    300  * Note, the pointer to be destroyed must have been created with a call
    301  * 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 }
  • 相关阅读:
    oracle 存储过程
    交错数组
    延迟加载
    js 闭包
    引用类型和值类型
    事务
    web api 之身份验证
    SQLServer中的服务器角色与数据库角色
    按照某一字段的相同值合并所对应的行的值
    VC工程中的字符集工程属性和字符编码(转)
  • 原文地址:https://www.cnblogs.com/hackfun/p/5741599.html
Copyright © 2011-2022 走看看