class.c 添加中文注释(1)

来源:互联网 发布:苹果电脑编写代码软件 编辑:程序博客网 时间:2024/06/05 19:24
/* * 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_tclass_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_tclass_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);}

原创粉丝点击