class.c 添加中文注释(3)

  1 int class_device_register(struct class_device *class_dev)
  2 {
  3     /* [cgw]: 初始化一个struct class_device */
  4     class_device_initialize(class_dev);
  5     /* [cgw]: 添加一个struct class_device */
  6     return class_device_add(class_dev);
  7 }
  8 
  9 /**
 10  * class_device_create - creates a class device and registers it with sysfs
 11  * @cls: pointer to the struct class that this device should be registered to.
 12  * @parent: pointer to the parent struct class_device of this new device, if any.
 13  * @devt: the dev_t for the char device to be added.
 14  * @device: a pointer to a struct device that is assiociated with this class device.
 15  * @fmt: string for the class device's name
 16  *
 17  * This function can be used by char device classes.  A struct
 18  * class_device will be created in sysfs, registered to the specified
 19  * class.
 20  * A "dev" file will be created, showing the dev_t for the device, if
 21  * the dev_t is not 0,0.
 22  * If a pointer to a parent struct class_device is passed in, the newly
 23  * created struct class_device will be a child of that device in sysfs.
 24  * The pointer to the struct class_device will be returned from the
 25  * call.  Any further sysfs files that might be required can be created
 26  * using this pointer.
 27  *
 28  * Note: the struct class passed to this function must have previously
 29  * been created with a call to class_create().
 30  */
 31 struct class_device *class_device_create(struct class *cls,
 32                      struct class_device *parent,
 33                      dev_t devt,
 34                      struct device *device,
 35                      const char *fmt, ...)
 36 {
 37     va_list args;
 38     struct class_device *class_dev = NULL;
 39     int retval = -ENODEV;
 40 
 41     /* [cgw]: cls为空或错误 */
 42     if (cls == NULL || IS_ERR(cls))
 43         goto error;
 44 
 45     /* [cgw]: 分配sizeof(*class_dev)字节大小的内存空间 */
 46     class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
 47     /* [cgw]: 分配失败 */
 48     if (!class_dev) {
 49         retval = -ENOMEM;
 50         goto error;
 51     }
 52 
 53     /* [cgw]: 分配设备号 */
 54     class_dev->devt = devt;
 55     /* [cgw]: 分配一个struct device */
 56     class_dev->dev = device;
 57     /* [cgw]: 分配一个struct class */
 58     class_dev->class = cls;
 59     /* [cgw]: 分配一个parent struct class_device */
 60     class_dev->parent = parent;
 61     /* [cgw]: 分配release方法 */
 62     class_dev->release = class_device_create_release;
 63     /* [cgw]: 分配uevent方法 */
 64     class_dev->uevent = class_device_create_uevent;
 65 
 66     va_start(args, fmt);
 67     /* [cgw]: 把args格式化到字符串fmt中,填装到class_dev->class_id */
 68     vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
 69     va_end(args);
 70     /* [cgw]: 注册一个class_dev */
 71     retval = class_device_register(class_dev);
 72     if (retval)
 73         goto error;
 74 
 75     return class_dev;
 76 
 77 error:
 78     /* [cgw]: 释放class_dev的内存空间 */
 79     kfree(class_dev);
 80     return ERR_PTR(retval);
 81 }
 82 
 83 void class_device_del(struct class_device *class_dev)
 84 {
 85     struct class *parent_class = class_dev->class;
 86     struct class_device *parent_device = class_dev->parent;
 87     struct class_interface *class_intf;
 88 
 89     /* [cgw]: parent_class不为空 */
 90     if (parent_class) {
 91         /* [cgw]: 获取信号量 */
 92         down(&parent_class->sem);
 93         /* [cgw]: 删除class_dev->node节点 */
 94         list_del_init(&class_dev->node);
 95         /* [cgw]: 历遍class_intf->node链表,直到回到parent_class->interfaces节点 */
 96         list_for_each_entry(class_intf, &parent_class->interfaces, node)
 97             /* [cgw]: class_intf->remove指针不为空 */
 98             if (class_intf->remove)
 99                 /* [cgw]: 调用remove方法 */
100                 class_intf->remove(class_dev, class_intf);
101         /* [cgw]: 释放信号量 */
102         up(&parent_class->sem);
103     }
104 
105     /* [cgw]: class_dev->dev指针不为空 */
106     if (class_dev->dev) {
107         /* [cgw] : 从class_dev->dev->kobj对象目录下删除一个名字为
108               * class_dev->class->name+class_dev->kobj->k_name的链表
109               */
110         remove_deprecated_class_device_links(class_dev);
111         /* [cgw]: class_dev->kobj目录下,删除名为device的链表 */
112         sysfs_remove_link(&class_dev->kobj, "device");
113     }
114     /* [cgw]: class_dev->kobj目录下,删除名为subsystem的链表 */
115     sysfs_remove_link(&class_dev->kobj, "subsystem");
116 
117     /* [cgw]: 删除class_dev->kobj对象对应的一个class_dev->uevent_attr->attr
118       * 属性文件
119       */
120     class_device_remove_file(class_dev, &class_dev->uevent_attr);
121     /* [cgw]: class_dev->devt_attr指针不为空 */
122     if (class_dev->devt_attr)
123         /* [cgw]: 删除class_dev->kobj对象对应的一个class_dev->devt_attr->attr
124               * 属性文件
125               */
126         class_device_remove_file(class_dev, class_dev->devt_attr);
127     /* [cgw]: 历遍class_dev->class->class_dev_attrs[]数组,如果该属性名字不为空,
128       * 则对应地删除一个属性文件
129       */
130     class_device_remove_attrs(class_dev);
131     /* [cgw]: 历遍class_dev->groups[],删除所有属性组 */
132     class_device_remove_groups(class_dev);
133 
134     /* [cgw]: 通知用户空间,产生一个KOBJ_REMOVE事件 */
135     kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
136     /* [cgw]: 删除kobj对象目录,从kset链表中删除class_dev->kobj */
137     kobject_del(&class_dev->kobj);
138 
139     /* [cgw]: parent_device->kobj引用计数-1 */
140     class_device_put(parent_device);
141     /* [cgw]: parent_class->kobj引用计数-1 */
142     class_put(parent_class);
143 }
144 
145 void class_device_unregister(struct class_device *class_dev)
146 {
147     pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
148          class_dev->class_id);
149     /* [cgw]: 删除struct class_device */
150     class_device_del(class_dev);
151     /* [cgw]: class_dev->kobj引用计数-1 */
152     class_device_put(class_dev);
153 }
154 
155 /**
156  * class_device_destroy - removes a class device that was created with class_device_create()
157  * @cls: the pointer to the struct class that this device was registered * with.
158  * @devt: the dev_t of the device that was previously registered.
159  *
160  * This call unregisters and cleans up a class device that was created with a
161  * call to class_device_create()
162  */
163 void class_device_destroy(struct class *cls, dev_t devt)
164 {
165     struct class_device *class_dev = NULL;
166     struct class_device *class_dev_tmp;
167 
168     /* [cgw]: 获得信号量 */
169     down(&cls->sem);
170     /* [cgw]: 返回class_dev_tmp指针,历遍class_dev_tmp链表,
171       * 查找与cls->children相等的节点class_dev_tmp->node
172       */
173     list_for_each_entry(class_dev_tmp, &cls->children, node) {
174         /* [cgw]: 找到该节点,设备号为devt */
175         if (class_dev_tmp->devt == devt) {
176             /* [cgw]: class_dev指向class_dev_tmp */
177             class_dev = class_dev_tmp;
178             break;
179         }
180     }
181     /* [cgw]: 释放信号量 */
182     up(&cls->sem);
183 
184     /* [cgw]: class_dev指针不为空 */
185     if (class_dev)
186         /* [cgw]: 注销这个class_dev */
187         class_device_unregister(class_dev);
188 }
189 
190 struct class_device * class_device_get(struct class_device *class_dev)
191 {
192     /* [cgw]: class_dev指针不为空 */
193     if (class_dev)
194         /* [cgw]: class_dev->kobj引用计数+1 
195               * 并根据kobj找到包含这个kobj的结构体指针
196               */
197         return to_class_dev(kobject_get(&class_dev->kobj));
198     return NULL;
199 }
200 
201 void class_device_put(struct class_device *class_dev)
202 {
203     /* [cgw]: class_dev指针不为空 */
204     if (class_dev)
205         /* [cgw]: class_dev->kobj引用计数-1 */
206         kobject_put(&class_dev->kobj);
207 }
208 
209 
210 int class_interface_register(struct class_interface *class_intf)
211 {
212     struct class *parent;
213     struct class_device *class_dev;
214     struct device *dev;
215 
216     /* [cgw]: class_intf或class_intf->class指针为空 */
217     if (!class_intf || !class_intf->class)
218         return -ENODEV;
219 
220     /* [cgw]:  class_intf->class->subsys->kset.kobj引用计数+1,
221           * parent指向class_intf->class 
222           */
223     parent = class_get(class_intf->class);
224     /* [cgw]: parent指针为空 */
225     if (!parent)
226         return -EINVAL;
227 
228     /* [cgw]: 获取信号量 */
229     down(&parent->sem);
230     /* [cgw]: 添加一个新节点class_intf->node,位于parent->interfaces节点前 */
231     list_add_tail(&class_intf->node, &parent->interfaces);
232 
233     /* [cgw]: class_intf->add指针不为空 */
234     if (class_intf->add) {
235         /* [cgw]: 返回class_dev指针,历遍class_dev链表,
236               * 调用每个节点node对应的add方法
237               */
238         list_for_each_entry(class_dev, &parent->children, node)
239             /* [cgw]: 调用与node (class_dev)对应的add方法 */
240             class_intf->add(class_dev, class_intf);
241     }
242 
243     /* [cgw]: class_intf->add_dev指针不为空 */
244     if (class_intf->add_dev) {
245         /* [cgw]: 返回dev指针,历遍dev链表,
246               * 调用每个节点node对应的add_dev方法
247               */
248         list_for_each_entry(dev, &parent->devices, node)
249             /* [cgw]: 调用与node (dev)对应的add_dev方法 */
250             class_intf->add_dev(dev, class_intf);
251     }
252     /* [cgw]: 释放信号量 */
253     up(&parent->sem);
254 
255     return 0;
256 }
257 
258 void class_interface_unregister(struct class_interface *class_intf)
259 {
260     /* [cgw]: parent指针指向class_intf->class */
261     struct class * parent = class_intf->class;
262     struct class_device *class_dev;
263     struct device *dev;
264 
265     /* [cgw]: parent指针为空 */
266     if (!parent)
267         return;
268 
269     /* [cgw]: 获取信号量 */
270     down(&parent->sem);
271     /* [cgw]: 删除一个节点class_intf->node */
272     list_del_init(&class_intf->node);
273     /* [cgw]: class_intf->remove指针不为空 */
274     if (class_intf->remove) {
275         /* [cgw]: 返回class_dev指针,历遍class_dev链表,
276               * 调用每个节点node对应的remove方法
277               */
278         list_for_each_entry(class_dev, &parent->children, node)
279             /* [cgw]: 调用与node (class_dev)对应的remove方法 */
280             class_intf->remove(class_dev, class_intf);
281     }
282 
283     /* [cgw]: class_intf->remove_dev指针不为空 */
284     if (class_intf->remove_dev) {
285         /* [cgw]: 返回dev指针,历遍dev链表,
286               * 调用每个节点node对应的remove_dev方法
287               */
288         list_for_each_entry(dev, &parent->devices, node)
289             /* [cgw]: 调用与node (class_dev)对应的remove_dev方法 */
290             class_intf->remove_dev(dev, class_intf);
291     }
292     /* [cgw]: 释放信号量 */
293     up(&parent->sem);
294 
295     /* [cgw]: parent->subsys->kobj引用计数-1 */
296     class_put(parent);
297 }
298 
299 int __init classes_init(void)
300 {
301     int retval;
302 
303     retval = subsystem_register(&class_subsys);
304     if (retval)
305         return retval;
306 
307     /* ick, this is ugly, the things we go through to keep from showing up
308      * in sysfs... */
309     subsystem_init(&class_obj_subsys);
310     if (!class_obj_subsys.kobj.parent)
311         class_obj_subsys.kobj.parent = &class_obj_subsys.kobj;
312     return 0;
313 }
314 
315 EXPORT_SYMBOL_GPL(class_create_file);
316 EXPORT_SYMBOL_GPL(class_remove_file);
317 EXPORT_SYMBOL_GPL(class_register);
318 EXPORT_SYMBOL_GPL(class_unregister);
319 EXPORT_SYMBOL_GPL(class_create);
320 EXPORT_SYMBOL_GPL(class_destroy);
321 
322 EXPORT_SYMBOL_GPL(class_device_register);
323 EXPORT_SYMBOL_GPL(class_device_unregister);
324 EXPORT_SYMBOL_GPL(class_device_initialize);
325 EXPORT_SYMBOL_GPL(class_device_add);
326 EXPORT_SYMBOL_GPL(class_device_del);
327 EXPORT_SYMBOL_GPL(class_device_get);
328 EXPORT_SYMBOL_GPL(class_device_put);
329 EXPORT_SYMBOL_GPL(class_device_create);
330 EXPORT_SYMBOL_GPL(class_device_destroy);
331 EXPORT_SYMBOL_GPL(class_device_create_file);
332 EXPORT_SYMBOL_GPL(class_device_remove_file);
333 EXPORT_SYMBOL_GPL(class_device_create_bin_file);
334 EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
335 
336 EXPORT_SYMBOL_GPL(class_interface_register);
337 EXPORT_SYMBOL_GPL(class_interface_unregister);

 

转载于:https://www.cnblogs.com/hackfun/p/5832371.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值