歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> 學習Linux >> class.c 添加中文注釋(1),class.c中文

class.c 添加中文注釋(1),class.c中文

日期:2017/3/6 9:24:45   编辑:學習Linux

class.c 添加中文注釋(1),class.c中文


class.c 添加中文注釋(1),class.c中文


注釋僅代表個人理解,僅供參考。

  1 /*
  2  * class.c - basic device class management
  3  *
  4  * Copyright (c) 2002-3 Patrick Mochel
  5  * Copyright (c) 2002-3 Open Source Development Labs
  6  * Copyright (c) 2003-2004 Greg Kroah-Hartman
  7  * Copyright (c) 2003-2004 IBM Corp.
  8  *
  9  * This file is released under the GPLv2
 10  *
 11  */
 12 
 13 #include <linux/device.h>
 14 #include <linux/module.h>
 15 #include <linux/init.h>
 16 #include <linux/string.h>
 17 #include <linux/kdev_t.h>
 18 #include <linux/err.h>
 19 #include <linux/slab.h>
 20 #include "base.h"
 21 
 22 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
 23 #define to_class(obj) container_of(obj, struct class, subsys.kobj)
 24 
 25 static ssize_t
 26 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 27 {
 28     /* [cgw]: 找出包含這個attr的struct class_attribute *指針 */
 29     struct class_attribute * class_attr = to_class_attr(attr);
 30     /* [cgw]: 找出包含這個kobj的struct class *指針,struct class沒有直接
 31       * 包含kobj,通過subsys.kobj間接找到struct class *指針
 32       */
 33     struct class * dc = to_class(kobj);
 34     ssize_t ret = -EIO;
 35     /* [cgw]: class_attr->show指針不為空 */
 36     if (class_attr->show)
 37         /* [cgw]: 調用class_attr->show這個方法 */
 38         ret = class_attr->show(dc, buf);
 39     return ret;
 40 }
 41 
 42 static ssize_t
 43 class_attr_store(struct kobject * kobj, struct attribute * attr,
 44          const char * buf, size_t count)
 45 {
 46     /* [cgw]: 找出包含這個attr的struct class_attribute *指針 */
 47     struct class_attribute * class_attr = to_class_attr(attr);
 48     /* [cgw]: 找出包含這個kobj的struct class *指針,struct class沒有直接
 49       * 包含kobj,通過subsys.kobj間接找到struct class *指針
 50       */
 51     struct class * dc = to_class(kobj);
 52     ssize_t ret = -EIO;
 53 
 54     /* [cgw]: class_attr->store指針不為空 */
 55     if (class_attr->store)
 56         /* [cgw]: 調用class_attr->store這個方法 */
 57         ret = class_attr->store(dc, buf, count);
 58     return ret;
 59 }
 60 
 61 static void class_release(struct kobject * kobj)
 62 {
 63     /* [cgw]: 找出包含這個kobj的struct class *指針,struct class沒有直接
 64       * 包含kobj,通過subsys.kobj間接找到struct class *指針
 65       */
 66     struct class *class = to_class(kobj);
 67 
 68     pr_debug("class '%s': release.\n", class->name);
 69 
 70     /* [cgw]: 釋放這個類的方法class->class_release指針不為空 */
 71     if (class->class_release)
 72         /* [cgw]: 調用這個方法 */
 73         class->class_release(class);
 74     else
 75         pr_debug("class '%s' does not have a release() function, "
 76              "be careful\n", class->name);
 77 }
 78 
 79 static struct sysfs_ops class_sysfs_ops = {
 80     .show    = class_attr_show,
 81     .store    = class_attr_store,
 82 };
 83 
 84 static struct kobj_type ktype_class = {
 85     .sysfs_ops    = &class_sysfs_ops,
 86     .release    = class_release,
 87 };
 88 
 89 /* Hotplug events for classes go to the class_obj subsys */
 90 static decl_subsys(class, &ktype_class, NULL);
 91 
 92 
 93 int class_create_file(struct class * cls, const struct class_attribute * attr)
 94 {
 95     int error;
 96     /* [cgw]: cls指針不為空 */
 97     if (cls) {
 98         /* [cgw]: 為cls->subsys.kobj對象創建一個屬性文件 */
 99         error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
100     } else
101         error = -EINVAL;
102     return error;
103 }
104 
105 void class_remove_file(struct class * cls, const struct class_attribute * attr)
106 {
107     /* [cgw]: cls指針不為空 */
108     if (cls)
109         /* [cgw]: 刪除cls->subsys.kobj這個對象的屬性文件 */
110         sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
111 }
112 
113 static struct class *class_get(struct class *cls)
114 {
115     /* [cgw]: cls不為空 */
116     if (cls)
117         /* [cgw]: cls->subsys.kobj引用計數+1,並返回cls指針 */
118         return container_of(subsys_get(&cls->subsys), struct class, subsys);
119     return NULL;
120 }
121 
122 static void class_put(struct class * cls)
123 {
124     /* [cgw]: cls指針不為空 */
125     if (cls)
126         /* [cgw]: 實際上是cls->subsys.kobj引用計數-1 */
127         subsys_put(&cls->subsys);
128 }
129 
130 
131 static int add_class_attrs(struct class * cls)
132 {
133     int i;
134     int error = 0;
135 
136     /* [cgw]: cls->class_attrs指針不為空 */
137     if (cls->class_attrs) {
138         /* [cgw]: cls->class_attrs指向了一個struct class_attribute數組
139               * 歷遍這個數組,並為這個數組裡的每一個元素創建一個屬性
140               * 文件
141               */
142         for (i = 0; attr_name(cls->class_attrs[i]); i++) {
143             /* [cgw]: 為cls->subsys.kobj創建一個屬性文件 */
144             error = class_create_file(cls,&cls->class_attrs[i]);
145             /* [cgw]: 創建失敗 */
146             if (error)
147                 goto Err;
148         }
149     }
150  Done:
151     return error;
152  Err:
153     /* [cgw]: 逐個刪除cls->subsys.kobj對應的屬性文件列表 */
154     while (--i >= 0)
155         class_remove_file(cls,&cls->class_attrs[i]);
156     goto Done;
157 }
158 
159 static void remove_class_attrs(struct class * cls)
160 {
161     int i;
162 
163     /* [cgw]: cls->class_attrs指針不為空 */
164     if (cls->class_attrs) {
165         /* [cgw]: cls->class_attrs指向了一個struct class_attribute數組
166               * 歷遍這個數組,並刪除這個數組裡的每一個元素對應的屬
167               * 性文件
168               */
169         for (i = 0; attr_name(cls->class_attrs[i]); i++)
170             /* [cgw]: 刪除cls->subsys.kobj對應的一個屬性文件 */
171             class_remove_file(cls,&cls->class_attrs[i]);
172     }
173 }
174 
175 int class_register(struct class * cls)
176 {
177     int error;
178 
179     pr_debug("device class '%s': registering\n", cls->name);
180 
181     /* [cgw]: 初始化children鏈表 */
182     INIT_LIST_HEAD(&cls->children);
183     /* [cgw]: 初始化devices鏈表 */
184     INIT_LIST_HEAD(&cls->devices);
185     /* [cgw]: 初始化interfaces鏈表 */
186     INIT_LIST_HEAD(&cls->interfaces);
187     /* [cgw]: 初始化kset */
188     kset_init(&cls->class_dirs);
189     /* [cgw]: 初始化一個互斥信號量 */
190     init_MUTEX(&cls->sem);
191     /* [cgw]: 設置kobj的名字和類的一樣 */
192     error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
193     /* [cgw]: 設置kobj的名字失敗 */
194     if (error)
195         return error;
196     /* [cgw]: cls->subsys.kobj.kset指向class_subsys (kset)
197           * 實際上是分配了一個kset
198           */
199     subsys_set_kset(cls, class_subsys);
200     /* [cgw]: 注冊子系統,實際上是注冊了kset */
201     error = subsystem_register(&cls->subsys);
202     /* [cgw]: 注冊成功 */
203     if (!error) {
204         /* [cgw]: 添加類屬性 */
205         error = add_class_attrs(class_get(cls));
206         /* [cgw]: cls->subsys.kobj 引用計數-1
207           * why ???? 
208           */
209         class_put(cls);
210     }
211     return error;
212 }
213 
214 void class_unregister(struct class * cls)
215 {
216     pr_debug("device class '%s': unregistering\n", cls->name);
217     /* [cgw]: 刪除這個類的所有屬性文件 */
218     remove_class_attrs(cls);
219     /* [cgw]: 注銷這個子系統,cls->subsys.kobj */
220     subsystem_unregister(&cls->subsys);
221 }
222 
223 static void class_create_release(struct class *cls)
224 {
225     pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
226     /* [cgw]: 釋放這個已分配的struct class *的內存空間 */
227     kfree(cls);
228 }
229 
230 static void class_device_create_release(struct class_device *class_dev)
231 {
232     pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
233     /* [cgw]: 釋放這個已分配的struct class_device *內存空間 */
234     kfree(class_dev);
235 }
236 
237 /* needed to allow these devices to have parent class devices */
238 static int class_device_create_uevent(struct class_device *class_dev,
239                        char **envp, int num_envp,
240                        char *buffer, int buffer_size)
241 {
242     pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
243     return 0;
244 }
245 
246 /**
247  * class_create - create a struct class structure
248  * @owner: pointer to the module that is to "own" this struct class
249  * @name: pointer to a string for the name of this class.
250  *
251  * This is used to create a struct class pointer that can then be used
252  * in calls to class_device_create().
253  *
254  * Note, the pointer created here is to be destroyed when finished by
255  * making a call to class_destroy().
256  */
257 struct class *class_create(struct module *owner, const char *name)
258 {
259     struct class *cls;
260     int retval;
261 
262     /* [cgw]: 分配sizeof(*cls)個字節的內存空間 */
263     cls = kzalloc(sizeof(*cls), GFP_KERNEL);
264     /* [cgw]: 分配失敗 */
265     if (!cls) {
266         retval = -ENOMEM;
267         goto error;
268     }
269 
270     /* [cgw]: 給這個類分配一個名字 */
271     cls->name = name;
272     /* [cgw]: 這個類屬於哪個內核模塊 */
273     cls->owner = owner;
274     /* [cgw]: 分配用於釋放這個struct class類的回調 
275       * 當一個設備從這個類中移除時調用
276       */
277     cls->class_release = class_create_release;
278     /* [cgw]: 分配用於釋放這個struct class_device類的回調
279       * 當這個類本身被移除時調用
280       */
281     cls->release = class_device_create_release;
282     /* [cgw]: 注冊這個類 */
283     retval = class_register(cls);
284     /* [cgw]: 注冊失敗 */
285     if (retval)
286         goto error;
287 
288     return cls;
289 
290 error:
291     /* [cgw]: 釋放這個類 */
292     kfree(cls);
293     return ERR_PTR(retval);
294 }
295 
296 /**
297  * class_destroy - destroys a struct class structure
298  * @cls: pointer to the struct class that is to be destroyed
299  *
300  * Note, the pointer to be destroyed must have been created with a call
301  * to class_create().
302  */
303 void class_destroy(struct class *cls)
304 {
305     if ((cls == NULL) || (IS_ERR(cls)))
306         return;
307     /* [cgw]: 注銷這個類cls,這個類必須是由class_create()
308           * 創建的
309           */
310     class_unregister(cls);
311 }

http://xxxxxx/Linuxjc/1147860.html TechArticle

Copyright © Linux教程網 All Rights Reserved