注釋僅代表個人理解,僅供參考。
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