首页 > 代码库 > class.c 添加中文注释(2)

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

  1 /* Class Device Stuff */  2   3 int class_device_create_file(struct class_device * class_dev,  4                  const struct class_device_attribute * attr)  5 {  6     int error = -EINVAL;  7       8     /* [cgw]: class_dev指针不为空 */  9     if (class_dev) 10         /* [cgw]: 为class_dev->kobj对象创建一个属性文件 */ 11         error = sysfs_create_file(&class_dev->kobj, &attr->attr); 12     return error; 13 } 14  15 void class_device_remove_file(struct class_device * class_dev, 16                   const struct class_device_attribute * attr) 17 { 18     /* [cgw]: class_dev指针不为空 */ 19     if (class_dev) 20         /* [cgw]: 删除class_dev->kobj对象对应的一个属性文件 */ 21         sysfs_remove_file(&class_dev->kobj, &attr->attr); 22 } 23  24 int class_device_create_bin_file(struct class_device *class_dev, 25                  struct bin_attribute *attr) 26 { 27     int error = -EINVAL; 28  29     /* [cgw]: class_dev指针不为空 */ 30     if (class_dev) 31         /* [cgw]: 为class_dev->kobj对象创建一个BIN文件 */ 32         error = sysfs_create_bin_file(&class_dev->kobj, attr); 33     return error; 34 } 35  36 void class_device_remove_bin_file(struct class_device *class_dev, 37                   struct bin_attribute *attr) 38 { 39     /* [cgw]: class_dev指针不为空 */ 40     if (class_dev) 41         /* [cgw]: 删除class_dev->kobj对象对应的一个BIN文件 */ 42         sysfs_remove_bin_file(&class_dev->kobj, attr); 43 } 44  45 static ssize_t 46 class_device_attr_show(struct kobject * kobj, struct attribute * attr, 47                char * buf) 48 { 49     /* [cgw]: 找出包含这个attr的struct class_device_attribute *指针 */ 50     struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); 51     /* [cgw]: 找出包含这个kobj的struct class_device *指针 52       */ 53     struct class_device * cd = to_class_dev(kobj); 54     ssize_t ret = 0; 55  56     /* [cgw]: class_dev_attr->show指针不为空 */ 57     if (class_dev_attr->show) 58         /* [cgw]: 调用class_dev_attr->show方法 */ 59         ret = class_dev_attr->show(cd, buf); 60     return ret; 61 } 62  63 static ssize_t 64 class_device_attr_store(struct kobject * kobj, struct attribute * attr, 65             const char * buf, size_t count) 66 { 67     /* [cgw]: 找出包含这个attr的struct class_device_attribute *指针 */ 68     struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); 69     /* [cgw]: 找出包含这个kobj的struct class_device *指针 70       */ 71     struct class_device * cd = to_class_dev(kobj); 72     ssize_t ret = 0; 73  74     /* [cgw]: class_dev_attr->store指针不为空 */ 75     if (class_dev_attr->store) 76         /* [cgw]: 调用class_dev_attr->store方法 */ 77         ret = class_dev_attr->store(cd, buf, count); 78     return ret; 79 } 80  81 static struct sysfs_ops class_dev_sysfs_ops = { 82     .show    = class_device_attr_show, 83     .store    = class_device_attr_store, 84 }; 85  86 static void class_dev_release(struct kobject * kobj) 87 { 88     /* [cgw]: 找出包含这个kobj的struct class_device *指针 */ 89     struct class_device *cd = to_class_dev(kobj); 90     /* [cgw]: cls指向class_device的成员class */ 91     struct class * cls = cd->class; 92  93     pr_debug("device class ‘%s‘: release.\n", cd->class_id); 94  95     /* [cgw]: 释放这个class_device的class_device_attribute内存空间 96           * 并把class_device_attribute指针置为空 97           */ 98     kfree(cd->devt_attr); 99     cd->devt_attr = NULL;100 101     /* [cgw]: 调用class_device->release 方法,102           * 释放这个已分配的struct class_device *的内存空间103           */104     if (cd->release)105         cd->release(cd);106     else if (cls->release)107         /* [cgw]: 调用class_device->class->release 方法108               * 释放这个已分配的struct class *的内存空间109               */110         cls->release(cd);111     else {112         printk(KERN_ERR "Class Device ‘%s‘ does not have a release() function, "113             "it is broken and must be fixed.\n",114             cd->class_id);115         WARN_ON(1);116     }117 }118 119 static struct kobj_type ktype_class_device = {120     .sysfs_ops    = &class_dev_sysfs_ops,121     .release    = class_dev_release,122 };123 124 static int class_uevent_filter(struct kset *kset, struct kobject *kobj)125 {126     /* [cgw]: 找到kobj所属的类型ktype */127     struct kobj_type *ktype = get_ktype(kobj);128 129     /* [cgw]: 这个kobj的类型ktype属于ktype_class_device */130     if (ktype == &ktype_class_device) {131         /* [cgw]: 找到包含这个kobj 的class_dev指针132               */133         struct class_device *class_dev = to_class_dev(kobj);134         /* [cgw]: class_dev->class指针不为空 */135         if (class_dev->class)136             return 1;137     }138     return 0;139 }140 141 static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)142 {143     /* [cgw]: 找到包含这个kobj 的class_dev指针144       */145     struct class_device *class_dev = to_class_dev(kobj);146 147     /* [cgw]: 返回class_dev下class的名字 */148     return class_dev->class->name;149 }150 151 #ifdef CONFIG_SYSFS_DEPRECATED152 char *make_class_name(const char *name, struct kobject *kobj)153 {154     char *class_name;155     int size;156     /* [cgw]: 找出这个kobj的名字157           * 计算两个字符串的总长度并+2,158           */159     size = strlen(name) + strlen(kobject_name(kobj)) + 2;160     /* [cgw]: 分配一个size字节的内存空间 */161     class_name = kmalloc(size, GFP_KERNEL);162     /* [cgw]: 分配失败 */163     if (!class_name)164         return NULL;165     /* [cgw] : 把名字name填装到class_name */166     strcpy(class_name, name);167     /* [cgw] : 在名字name末尾添加":" */168     strcat(class_name, ":");169     /* [cgw] : 合并字符串,name+":"+kobj->k_name */170     strcat(class_name, kobject_name(kobj));171     return class_name;172 }173 174 static int make_deprecated_class_device_links(struct class_device *class_dev)175 {176     char *class_name;177     int error;178 179     /* [cgw]: class_dev->dev指针为空 */180     if (!class_dev->dev)181         return 0;182     /* [cgw]: 合并class_dev->class->name和class_dev->kobj->k_name183           */184     class_name = make_class_name(class_dev->class->name, &class_dev->kobj);185     /* [cgw]: 合并成功 */186     if (class_name)187         /* [cgw]: 在class_dev->dev->kobj对象目录下创建一个链表188               * 设置这个链表的名字为class_name189               */190         error = sysfs_create_link(&class_dev->dev->kobj,191                       &class_dev->kobj, class_name);192     else193         error = -ENOMEM;194     /* [cgw]: 释放class_name内存空间,class_name在这里只做临时作用 */195     kfree(class_name);196     return error;197 }198 199 static void remove_deprecated_class_device_links(struct class_device *class_dev)200 {201     char *class_name;202 203     /* [cgw]: class_dev->dev指针为空 */204     if (!class_dev->dev)205         return;206         207     /* [cgw]: 合并class_dev->class->name和class_dev->kobj->k_name208           */209     class_name = make_class_name(class_dev->class->name, &class_dev->kobj);210     if (class_name)211         /* [cgw] : 从class_dev->dev->kobj对象目录下删除一个名字为212               * class_name的链表213               */214         sysfs_remove_link(&class_dev->dev->kobj, class_name);215     /* [cgw] : 释放class_name的内存空间 */216     kfree(class_name);217 }218 #else219 static inline int make_deprecated_class_device_links(struct class_device *cd)220 { return 0; }221 static void remove_deprecated_class_device_links(struct class_device *cd)222 { }223 #endif224 225 static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,226              int num_envp, char *buffer, int buffer_size)227 {228     /* [cgw]: 找出包含这个kobj的class_device结构体指针 */229     struct class_device *class_dev = to_class_dev(kobj);230     struct device *dev = class_dev->dev;231     int i = 0;232     int length = 0;233     int retval = 0;234 235     pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);236 237     /* [cgw]: 主设备号不为0 */238     if (MAJOR(class_dev->devt)) {239         /* [cgw]: 格式化"MAJOR= MAJOR(class_dev->devt)"填装到buffer中240               * 并把buffer指针储存在envp数组241               */242         add_uevent_var(envp, num_envp, &i,243                    buffer, buffer_size, &length,244                    "MAJOR=%u", MAJOR(class_dev->devt));245 246         /* [cgw]: 格式化"MAJOR= MINOR(class_dev->devt)"填装到buffer中247               * 并把buffer指针储存在envp数组248               */249         add_uevent_var(envp, num_envp, &i,250                    buffer, buffer_size, &length,251                    "MINOR=%u", MINOR(class_dev->devt));252     }253 254     /* [cgw]: dev指针不为空 */255     if (dev) {256         /* [cgw]: 获得dev->kobj所在的路径 */257         const char *path = kobject_get_path(&, GFP_KERNEL);258         /* [cgw]: 获取成功 */259         if (path) {260             /* [cgw]: 格式化"PHYSDEVPATH=path"填装到buffer中261                       * 并把buffer指针储存在环境变量envp数组,i+1262                       */263             add_uevent_var(envp, num_envp, &i,264                        buffer, buffer_size, &length,265                        "PHYSDEVPATH=%s", path);266             /* [cgw]: 释放path的内存空间 */267             kfree(path);268         }269 270         /* [cgw]: dev->bus指针不为空 */271         if (dev->bus)272             /* [cgw]: 格式化"PHYSDEVBUS=dev->bus->name"填装到buffer中273                       * 并把buffer指针储存在环境变量envp数组,i+1274                       */275             add_uevent_var(envp, num_envp, &i,276                        buffer, buffer_size, &length,277                        "PHYSDEVBUS=%s", dev->bus->name);278 279         /* [cgw]: dev->driver指针不为空 */280         if (dev->driver)281             /* [cgw]: 格式化"PHYSDEVDRIVER=dev->driver->name"填装到buffer中282                       * 并把buffer指针储存在环境变量envp数组,i+1283                       */284             add_uevent_var(envp, num_envp, &i,285                        buffer, buffer_size, &length,286                        "PHYSDEVDRIVER=%s", dev->driver->name);287     }288 289     /* terminate, set to next free slot, shrink available space */290     /* [cgw]: 清空下一个环境变量,envp[i]是一个指针,把这个指针置0 */291     envp[i] = NULL;292     /* [cgw]: 重置envp的指针,指向下一个环境变量envp[i] */293     envp = &envp[i];294     /* [cgw]: 计算环境变量数组剩下的可用大小 */295     num_envp -= i;296     /* [cgw]: 重置buffer指针,指向buffer + length */297     buffer = &buffer[length];298     /* [cgw]: 计算环境变量buffer剩下的可用大小 */299     buffer_size -= length;300 301     /* [cgw]: class_dev->uevent指针不为空 */302     if (class_dev->uevent) {303         /* have the class device specific function add its stuff */304         /* [cgw]: 调用class_dev->uevent方法 */305         retval = class_dev->uevent(class_dev, envp, num_envp,306                         buffer, buffer_size);307         if (retval)308             pr_debug("class_dev->uevent() returned %d\n", retval);309     } else if (class_dev->class->uevent) {310         /* have the class specific function add its stuff */311         /* [cgw]: 调用class_dev->class->uevent方法 */312         retval = class_dev->class->uevent(class_dev, envp, num_envp,313                            buffer, buffer_size);314         if (retval)315             pr_debug("class->uevent() returned %d\n", retval);316     }317 318     return retval;319 }320 321 static struct kset_uevent_ops class_uevent_ops = {322     .filter =    class_uevent_filter,323     .name =        class_uevent_name,324     .uevent =    class_uevent,325 };326 327 static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);328 329 330 static int class_device_add_attrs(struct class_device * cd)331 {332     int i;333     int error = 0;334     struct class * cls = cd->class;335 336     /* [cgw]: cls->class_dev_attrs指针不为空,即分配了class device 的属性 */337     if (cls->class_dev_attrs) {338         /* [cgw]: 历遍class_dev_attrs[]数组,如果该属性名字不为空,则339               * 对应地创建一个属性文件340               */341         for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {342             /* [cgw]: 创建一个class device属性文件 */343             error = class_device_create_file(cd,344                              &cls->class_dev_attrs[i]);345             if (error)346                 goto Err;347         }348     }349  Done:350     return error;351  Err:352     /* [cgw]: 删除class device的所有属性文件 */353     while (--i >= 0)354         class_device_remove_file(cd,&cls->class_dev_attrs[i]);355     goto Done;356 }357 358 static void class_device_remove_attrs(struct class_device * cd)359 {360     int i;361     struct class * cls = cd->class;362 363     /* [cgw]: cls->class_dev_attrs指针不为空,即此前已经添加了这个属性列表 */364     if (cls->class_dev_attrs) {365         /* [cgw]: 历遍class_dev_attrs[]数组,如果该属性名字不为空,则366               * 对应地删除一个属性文件367               */368         for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)369             /* [cgw]: 删除一个属性文件 */370             class_device_remove_file(cd,&cls->class_dev_attrs[i]);371     }372 }373 374 static int class_device_add_groups(struct class_device * cd)375 {376     int i;377     int error = 0;378 379     /* [cgw]: cd->groups指针不为空 */380     if (cd->groups) {381         /* [cgw]: 历遍groups[],对应每个groups创建一个属性组 */382         for (i = 0; cd->groups[i]; i++) {383             /* [cgw]: 创建一个属性组 */384             error = sysfs_create_group(&cd->kobj, cd->groups[i]);385             /* [cgw]: 创建失败 */386             if (error) {387                 /* [cgw]: 删除所有属性组 */388                 while (--i >= 0)389                     /* [cgw]: 删除一个属性组 */390                     sysfs_remove_group(&cd->kobj, cd->groups[i]);391                 goto out;392             }393         }394     }395 out:396     return error;397 }398 399 static void class_device_remove_groups(struct class_device * cd)400 {401     int i;402     /* [cgw]: cd->groups指针不为空 */403     if (cd->groups) {404         /* [cgw]: 历遍groups[],删除所有属性组 */405         for (i = 0; cd->groups[i]; i++) {406             /* [cgw]: 删除一个属性组 */407             sysfs_remove_group(&cd->kobj, cd->groups[i]);408         }409     }410 }411 412 static ssize_t show_dev(struct class_device *class_dev, char *buf)413 {414     /* [cgw]: 格式化class_dev->devt的主和次设备号为字符串,415           * 填装到buf中416           */417     return print_dev_t(buf, class_dev->devt);418 }419 420 static ssize_t store_uevent(struct class_device *class_dev,421                 const char *buf, size_t count)422 {423     /* [cgw]: 对class_dev->kobj产生一个KOBJ_ADD事件通知用户空间 */424     kobject_uevent(&class_dev->kobj, KOBJ_ADD);425     return count;426 }427 428 void class_device_initialize(struct class_device *class_dev)429 {430     /* [cgw]: 分配class_dev->kobj.kset,指向&class_obj_subsys */431     kobj_set_kset_s(class_dev, class_obj_subsys);432     /* [cgw]: 初始化class_dev->kobj */433     kobject_init(&class_dev->kobj);434     /* [cgw]: 初始化class_dev->node链表 */435     INIT_LIST_HEAD(&class_dev->node);436 }437 438 int class_device_add(struct class_device *class_dev)439 {440     struct class *parent_class = NULL;441     struct class_device *parent_class_dev = NULL;442     struct class_interface *class_intf;443     int error = -EINVAL;444 445     /* [cgw]: class_dev->kobj引用计数+1 446           * 并根据kobj找到包含这个kobj的结构体指针class_dev447           */448     class_dev = class_device_get(class_dev);449     /* [cgw]: class_dev指针为空 */450     if (!class_dev)451         return -EINVAL;452 453     /* [cgw]: class_dev->class_id长度为0 */454     if (!strlen(class_dev->class_id))455         goto out1;456 457     /* [cgw]: class->kobj引用计数+1 458           * 并根据kobj找到包含这个kobj的结构体指针class459           */460     parent_class = class_get(class_dev->class);461     /* [cgw]: parent_class指针为空 */462     if (!parent_class)463         goto out1;464 465     /* [cgw]: 找出class_dev的父节点,并且class_dev->parent->kobj466           * 引用计数+1467           */468     parent_class_dev = class_device_get(class_dev->parent);469 470     pr_debug("CLASS: registering class device: ID = ‘%s‘\n",471          class_dev->class_id);472 473     /* first, register with generic layer. */474     /* [cgw]: 以class_dev->class_id作为class_dev->kobj的名字 */475     error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);476     /* [cgw]: 设置class_dev->kobj的名字失败 */477     if (error)478         goto out2;479 480     /* [cgw]: parent_class_dev指针不为空 */481     if (parent_class_dev)482         /* [cgw]: 设置class_dev的kobj的父节点为class_dev父节点的kobj */483         class_dev->kobj.parent = &parent_class_dev->kobj;484     else485         /* [cgw]: 设置class_dev的kobj的父节点为class->subsys.kobj 486               * 设置class_dev的kobj的在最顶层,父节点就是kset.kobj487               */488         class_dev->kobj.parent = &parent_class->subsys.kobj;489 490     /* [cgw]: 添加kobj到层,实际上是把kobj添加到kset集合491           * entry插入到kobj->kset->list链表中, 为这个kobj创建目录,492           * 即加入到sysfs目录,并为这个kobj添加属性493           */494     error = kobject_add(&class_dev->kobj);495     /* [cgw]: 添加失败 */496     if (error)497         goto out2;498 499     /* add the needed attributes to this device */500     /* [cgw]: 在class_dev->kobj目录下创建一个名为subsystem501       * 的链表,指向parent_class->subsys.kobj502       */503     error = sysfs_create_link(&class_dev->kobj,504                   &parent_class->subsys.kobj, "subsystem");505     /* [cgw]: 创建失败 */506     if (error)507         goto out3;508     /* [cgw]: 设置class_dev的属性名为uevent */509     class_dev->uevent_attr.attr.name = "uevent";510     /* [cgw]: 权限为S_IWUSR */511     class_dev->uevent_attr.attr.mode = S_IWUSR;512     /* [cgw]: 设置拥有这个class_dev->uevent_attr属性的模块 */513     class_dev->uevent_attr.attr.owner = parent_class->owner;514     /* [cgw]: 分配class_dev->uevent_attr.store的方法 */515     class_dev->uevent_attr.store = store_uevent;516     /* [cgw]: 为class_dev->kobj创建一个属性为class_dev->uevent_attr的517       * 属性文件518       */519     error = class_device_create_file(class_dev, &class_dev->uevent_attr);520     /* [cgw]: 创建失败 */521     if (error)522         goto out3;523     /* [cgw]: 主设备号不为0 */524     if (MAJOR(class_dev->devt)) {525         struct class_device_attribute *attr;526         /* [cgw]: 分配一块sizeof(*attr)字节大小的内存空间 */527         attr = kzalloc(sizeof(*attr), GFP_KERNEL);528         /* [cgw]: 分配失败 */529         if (!attr) {530             error = -ENOMEM;531             goto out4;532         }533         /* [cgw]: attr的属性名为dev */534         attr->attr.name = "dev";535         /* [cgw]: attr的权限为S_IRUGO */536         attr->attr.mode = S_IRUGO;537         /* [cgw]: 设置拥有这个attr->attr属性的模块 */538         attr->attr.owner = parent_class->owner;539         /* [cgw]: 分配attr->show的方法 */540         attr->show = show_dev;541         /* [cgw]: 为class_dev->kobj对象创建一个attr属性文件 */542         error = class_device_create_file(class_dev, attr);543         /* [cgw]: 创建失败 */544         if (error) {545             /* [cgw]: 释放attr的内存空间 */546             kfree(attr);547             goto out4;548         }549         /* [cgw]: class_dev->devt_attr指向attr */550         class_dev->devt_attr = attr;551     }552 553     /* [cgw]: 为class_dev->kobj添加属性文件列表,属性文件554           * 来自于class_dev->class->class_dev_attrs[]555           */556     error = class_device_add_attrs(class_dev);557     /* [cgw]: 添加失败 */558     if (error)559         goto out5;560 561     /* [cgw]: class_dev->dev指针不为空 */562     if (class_dev->dev) {563         /* [cgw]: 在class_dev->kobj目录下创建一个名为device的链表564               * 指向class_dev->dev->kobj565               */566         error = sysfs_create_link(&class_dev->kobj,567                       &class_dev->dev->kobj, "device");568         /* [cgw]: 创建失败 */569         if (error)570             goto out6;571     }572 573     /* [cgw]: 添加属性组 */574     error = class_device_add_groups(class_dev);575     /* [cgw]: 添加失败 */576     if (error)577         goto out7;578 579     /* [cgw]: 合并class_dev->class->name和class_dev->kobj->k_name580           * class_dev->dev->kobj对象目录下创建一个链表581           */582     error = make_deprecated_class_device_links(class_dev);583     /* [cgw]: 创建失败 */584     if (error)585         goto out8;586 587     /* [cgw]: 通知用户空间,产生一个KOBJ_ADD事件 */ 588     kobject_uevent(&class_dev->kobj, KOBJ_ADD);589 590     /* notify any interfaces this device is now here */591     /* [cgw]: 获得信号量 */592     down(&parent_class->sem);593     /* [cgw]: 插入一个新节点class_dev->node到parent_class->children节点前 */594     list_add_tail(&class_dev->node, &parent_class->children);595     /* [cgw]: 从parent_class->interfaces的下一节点起,历遍这个链表,直到又回到596       * 头节点(环形链表)597       */598     list_for_each_entry(class_intf, &parent_class->interfaces, node) {599         /* [cgw]: 这个节点的class_intf->add的指针不为空 */600         if (class_intf->add)601             /* [cgw]: 调用class_intf->add方法 */602             class_intf->add(class_dev, class_intf);603     }604     /* [cgw]: 释放信号量 */605     up(&parent_class->sem);606 607     goto out1;608 609  out8:610     /* [cgw]: 删除属性组 */611     class_device_remove_groups(class_dev);612  out7:613     /* [cgw]: class_dev->dev指针不为空 */614     if (class_dev->dev)615         /* [cgw]: 删除class_dev->kobj目录下,名为device的链表 */616         sysfs_remove_link(&class_dev->kobj, "device");617  out6:618     /* [cgw]: 删除class_dev所有属性文件 */619     class_device_remove_attrs(class_dev);620  out5:621     /* [cgw]: class_dev->devt_attr指针不为空,即已经分配了class_dev->devt_attr属性 */622     if (class_dev->devt_attr)623         /* [cgw]: 删除class_dev->kobj对象对应的一个class_dev->devt_attr属性文件 */624         class_device_remove_file(class_dev, class_dev->devt_attr);625  out4:626     /* [cgw]: 删除class_dev->kobj对象对应的一个class_dev->uevent_attr属性文件 */627     class_device_remove_file(class_dev, &class_dev->uevent_attr);628  out3:629     /* [cgw]: 删除class_dev->kobj,从sysfs中删除对应class_dev->kobj的630           * 条目631           */632     kobject_del(&class_dev->kobj);633  out2:634     /* [cgw]: parent_class_dev指针不为空(class_dev->parent) */635     if(parent_class_dev)636         /* [cgw]: parent_class_dev->kobj引用计数-1 */637         class_device_put(parent_class_dev);638     /* [cgw]: parent_class->subsys.kset.kobj引用计数-1 */639     class_put(parent_class);640  out1:641     /* [cgw]: class_dev->kobj引用计数-1 */642     class_device_put(class_dev);643     return error;644 }

 

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