class.c 添加中文注释(2)
2016-08-26 18:08
197 查看
/* 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_t class_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_t class_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_DEPRECATED char *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); } #else static inline int make_deprecated_class_device_links(struct class_device *cd) { return 0; } static void remove_deprecated_class_device_links(struct class_device *cd) { } #endif static 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; }
相关文章推荐
- class.c 添加中文注释(1)
- class.c 添加中文注释(2)
- class.c 添加中文注释(3)
- class.c 添加中文注释(3)
- class.c 添加中文注释(1)
- Hive创建表时添加中文注释后乱码问题
- eclipse查看jar包中class的中文注释乱码问题的解决
- Tomcat的配置文件server.xml中添加中文注释后,启动Tomcat时出现错误
- python 添加中文注释
- eclipse查看jar包中class的中文注释乱码问题的解决
- eclipse查看jar包中class的中文注释乱码问题的解决
- eclipse查看jar包中class的中文注释乱码问题的解决
- KiCad设计PCB-40-PCB中添加开窗的logo、丝印层添加英文和中文注释
- SE38里行注释的添加取消与中文输入法冲突解决办法
- eclipse查看jar包中class的中文注释乱码问题的解决
- eclipse 自动为getter和setter添加中文注释
- eclipse查看jar包中class的中文注释乱码问题的解决
- python添加中文注释
- 解决svn的一个小问题:添加注释钩子echo中文字符
- eclipse搜索中文字符并自动添加注释到行尾