你的位置:首页 > 操作系统

[操作系统]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 }