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