linux设备驱动(15)type详解
在linux设备驱动中总是见到type的结构体变量,一般是嵌入其他数据结构体中。本节将一 一介绍下。
bus_type是bus总结对应的结构体变量,不属于本节所叙述范围。
1 device_type
定义位于:include\linux\device.h,devices_type嵌入结构体device中
1 /* 2 * The type of device, "struct device" is embedded in. A class 3 * or bus can contain devices of different types 4 * like "partitions" and "disks", "mouse" and "event". 5 * This identifies the device type and carries type-specific 6 * information, equivalent to the kobj_type of a kobject. 7 * If "name" is specified, the uevent will contain it in 8 * the DEVTYPE variable. 9 */ 10 struct device_type { 11 const char *name; 12 const struct attribute_group **groups; 13 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 14 char *(*devnode)(struct device *dev, umode_t *mode, 15 kuid_t *uid, kgid_t *gid); 16 void (*release)(struct device *dev); 17 18 const struct dev_pm_ops *pm; 19 };
device_add_attrs()中device_add_groups将device_type加入group中
1 static int device_add_attrs(struct device *dev) 2 { 3 struct class *class = dev->class; 4 const struct device_type *type = dev->type; 5 int error; 6 7 if (class) { 8 error = device_add_attributes(dev, class->dev_attrs); 9 if (error) 10 return error; 11 error = device_add_bin_attributes(dev, class->dev_bin_attrs); 12 if (error) 13 goto err_remove_class_attrs; 14 } 15 16 if (type) { 17 error = device_add_groups(dev, type->groups); 18 if (error) 19 goto err_remove_class_bin_attrs; 20 } 21 22 error = device_add_groups(dev, dev->groups); 23 if (error) 24 goto err_remove_type_groups; 25 26 return 0; 27 28 err_remove_type_groups: 29 if (type) 30 device_remove_groups(dev, type->groups); 31 err_remove_class_bin_attrs: 32 if (class) 33 device_remove_bin_attributes(dev, class->dev_bin_attrs); 34 err_remove_class_attrs: 35 if (class) 36 device_remove_attributes(dev, class->dev_attrs); 37 38 return error; 39 }
2.kobject_type
定义位于:include\linux\kobject.h,kobject_type嵌入结构体kobject中
1 struct kobj_type { 2 void (*release)(struct kobject *kobj); 3 const struct sysfs_ops *sysfs_ops; 4 struct attribute **default_attrs; 5 const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj); 6 const void *(*namespace)(struct kobject *kobj); 7 };
kobject_init()会初始化kobject中的kobj_type
1 void kobject_init(struct kobject *kobj, struct kobj_type *ktype) 2 { 3 char *err_str; 4 5 if (!kobj) { 6 err_str = "invalid kobject pointer!"; 7 goto error; 8 } 9 if (!ktype) { 10 err_str = "must have a ktype to be initialized properly!\n"; 11 goto error; 12 } 13 if (kobj->state_initialized) { 14 /* do not error out as sometimes we can recover */ 15 printk(KERN_ERR "kobject (%p): tried to init an initialized " 16 "object, something is seriously wrong.\n", kobj); 17 dump_stack(); 18 } 19 20 kobject_init_internal(kobj); 21 kobj->ktype = ktype; 22 return; 23 24 error: 25 printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str); 26 dump_stack(); 27 }
3. kset_type
实际上同kobj_type
定义如下:
1 static struct kobj_type kset_ktype = { 2 .sysfs_ops = &kobj_sysfs_ops, 3 .release = kset_release, 4 };
kset_create时会用kset_type初始化kset中kobj的kobj_type
1 static struct kset *kset_create(const char *name, 2 const struct kset_uevent_ops *uevent_ops, 3 struct kobject *parent_kobj) 4 { 5 struct kset *kset; 6 int retval; 7 8 kset = kzalloc(sizeof(*kset), GFP_KERNEL); 9 if (!kset) 10 return NULL; 11 retval = kobject_set_name(&kset->kobj, name); 12 if (retval) { 13 kfree(kset); 14 return NULL; 15 } 16 kset->uevent_ops = uevent_ops; 17 kset->kobj.parent = parent_kobj; 18 19 /* 20 * The kobject of this kset will have a type of kset_ktype and belong to 21 * no kset itself. That way we can properly free it when it is 22 * finished being used. 23 */ 24 kset->kobj.ktype = &kset_ktype; 25 kset->kobj.kset = NULL; 26 27 return kset; 28 }
其他待续。。。
行胜于言,自强不息。