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

来源:互联网 发布:京东销售额和淘宝比 编辑:程序博客网 时间:2024/06/08 17:36
/* Class Device Stuff */int class_device_create_file(struct class_device * class_dev,                 const struct class_device_attribute * attr){    int error = -EINVAL;        /* [cgw]: class_dev指针不为空 */    if (class_dev)        /* [cgw]: 为class_dev->kobj对象创建一个属性文件 */        error = sysfs_create_file(&class_dev->kobj, &attr->attr);    return error;}void class_device_remove_file(struct class_device * class_dev,                  const struct class_device_attribute * attr){    /* [cgw]: class_dev指针不为空 */    if (class_dev)        /* [cgw]: 删除class_dev->kobj对象对应的一个属性文件 */        sysfs_remove_file(&class_dev->kobj, &attr->attr);}int class_device_create_bin_file(struct class_device *class_dev,                 struct bin_attribute *attr){    int error = -EINVAL;    /* [cgw]: class_dev指针不为空 */    if (class_dev)        /* [cgw]: 为class_dev->kobj对象创建一个BIN文件 */        error = sysfs_create_bin_file(&class_dev->kobj, attr);    return error;}void class_device_remove_bin_file(struct class_device *class_dev,                  struct bin_attribute *attr){    /* [cgw]: class_dev指针不为空 */    if (class_dev)        /* [cgw]: 删除class_dev->kobj对象对应的一个BIN文件 */        sysfs_remove_bin_file(&class_dev->kobj, attr);}static ssize_tclass_device_attr_show(struct kobject * kobj, struct attribute * attr,               char * buf){    /* [cgw]: 找出包含这个attr的struct class_device_attribute *指针 */    struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);    /* [cgw]: 找出包含这个kobj的struct class_device *指针      */    struct class_device * cd = to_class_dev(kobj);    ssize_t ret = 0;    /* [cgw]: class_dev_attr->show指针不为空 */    if (class_dev_attr->show)        /* [cgw]: 调用class_dev_attr->show方法 */        ret = class_dev_attr->show(cd, buf);    return ret;}static ssize_tclass_device_attr_store(struct kobject * kobj, struct attribute * attr,            const char * buf, size_t count){    /* [cgw]: 找出包含这个attr的struct class_device_attribute *指针 */    struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);    /* [cgw]: 找出包含这个kobj的struct class_device *指针      */    struct class_device * cd = to_class_dev(kobj);    ssize_t ret = 0;    /* [cgw]: class_dev_attr->store指针不为空 */    if (class_dev_attr->store)        /* [cgw]: 调用class_dev_attr->store方法 */        ret = class_dev_attr->store(cd, buf, count);    return ret;}static struct sysfs_ops class_dev_sysfs_ops = {    .show    = class_device_attr_show,    .store    = class_device_attr_store,};static void class_dev_release(struct kobject * kobj){    /* [cgw]: 找出包含这个kobj的struct class_device *指针 */    struct class_device *cd = to_class_dev(kobj);    /* [cgw]: cls指向class_device的成员class */    struct class * cls = cd->class;    pr_debug("device class '%s': release.\n", cd->class_id);    /* [cgw]: 释放这个class_device的class_device_attribute内存空间          * 并把class_device_attribute指针置为空          */    kfree(cd->devt_attr);    cd->devt_attr = NULL;    /* [cgw]: 调用class_device->release 方法,          * 释放这个已分配的struct class_device *的内存空间          */    if (cd->release)        cd->release(cd);    else if (cls->release)        /* [cgw]: 调用class_device->class->release 方法              * 释放这个已分配的struct class *的内存空间              */        cls->release(cd);    else {        printk(KERN_ERR "Class Device '%s' does not have a release() function, "            "it is broken and must be fixed.\n",            cd->class_id);        WARN_ON(1);    }}static struct kobj_type ktype_class_device = {    .sysfs_ops    = &class_dev_sysfs_ops,    .release    = class_dev_release,};static int class_uevent_filter(struct kset *kset, struct kobject *kobj){    /* [cgw]: 找到kobj所属的类型ktype */    struct kobj_type *ktype = get_ktype(kobj);    /* [cgw]: 这个kobj的类型ktype属于ktype_class_device */    if (ktype == &ktype_class_device) {        /* [cgw]: 找到包含这个kobj 的class_dev指针              */        struct class_device *class_dev = to_class_dev(kobj);        /* [cgw]: class_dev->class指针不为空 */        if (class_dev->class)            return 1;    }    return 0;}static const char *class_uevent_name(struct kset *kset, struct kobject *kobj){    /* [cgw]: 找到包含这个kobj 的class_dev指针      */    struct class_device *class_dev = to_class_dev(kobj);    /* [cgw]: 返回class_dev下class的名字 */    return class_dev->class->name;}#ifdef CONFIG_SYSFS_DEPRECATEDchar *make_class_name(const char *name, struct kobject *kobj){    char *class_name;    int size;    /* [cgw]: 找出这个kobj的名字          * 计算两个字符串的总长度并+2,          */    size = strlen(name) + strlen(kobject_name(kobj)) + 2;    /* [cgw]: 分配一个size字节的内存空间 */    class_name = kmalloc(size, GFP_KERNEL);    /* [cgw]: 分配失败 */    if (!class_name)        return NULL;    /* [cgw] : 把名字name填装到class_name */    strcpy(class_name, name);    /* [cgw] : 在名字name末尾添加":" */    strcat(class_name, ":");    /* [cgw] : 合并字符串,name+":"+kobj->k_name */    strcat(class_name, kobject_name(kobj));    return class_name;}static int make_deprecated_class_device_links(struct class_device *class_dev){    char *class_name;    int error;    /* [cgw]: class_dev->dev指针为空 */    if (!class_dev->dev)        return 0;    /* [cgw]: 合并class_dev->class->name和class_dev->kobj->k_name          */    class_name = make_class_name(class_dev->class->name, &class_dev->kobj);    /* [cgw]: 合并成功 */    if (class_name)        /* [cgw]: 在class_dev->dev->kobj对象目录下创建一个链表              * 设置这个链表的名字为class_name              */        error = sysfs_create_link(&class_dev->dev->kobj,                      &class_dev->kobj, class_name);    else        error = -ENOMEM;    /* [cgw]: 释放class_name内存空间,class_name在这里只做临时作用 */    kfree(class_name);    return error;}static void remove_deprecated_class_device_links(struct class_device *class_dev){    char *class_name;    /* [cgw]: class_dev->dev指针为空 */    if (!class_dev->dev)        return;            /* [cgw]: 合并class_dev->class->name和class_dev->kobj->k_name          */    class_name = make_class_name(class_dev->class->name, &class_dev->kobj);    if (class_name)        /* [cgw] : 从class_dev->dev->kobj对象目录下删除一个名字为              * class_name的链表              */        sysfs_remove_link(&class_dev->dev->kobj, class_name);    /* [cgw] : 释放class_name的内存空间 */    kfree(class_name);}#elsestatic inline int make_deprecated_class_device_links(struct class_device *cd){ return 0; }static void remove_deprecated_class_device_links(struct class_device *cd){ }#endifstatic int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,             int num_envp, char *buffer, int buffer_size){    /* [cgw]: 找出包含这个kobj的class_device结构体指针 */    struct class_device *class_dev = to_class_dev(kobj);    struct device *dev = class_dev->dev;    int i = 0;    int length = 0;    int retval = 0;    pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);    /* [cgw]: 主设备号不为0 */    if (MAJOR(class_dev->devt)) {        /* [cgw]: 格式化"MAJOR= MAJOR(class_dev->devt)"填装到buffer中              * 并把buffer指针储存在envp数组              */        add_uevent_var(envp, num_envp, &i,                   buffer, buffer_size, &length,                   "MAJOR=%u", MAJOR(class_dev->devt));        /* [cgw]: 格式化"MAJOR= MINOR(class_dev->devt)"填装到buffer中              * 并把buffer指针储存在envp数组              */        add_uevent_var(envp, num_envp, &i,                   buffer, buffer_size, &length,                   "MINOR=%u", MINOR(class_dev->devt));    }    /* [cgw]: dev指针不为空 */    if (dev) {        /* [cgw]: 获得dev->kobj所在的路径 */        const char *path = kobject_get_path(&, GFP_KERNEL);        /* [cgw]: 获取成功 */        if (path) {            /* [cgw]: 格式化"PHYSDEVPATH=path"填装到buffer中                      * 并把buffer指针储存在环境变量envp数组,i+1                      */            add_uevent_var(envp, num_envp, &i,                       buffer, buffer_size, &length,                       "PHYSDEVPATH=%s", path);            /* [cgw]: 释放path的内存空间 */            kfree(path);        }        /* [cgw]: dev->bus指针不为空 */        if (dev->bus)            /* [cgw]: 格式化"PHYSDEVBUS=dev->bus->name"填装到buffer中                      * 并把buffer指针储存在环境变量envp数组,i+1                      */            add_uevent_var(envp, num_envp, &i,                       buffer, buffer_size, &length,                       "PHYSDEVBUS=%s", dev->bus->name);        /* [cgw]: dev->driver指针不为空 */        if (dev->driver)            /* [cgw]: 格式化"PHYSDEVDRIVER=dev->driver->name"填装到buffer中                      * 并把buffer指针储存在环境变量envp数组,i+1                      */            add_uevent_var(envp, num_envp, &i,                       buffer, buffer_size, &length,                       "PHYSDEVDRIVER=%s", dev->driver->name);    }    /* terminate, set to next free slot, shrink available space */    /* [cgw]: 清空下一个环境变量,envp[i]是一个指针,把这个指针置0 */    envp[i] = NULL;    /* [cgw]: 重置envp的指针,指向下一个环境变量envp[i] */    envp = &envp[i];    /* [cgw]: 计算环境变量数组剩下的可用大小 */    num_envp -= i;    /* [cgw]: 重置buffer指针,指向buffer + length */    buffer = &buffer[length];    /* [cgw]: 计算环境变量buffer剩下的可用大小 */    buffer_size -= length;    /* [cgw]: class_dev->uevent指针不为空 */    if (class_dev->uevent) {        /* have the class device specific function add its stuff */        /* [cgw]: 调用class_dev->uevent方法 */        retval = class_dev->uevent(class_dev, envp, num_envp,                        buffer, buffer_size);        if (retval)            pr_debug("class_dev->uevent() returned %d\n", retval);    } else if (class_dev->class->uevent) {        /* have the class specific function add its stuff */        /* [cgw]: 调用class_dev->class->uevent方法 */        retval = class_dev->class->uevent(class_dev, envp, num_envp,                           buffer, buffer_size);        if (retval)            pr_debug("class->uevent() returned %d\n", retval);    }    return retval;}static struct kset_uevent_ops class_uevent_ops = {    .filter =    class_uevent_filter,    .name =        class_uevent_name,    .uevent =    class_uevent,};static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);static int class_device_add_attrs(struct class_device * cd){    int i;    int error = 0;    struct class * cls = cd->class;    /* [cgw]: cls->class_dev_attrs指针不为空,即分配了class device 的属性 */    if (cls->class_dev_attrs) {        /* [cgw]: 历遍class_dev_attrs[]数组,如果该属性名字不为空,则              * 对应地创建一个属性文件              */        for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {            /* [cgw]: 创建一个class device属性文件 */            error = class_device_create_file(cd,                             &cls->class_dev_attrs[i]);            if (error)                goto Err;        }    } Done:    return error; Err:    /* [cgw]: 删除class device的所有属性文件 */    while (--i >= 0)        class_device_remove_file(cd,&cls->class_dev_attrs[i]);    goto Done;}static void class_device_remove_attrs(struct class_device * cd){    int i;    struct class * cls = cd->class;    /* [cgw]: cls->class_dev_attrs指针不为空,即此前已经添加了这个属性列表 */    if (cls->class_dev_attrs) {        /* [cgw]: 历遍class_dev_attrs[]数组,如果该属性名字不为空,则              * 对应地删除一个属性文件              */        for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)            /* [cgw]: 删除一个属性文件 */            class_device_remove_file(cd,&cls->class_dev_attrs[i]);    }}static int class_device_add_groups(struct class_device * cd){    int i;    int error = 0;    /* [cgw]: cd->groups指针不为空 */    if (cd->groups) {        /* [cgw]: 历遍groups[],对应每个groups创建一个属性组 */        for (i = 0; cd->groups[i]; i++) {            /* [cgw]: 创建一个属性组 */            error = sysfs_create_group(&cd->kobj, cd->groups[i]);            /* [cgw]: 创建失败 */            if (error) {                /* [cgw]: 删除所有属性组 */                while (--i >= 0)                    /* [cgw]: 删除一个属性组 */                    sysfs_remove_group(&cd->kobj, cd->groups[i]);                goto out;            }        }    }out:    return error;}static void class_device_remove_groups(struct class_device * cd){    int i;    /* [cgw]: cd->groups指针不为空 */    if (cd->groups) {        /* [cgw]: 历遍groups[],删除所有属性组 */        for (i = 0; cd->groups[i]; i++) {            /* [cgw]: 删除一个属性组 */            sysfs_remove_group(&cd->kobj, cd->groups[i]);        }    }}static ssize_t show_dev(struct class_device *class_dev, char *buf){    /* [cgw]: 格式化class_dev->devt的主和次设备号为字符串,          * 填装到buf中          */    return print_dev_t(buf, class_dev->devt);}static ssize_t store_uevent(struct class_device *class_dev,                const char *buf, size_t count){    /* [cgw]: 对class_dev->kobj产生一个KOBJ_ADD事件通知用户空间 */    kobject_uevent(&class_dev->kobj, KOBJ_ADD);    return count;}void class_device_initialize(struct class_device *class_dev){    /* [cgw]: 分配class_dev->kobj.kset,指向&class_obj_subsys */    kobj_set_kset_s(class_dev, class_obj_subsys);    /* [cgw]: 初始化class_dev->kobj */    kobject_init(&class_dev->kobj);    /* [cgw]: 初始化class_dev->node链表 */    INIT_LIST_HEAD(&class_dev->node);}int class_device_add(struct class_device *class_dev){    struct class *parent_class = NULL;    struct class_device *parent_class_dev = NULL;    struct class_interface *class_intf;    int error = -EINVAL;    /* [cgw]: class_dev->kobj引用计数+1           * 并根据kobj找到包含这个kobj的结构体指针class_dev          */    class_dev = class_device_get(class_dev);    /* [cgw]: class_dev指针为空 */    if (!class_dev)        return -EINVAL;    /* [cgw]: class_dev->class_id长度为0 */    if (!strlen(class_dev->class_id))        goto out1;    /* [cgw]: class->kobj引用计数+1           * 并根据kobj找到包含这个kobj的结构体指针class          */    parent_class = class_get(class_dev->class);    /* [cgw]: parent_class指针为空 */    if (!parent_class)        goto out1;    /* [cgw]: 找出class_dev的父节点,并且class_dev->parent->kobj          * 引用计数+1          */    parent_class_dev = class_device_get(class_dev->parent);    pr_debug("CLASS: registering class device: ID = '%s'\n",         class_dev->class_id);    /* first, register with generic layer. */    /* [cgw]: 以class_dev->class_id作为class_dev->kobj的名字 */    error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);    /* [cgw]: 设置class_dev->kobj的名字失败 */    if (error)        goto out2;    /* [cgw]: parent_class_dev指针不为空 */    if (parent_class_dev)        /* [cgw]: 设置class_dev的kobj的父节点为class_dev父节点的kobj */        class_dev->kobj.parent = &parent_class_dev->kobj;    else        /* [cgw]: 设置class_dev的kobj的父节点为class->subsys.kobj               * 设置class_dev的kobj的在最顶层,父节点就是kset.kobj              */        class_dev->kobj.parent = &parent_class->subsys.kobj;    /* [cgw]: 添加kobj到层,实际上是把kobj添加到kset集合          * entry插入到kobj->kset->list链表中, 为这个kobj创建目录,          * 即加入到sysfs目录,并为这个kobj添加属性          */    error = kobject_add(&class_dev->kobj);    /* [cgw]: 添加失败 */    if (error)        goto out2;    /* add the needed attributes to this device */    /* [cgw]: 在class_dev->kobj目录下创建一个名为subsystem      * 的链表,指向parent_class->subsys.kobj      */    error = sysfs_create_link(&class_dev->kobj,                  &parent_class->subsys.kobj, "subsystem");    /* [cgw]: 创建失败 */    if (error)        goto out3;    /* [cgw]: 设置class_dev的属性名为uevent */    class_dev->uevent_attr.attr.name = "uevent";    /* [cgw]: 权限为S_IWUSR */    class_dev->uevent_attr.attr.mode = S_IWUSR;    /* [cgw]: 设置拥有这个class_dev->uevent_attr属性的模块 */    class_dev->uevent_attr.attr.owner = parent_class->owner;    /* [cgw]: 分配class_dev->uevent_attr.store的方法 */    class_dev->uevent_attr.store = store_uevent;    /* [cgw]: 为class_dev->kobj创建一个属性为class_dev->uevent_attr的      * 属性文件      */    error = class_device_create_file(class_dev, &class_dev->uevent_attr);    /* [cgw]: 创建失败 */    if (error)        goto out3;    /* [cgw]: 主设备号不为0 */    if (MAJOR(class_dev->devt)) {        struct class_device_attribute *attr;        /* [cgw]: 分配一块sizeof(*attr)字节大小的内存空间 */        attr = kzalloc(sizeof(*attr), GFP_KERNEL);        /* [cgw]: 分配失败 */        if (!attr) {            error = -ENOMEM;            goto out4;        }        /* [cgw]: attr的属性名为dev */        attr->attr.name = "dev";        /* [cgw]: attr的权限为S_IRUGO */        attr->attr.mode = S_IRUGO;        /* [cgw]: 设置拥有这个attr->attr属性的模块 */        attr->attr.owner = parent_class->owner;        /* [cgw]: 分配attr->show的方法 */        attr->show = show_dev;        /* [cgw]: 为class_dev->kobj对象创建一个attr属性文件 */        error = class_device_create_file(class_dev, attr);        /* [cgw]: 创建失败 */        if (error) {            /* [cgw]: 释放attr的内存空间 */            kfree(attr);            goto out4;        }        /* [cgw]: class_dev->devt_attr指向attr */        class_dev->devt_attr = attr;    }    /* [cgw]: 为class_dev->kobj添加属性文件列表,属性文件          * 来自于class_dev->class->class_dev_attrs[]          */    error = class_device_add_attrs(class_dev);    /* [cgw]: 添加失败 */    if (error)        goto out5;    /* [cgw]: class_dev->dev指针不为空 */    if (class_dev->dev) {        /* [cgw]: 在class_dev->kobj目录下创建一个名为device的链表              * 指向class_dev->dev->kobj              */        error = sysfs_create_link(&class_dev->kobj,                      &class_dev->dev->kobj, "device");        /* [cgw]: 创建失败 */        if (error)            goto out6;    }    /* [cgw]: 添加属性组 */    error = class_device_add_groups(class_dev);    /* [cgw]: 添加失败 */    if (error)        goto out7;    /* [cgw]: 合并class_dev->class->name和class_dev->kobj->k_name          * class_dev->dev->kobj对象目录下创建一个链表          */    error = make_deprecated_class_device_links(class_dev);    /* [cgw]: 创建失败 */    if (error)        goto out8;    /* [cgw]: 通知用户空间,产生一个KOBJ_ADD事件 */     kobject_uevent(&class_dev->kobj, KOBJ_ADD);    /* notify any interfaces this device is now here */    /* [cgw]: 获得信号量 */    down(&parent_class->sem);    /* [cgw]: 插入一个新节点class_dev->node到parent_class->children节点前 */    list_add_tail(&class_dev->node, &parent_class->children);    /* [cgw]: 从parent_class->interfaces的下一节点起,历遍这个链表,直到又回到      * 头节点(环形链表)      */    list_for_each_entry(class_intf, &parent_class->interfaces, node) {        /* [cgw]: 这个节点的class_intf->add的指针不为空 */        if (class_intf->add)            /* [cgw]: 调用class_intf->add方法 */            class_intf->add(class_dev, class_intf);    }    /* [cgw]: 释放信号量 */    up(&parent_class->sem);    goto out1; out8:    /* [cgw]: 删除属性组 */    class_device_remove_groups(class_dev); out7:    /* [cgw]: class_dev->dev指针不为空 */    if (class_dev->dev)        /* [cgw]: 删除class_dev->kobj目录下,名为device的链表 */        sysfs_remove_link(&class_dev->kobj, "device"); out6:    /* [cgw]: 删除class_dev所有属性文件 */    class_device_remove_attrs(class_dev); out5:    /* [cgw]: class_dev->devt_attr指针不为空,即已经分配了class_dev->devt_attr属性 */    if (class_dev->devt_attr)        /* [cgw]: 删除class_dev->kobj对象对应的一个class_dev->devt_attr属性文件 */        class_device_remove_file(class_dev, class_dev->devt_attr); out4:    /* [cgw]: 删除class_dev->kobj对象对应的一个class_dev->uevent_attr属性文件 */    class_device_remove_file(class_dev, &class_dev->uevent_attr); out3:    /* [cgw]: 删除class_dev->kobj,从sysfs中删除对应class_dev->kobj的          * 条目          */    kobject_del(&class_dev->kobj); out2:    /* [cgw]: parent_class_dev指针不为空(class_dev->parent) */    if(parent_class_dev)        /* [cgw]: parent_class_dev->kobj引用计数-1 */        class_device_put(parent_class_dev);    /* [cgw]: parent_class->subsys.kset.kobj引用计数-1 */    class_put(parent_class); out1:    /* [cgw]: class_dev->kobj引用计数-1 */    class_device_put(class_dev);    return error;}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 速写型总是画不准怎么办 速写人物不会打形怎么办 鼻头又圆又大怎么办 耳鸣嘴溃疡眼流泪上火怎么办 孩子看电视总挤眼睛怎么办 小孩老是咳嗽有痰怎么办 长时间看手机眼睛模糊怎么办 长时间看电脑眼睛模糊怎么办 手机玩多了眼睛模糊怎么办 手机看多了眼睛模糊怎么办 孩子玩手机眼睛红怎么办 手机玩多了眼睛红怎么办 手机看久了眼花怎么办 玩手机眼睛近视了怎么办 近视了怎么办30个字 吃了长牙的土豆怎么办 鸡蛋和土豆吃了怎么办 狗狗眼睛流血水怎么办 石粉粘土干了怎么办 樱花针管笔干了怎么办 想学linux不会c语言怎么办 被摩托车排气管烫伤了怎么办 泡泡糖粘在衣服上怎么办 皮卡书屋办卡怎么办 照证件照齐刘海怎么办 哈挺机床卡刀了怎么办 绝地求生卡在登陆页面怎么办 白鞋子长霉了怎么办 幸福树树干烂了怎么办 花椒树树叶掉落枝干发黑怎么办 茉莉枝干变干了怎么办 冲风了头蒙怎么办 不小心把腰扭了怎么办 白衣服发霉有小黑点怎么办 佛肚竹的枝叶都枯了怎么办 山竹一天吃多了怎么办 水养竹子叶子发黄怎么办 龙竹的竹杆黄了怎么办 散尾竹叶子发黑怎么办 给姐姐打工不发工资怎么办? 水培红掌叶子发黄怎么办