作者:刘昊昱
博客:http://blog.csdn.net/liuhaoyutz
内核版本:2.6.36
前面我们分析了Linux设备模型中kobject、kset以及ktype的使用,它们是设备模型的最基础部分,在其上有更高级一层的bus、device和driver。在这一篇文章中,我们来看一下bus的用法。
一、相关数据结构
首先,我们列出本文涉及的相关数据结构。
51struct bus_type { 52 const char *name; 53 struct bus_attribute *bus_attrs; 54 struct device_attribute *dev_attrs; 55 struct driver_attribute *drv_attrs; 56 57 int (*match)(struct device *dev, struct device_driver *drv); 58 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 59 int (*probe)(struct device *dev); 60 int (*remove)(struct device *dev); 61 void (*shutdown)(struct device *dev); 62 63 int (*suspend)(struct device *dev, pm_message_t state); 64 int (*resume)(struct device *dev); 65 66 const struct dev_pm_ops *pm; 67 68 struct bus_type_private *p; 69}; 38struct bus_attribute { 39 struct attribute attr; 40 ssize_t (*show)(struct bus_type *bus, char *buf); 41 ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count); 42}; 336/* interface for exporting device attributes */ 337struct device_attribute { 338 struct attribute attr; 339 ssize_t (*show)(struct device *dev, struct device_attribute *attr, 340 char *buf); 341 ssize_t (*store)(struct device *dev, struct device_attribute *attr, 342 const char *buf, size_t count); 343}; 162struct driver_attribute { 163 struct attribute attr; 164 ssize_t (*show)(struct device_driver *driver, char *buf); 165 ssize_t (*store)(struct device_driver *driver, const char *buf, 166 size_t count); 167}; 2/** 3 * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. 4 * 5 * @subsys - the struct kset that defines this bus. This is the main kobject 6 * @drivers_kset - the list of drivers associated with this bus 7 * @devices_kset - the list of devices associated with this bus 8 * @klist_devices - the klist to iterate over the @devices_kset 9 * @klist_drivers - the klist to iterate over the @drivers_kset 10 * @bus_notifier - the bus notifier list for anything that cares about things 11 * on this bus. 12 * @bus - pointer back to the struct bus_type that this structure is associated 13 * with. 14 * 15 * This structure is the one that is the actual kobject allowing struct 16 * bus_type to be statically allocated safely. Nothing outside of the driver 17 * core should ever touch these fields. 18 */ 19struct bus_type_private { 20 struct kset subsys; 21 struct kset *drivers_kset; 22 struct kset *devices_kset; 23 struct klist klist_devices; 24 struct klist klist_drivers; 25 struct blocking_notifier_head bus_notifier; 26 unsigned int drivers_autoprobe:1; 27 struct bus_type *bus; 28}; 406struct device { 407 struct device *parent; 408 409 struct device_private *p; 410 411 struct kobject kobj; 412 const char *init_name; /* initial name of the device */ 413 struct device_type *type; 414 415 struct mutex mutex; /* mutex to synchronize calls to 416 * its driver. 417 */ 418 419 struct bus_type *bus; /* type of bus device is on */ 420 struct device_driver *driver; /* which driver has allocated this 421 device */ 422 void *platform_data; /* Platform specific data, device 423 core doesn't touch it */ 424 struct dev_pm_info power; 425 426#ifdef CONFIG_NUMA 427 int numa_node; /* NUMA node this device is close to */ 428#endif 429 u64 *dma_mask; /* dma mask (if dma'able device) */ 430 u64 coherent_dma_mask;/* Like dma_mask, but for 431 alloc_coherent mappings as 432 not all hardware supports 433 64 bit addresses for consistent 434 allocations such descriptors. */ 435 436 struct device_dma_parameters *dma_parms; 437 438 struct list_head dma_pools; /* dma pools (if dma'ble) */ 439 440 struct dma_coherent_mem *dma_mem; /* internal for coherent mem 441 override */ 442 /* arch specific additions */ 443 struct dev_archdata archdata; 444#ifdef CONFIG_OF 445 struct device_node *of_node; 446#endif 447 448 dev_t devt; /* dev_t, creates the sysfs "dev" */ 449 450 spinlock_t devres_lock; 451 struct list_head devres_head; 452 453 struct klist_node knode_class; 454 struct class *class; 455 const struct attribute_group **groups; /* optional groups */ 456 457 void (*release)(struct device *dev); 458}; 123struct device_driver { 124 const char *name; 125 struct bus_type *bus; 126 127 struct module *owner; 128 const char *mod_name; /* used for built-in modules */ 129 130 bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ 131 132#if defined(CONFIG_OF) 133 const struct of_device_id *of_match_table; 134#endif 135 136 int (*probe) (struct device *dev); 137 int (*remove) (struct device *dev); 138 void (*shutdown) (struct device *dev); 139 int (*suspend) (struct device *dev, pm_message_t state); 140 int (*resume) (struct device *dev); 141 const struct attribute_group **groups; 142 143 const struct dev_pm_ops *pm; 144 145 struct driver_private *p; 146};
二、注册bus
bus的注册接口为bus_register,该函数代码如下:
872/** 873 * bus_register - register a bus with the system. 874 * @bus: bus. 875 * 876 * Once we have that, we registered the bus with the kobject 877 * infrastructure, then register the children subsystems it has: 878 * the devices and drivers that belong to the bus. 879 */ 880int bus_register(struct bus_type *bus) 881{ 882 int retval; 883 struct bus_type_private *priv; 884 885 priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); 886 if (!priv) 887 return -ENOMEM; 888 889 priv->bus = bus; 890 bus->p = priv; 891 892 BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); 893 894 retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); 895 if (retval) 896 goto out; 897 898 priv->subsys.kobj.kset = bus_kset; 899 priv->subsys.kobj.ktype = &bus_ktype; 900 priv->drivers_autoprobe = 1; 901 902 retval = kset_register(&priv->subsys); 903 if (retval) 904 goto out; 905 906 retval = bus_create_file(bus, &bus_attr_uevent); 907 if (retval) 908 goto bus_uevent_fail; 909 910 priv->devices_kset = kset_create_and_add("devices", NULL, 911 &priv->subsys.kobj); 912 if (!priv->devices_kset) { 913 retval = -ENOMEM; 914 goto bus_devices_fail; 915 } 916 917 priv->drivers_kset = kset_create_and_add("drivers", NULL, 918 &priv->subsys.kobj); 919 if (!priv->drivers_kset) { 920 retval = -ENOMEM; 921 goto bus_drivers_fail; 922 } 923 924 klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); 925 klist_init(&priv->klist_drivers, NULL, NULL); 926 927 retval = add_probe_files(bus); 928 if (retval) 929 goto bus_probe_files_fail; 930 931 retval = bus_add_attrs(bus); 932 if (retval) 933 goto bus_attrs_fail; 934 935 pr_debug("bus: '%s': registered\n", bus->name); 936 return 0; 937 938bus_attrs_fail: 939 remove_probe_files(bus); 940bus_probe_files_fail: 941 kset_unregister(bus->p->drivers_kset); 942bus_drivers_fail: 943 kset_unregister(bus->p->devices_kset); 944bus_devices_fail: 945 bus_remove_file(bus, &bus_attr_uevent); 946bus_uevent_fail: 947 kset_unregister(&bus->p->subsys); 948out: 949 kfree(bus->p); 950 bus->p = NULL; 951 return retval; 952}
894行,设置priv->subsys.kobj的名字,priv->subsys是一个kset,代表这个bus。bus是通过一个kset来表示的,而device和device_driver都是通过一个kobject来表示的,由此也可以看出他们的不同。
898行,设置priv->subsys.kobj.kset为bus_kset;
在drivers/base/bus.c文件中,162行有如下定义:
162static struct kset *bus_kset;
同时,在buses_init函数中对bus_kset进行了初始化:
1054int __init buses_init(void) 1055{ 1056 bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); 1057 if (!bus_kset) 1058 return -ENOMEM; 1059 return 0; 1060}
1056行,创建一个名为bus的kset,赋值给bus_kset,对应/sys/bus目录。所有的bus都属性bus_set,即所有的bus对应的sys系统目录都放在/sys/bus目录下。
bus_kset对应的kset_uevent_ops是bus_uevent_ops,其定义如下:
158static const struct kset_uevent_ops bus_uevent_ops = { 159 .filter = bus_uevent_filter, 160};
bus_uevent_filter函数定义如下:
149static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) 150{ 151 struct kobj_type *ktype = get_ktype(kobj); 152 153 if (ktype == &bus_ktype) 154 return 1; 155 return 0; 156}
回忆一下上一篇博客《Linux设备模型分析之kset》介绍的内容,如果kset_uevent_ops.filter函数返回0,将不会处理uevent事件。在bus_uevent_filter函数中,如果kobj->ktype不是bus_ktype,则返回0,即不处理Uevent事件。
bus_ktype定义如下:
145static struct kobj_type bus_ktype = { 146 .sysfs_ops = &bus_sysfs_ops, 147};
bus_sysfs_ops定义如下:
119static const struct sysfs_ops bus_sysfs_ops = { 120 .show = bus_attr_show, 121 .store = bus_attr_store, 122};
bus_attr_show和bus_attr_store函数定义如下:
95static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, 96 char *buf) 97{ 98 struct bus_attribute *bus_attr = to_bus_attr(attr); 99 struct bus_type_private *bus_priv = to_bus(kobj); 100 ssize_t ret = 0; 101 102 if (bus_attr->show) 103 ret = bus_attr->show(bus_priv->bus, buf); 104 return ret; 105} 106 107static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, 108 const char *buf, size_t count) 109{ 110 struct bus_attribute *bus_attr = to_bus_attr(attr); 111 struct bus_type_private *bus_priv = to_bus(kobj); 112 ssize_t ret = 0; 113 114 if (bus_attr->store) 115 ret = bus_attr->store(bus_priv->bus, buf, count); 116 return ret; 117}
bus_attribute结构体定义如下:
38struct bus_attribute { 39 struct attribute attr; 40 ssize_t (*show)(struct bus_type *bus, char *buf); 41 ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count); 42};
回到bus_register函数:
899行,设置priv->subsys.kobj.ktype为 &bus_ktype;回忆一下前面的文章《Linux设备模型分析之kobject》,对kobject属性的读写操作将调用kobject.ktype定义的sysfs_ops函数集指定的show和store函数。所以对bus属性文件的读写操作将会调用bus_ktyp.sysfs_ops指定的bus_attr_show和bus_attr_store函数,这两个函数我们前面已经分析过了,他们将回溯到bus_attr->show和bus_attr->store函数。
900行,设置priv->drivers_autoprobe为1;
902行,调用kset_register注册priv->subsys,即注册代表bus的kset。注册完成后,将在/sys/bus目录下出现对应该bus的目录。
906行,调用bus_create_file(bus, &bus_attr_uevent),创建uevent属性文件,该函数定义如下:
124int bus_create_file(struct bus_type *bus, struct bus_attribute *attr) 125{ 126 int error; 127 if (bus_get(bus)) { 128 error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr); 129 bus_put(bus); 130 } else 131 error = -EINVAL; 132 return error; 133}
128行,调用sysfs_create_file函数创建了bus_attribute对应的属性文件。
先来看bus_attr_uevent的定义,它是通过宏BUS_ATTR生成的:
870static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
BUS_ATTR定义如下:
44#define BUS_ATTR(_name, _mode, _show, _store) \ 45struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
__ATTR定义如下:
70#define __ATTR(_name,_mode,_show,_store) { \ 71 .attr = {.name = __stringify(_name), .mode = _mode }, \ 72 .show = _show, \ 73 .store = _store, \ 74}
从bus_attr_uevent的定义可以看出,对应的uevent属性只有store接口,没有实现show接口。store接口函数bus_uevent_store定义如下:
861static ssize_t bus_uevent_store(struct bus_type *bus, 862 const char *buf, size_t count) 863{ 864 enum kobject_action action; 865 866 if (kobject_action_type(buf, count, &action) == 0) 867 kobject_uevent(&bus->p->subsys.kobj, action); 868 return count; 869}
回到bus_register函数:
910 - 915行,创建名为devices的kset,其parent是priv->subsys.kobj,即在相应bus目录下创建一个devices目录。
917 - 922行,创建名为drivers的kset,其parent是priv->subsys.kobj,即在相应bus目录下创建一个drivers目录。
924行,初始化priv->klist_devices,即devices链表。
925行,初始化priv->klist_drivers,即drivers链表。
927行,调用add_probe_files(bus)函数创建drivers_probe和drivers_autoprobe两个属性文件,该函数定义如下:
606static int add_probe_files(struct bus_type *bus) 607{ 608 int retval; 609 610 retval = bus_create_file(bus, &bus_attr_drivers_probe); 611 if (retval) 612 goto out; 613 614 retval = bus_create_file(bus, &bus_attr_drivers_autoprobe); 615 if (retval) 616 bus_remove_file(bus, &bus_attr_drivers_probe); 617out: 618 return retval; 619}
bus_create_file函数我们前面已经分析过了,610行,创建drivers_probe属性文件,614行,创建drivers_autoprobe属性文件。其对应的bus_attribute定义如下:
602static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe); 603static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO, 604 show_drivers_autoprobe, store_drivers_autoprobe);
属性文件对应的操作函数定义如下:
225static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) 226{ 227 return sprintf(buf, "%d\n", bus->p->drivers_autoprobe); 228} 229 230static ssize_t store_drivers_autoprobe(struct bus_type *bus, 231 const char *buf, size_t count) 232{ 233 if (buf[0] == '0') 234 bus->p->drivers_autoprobe = 0; 235 else 236 bus->p->drivers_autoprobe = 1; 237 return count; 238} 239 240static ssize_t store_drivers_probe(struct bus_type *bus, 241 const char *buf, size_t count) 242{ 243 struct device *dev; 244 245 dev = bus_find_device_by_name(bus, NULL, buf); 246 if (!dev) 247 return -ENODEV; 248 if (bus_rescan_devices_helper(dev, NULL) != 0) 249 return -EINVAL; 250 return count; 251}
show_drivers_autoprobe函数用于显示bus->p->drivers_autoprobe的值。
store_drivers_autoprobe函数根据用户的要求设置bus->p->drivers_autoprobe的值。
store_drivers_probe函数245行调用bus_find_device_by_name 在bus上查找用户指定的device,并且在248行调用bus_rescan_devices_helper函数查找匹配device_driver.
回到bus_register函数:
931行,调用bus_add_attrs函数创建bus默认属性文件,该函数定义如下:
810/** 811 * bus_add_attrs - Add default attributes for this bus. 812 * @bus: Bus that has just been registered. 813 */ 814 815static int bus_add_attrs(struct bus_type *bus) 816{ 817 int error = 0; 818 int i; 819 820 if (bus->bus_attrs) { 821 for (i = 0; attr_name(bus->bus_attrs[i]); i++) { 822 error = bus_create_file(bus, &bus->bus_attrs[i]); 823 if (error) 824 goto err; 825 } 826 } 827done: 828 return error; 829err: 830 while (--i >= 0) 831 bus_remove_file(bus, &bus->bus_attrs[i]); 832 goto done; 833}
820 - 826行,如果bus->bus_attrs指定了bus的默认属性,则创建对应的属性文件。