总线
Linux设备模型总线、设备和驱动
1.总线
总线使用结构structbus_type描述,这个结构类型定义在include/linux/device.h中
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};
使用bus_register和bus_unregister向系统注册和注销一条总线,在看这两个函数之前,先看structbus_type_private结构,这个结构类型定义在drivers/base/base.h中
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};
总线有两个链表,一个是设备的链表,一个是驱动的链表,就是这里的klist_devices和
klist_drivers。先看总线的注册函数bus_register
871/**
872 * bus_register - register a bus with the system.
873 * @bus: bus.
874 *
875 * Once we have that, we registered the bus with the kobject
876 * infrastructure, then register the children subsystems it has:
877 * the devices and drivers that belong to the bus.
878 */
879int bus_register(struct bus_type *bus)
880{
881 int retval;
882 struct bus_type_private *priv;
883
884 priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
885 if (!priv)
886 return -ENOMEM;
887
888 priv->bus = bus;
889 bus->p = priv;
890
891 BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
892
893 retval = kobject_set_name(&priv->subsys.kobj, "%s",bus->name);
894 if (retval)
895 goto out;
896
897 priv->subsys.kobj.kset = bus_kset;
898 priv->subsys.kobj.ktype = &bus_ktype;
899 priv->drivers_autoprobe = 1;
900
901 retval = kset_register(&priv->subsys);
902 if (retval)
903 goto out;
904
905 retval = bus_create_file(bus, &bus_attr_uevent);
906 if (retval)
907 goto bus_uevent_fail;
908
909 priv->devices_kset = kset_create_and_add("devices",NULL,
910 &priv->subsys.kobj);
911 if (!priv->devices_kset) {
912 retval = -ENOMEM;
913 goto bus_devices_fail;
914 }
915
916 priv->drivers_kset = kset_create_and_add("drivers",NULL,
917 &priv->subsys.kobj);
918 if (!priv->drivers_kset) {
919 retval = -ENOMEM;
920 goto bus_drivers_fail;
921 }
922
923 klist_init(&priv->klist_devices, klist_devices_get,klist_devices_put);
924 klist_init(&priv->klist_drivers, NULL, NULL);
925
926 retval = add_probe_files(bus);
927 if (retval)
928 goto bus_probe_files_fail;
929
930 retval = bus_add_attrs(bus);
931 if (retval)
932 goto bus_attrs_fail;
933
934 pr_debug("bus: '%s': registered\n", bus->name);
935 return 0;
936
937bus_attrs_fail:
938 remove_probe_files(bus);
939bus_probe_files_fail:
940 kset_unregister(bus->p->drivers_kset);
941bus_drivers_fail:
942 kset_unregister(bus->p->devices_kset);
943bus_devices_fail:
944 bus_remove_file(bus, &bus_attr_uevent);
945bus_uevent_fail:
946 kset_unregister(&bus->p->subsys);
947 kfree(bus->p);
948out:
949 bus->p = NULL;
950 return retval;
951}
952EXPORT_SYMBOL_GPL(bus_register);
在这里我们只关注总线注册时初始化了两个链表,一个是设备链表,另一是驱动链表。至于kobject,kset以及sysfs文件系统是如何建立起来的,将在以后介绍。这里只需要理解总线、设备和驱动它们三者的关系,设备是如何绑定一款驱动的。在这里,我想说的是,如果你什么都想弄懂,也许到头来你什么也没有弄懂。
总线注销函数bus_unregister
954/**
955 * bus_unregister - remove a bus from the system
956 * @bus: bus.
957 *
958 * Unregister the child subsystems and the bus itself.
959 * Finally, we call bus_put() to release the refcount
960 */
961void bus_unregister(struct bus_type *bus)
962{
963 pr_debug("bus: '%s': unregistering\n", bus->name);
964 bus_remove_attrs(bus);
965 remove_probe_files(bus);
966 kset_unregister(bus->p->drivers_kset);
967 kset_unregister(bus->p->devices_kset);
968 bus_remove_file(bus, &bus_attr_uevent);
969 kset_unregister(&bus->p->subsys);
970 kfree(bus->p);
971 bus->p = NULL;
972}
973EXPORT_SYMBOL_GPL(bus_unregister);