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_DEPRECATED
152 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_name
183           */
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_name
189               */
190         error = sysfs_create_link(&class_dev->dev->kobj,
191                       &class_dev->kobj, class_name);
192     else
193         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_name
208           */
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 #else
219 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 #endif
224
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+1
262                       */
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+1
274                       */
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+1
283                       */
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_dev
447           */
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的结构体指针class
459           */
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->kobj
466           * 引用计数+1
467           */
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     else
485         /* [cgw]: 设置class_dev的kobj的父节点为class->subsys.kobj
486               * 设置class_dev的kobj的在最顶层,父节点就是kset.kobj
487               */
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目录下创建一个名为subsystem
501       * 的链表,指向parent_class->subsys.kobj
502       */
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->kobj
565               */
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_name
580           * 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 }
时间: 2024-10-29 19:06:07

class.c 添加中文注释(2)的相关文章

Python 中添加中文注释以及中文输出解释器报错的解决办法

终于知道如果文件里有非ASCII字符,需要在第一行或第二行指定编码声明.把ChineseTest.py文件的编码重新改为ANSI,并加上编码声明. 在代码的第一行 或者 第二行添加指定文件的编码类型 #-*- coding:utf-8 -*-           //添加代码类型1 #coding=utf-8         //添加代码类型2 上面两种方法随便哪一种都可以,别忘记了前面的 # . 这样代码中就可以添加中文注释 和 中文输出了. 另外提醒一句:vim 查看文件的编码类型是在命令模

eclipse 自动为getter和setter添加中文注释

在我们使用eclipse进行开发的时候常常会使用到eclipse自动生成getter和setter的功能,然后大多情况下eclipse为我们生成的getter和setter都是无法在项目中使用的.还需要我们自己手动修改. 比如下面这个类.我使用了eclipse的自动生成getter和setter的功能并且选择了添加注释.最终的类为如下 public class User { //用户名 private String name; /** * @return the name */ public S

CocosCreator手记02——Examples中文注释目录

任何游戏引擎的都会有一套例子库.用于展示引擎的功能和API的用法. 最近看CocosCreator引擎附带的例子库.目前来说这套Cocos系列引擎的最新版,很有诚意,对比老引擎.加入了很多新的内容.比如资源下载器装载器,各种布局管理工具.预制资源.网络库.碰撞系统.也预留了扩展接口.当然整个引擎也支持插件式扩展. 可惜的是,这份例子是1.5版的,但是没有演示1.5新加的功能,比如物理引擎,摄像机等.另外,个别例子需要对应平台才能跑,在有些平台跑不了.有些例子功能重复,或无法正确演示.但这些都是小

python中文注释报错问题

错误信息: SyntaxError: Non-ASCII character '\xe4' in file... 解决办法: 在文件第一行或第二行添加:# -*- coding: utf-8 -*- 参考:http://blog.csdn.net/chen861201/article/details/7706535 python中文注释报错问题,布布扣,bubuko.com

Android uses-permission权限列表中文注释版

Android有一个精心设计的安全模型.每一个应用都有其自己Linux用户和群组,在单独的进程和VM上运行,不能影响到其他应用 android同时也限定了系统资源的使用,像网络设备,SD卡,录音设备等.如果你的应用希望去使用任何系统资源,我们必须去申请Android的权限.这就是<uses-permission>元素的作用. 一个权限通常有以下格式,用一个名字为name 的字符串去指导我们希望使用的权限. 复制代码代码如下: <uses-permission android:name=&

通过实现CommentGenerator接口的方法来实现Mybatis Generator的model生成中文注释

自己手动实现的前提,对maven项目有基本的了解,在本地成功搭建了maven环境,可以参考我之前的文章:maven环境搭建 项目里新建表时model,mapper以及mapper.xml基本都是用Mybatis Generator(以下简称为MBG)自动生成的,但是MBG自动生成的model的注释实在有点非人类,至少中国人是完全接受不了的,在配置中禁用掉注释吧,倒是简单了,可是生成的model类光秃秃的,啥都没有,字段方法没有注释,使用很不方便,别人看也不知道这个字段是啥含义,到最后还是要自己添

SqlHelper 带详细中文注释

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 //对数据库进行操作引入命名空间 6 using System.Data; 7 using System.Data.SqlClient; 8 using System.Configuration; 9 10 11 namespace DAL 12 { 13 public class SQLhelper 14

Mybatis Generator的model生成中文注释,支持oracle和mysql(通过修改源码的方式来实现)

在看本篇之前,最好先看一下上一篇通过实现CommentGenerator接口的方法来实现中文注释的例子,因为很多操作和上一篇基本是一致的,所以本篇可能不那么详细. 首先说一下上篇通过实现CommentGenerator接口的一些不足,毕竟只是实现了CommentGenerator接口,在里面的方法再怎么改,有效的也只是针对model类,并且使用的人大概也发现了,里面的addClassComment方法都知道是在类文件上面生成注释,但是无论我们在这个方法实现里写什么都没有效果,其实因为MGB默认是

Java项目导出源代码jar包在Eclipse中查看中文注释乱码的问题

问题现场: 由于项目比较多,全部添加到Maven主项目中的话虽然更新调试方便,但项目多了严重影响Eclipse的速度,所以将一部分项目单独导出包含源代码的jar包,上传到nexus上,供其它项目引用:但是在引用的项目中通过Eclipse查看时,中文注释都变成了乱码. 其实这是eclipse的默认编码造成的问题. 解决方案: 1.修改Eclipse中文本文件的默认编码: windows->Preferences->general->Workspace->Text file encod