bus_type结构体定义
struct bus_type {
const char *name;
const char *dev_name;
struct device *dev_root;
struct device_attribute *dev_attrs; /* use dev_groups instead */
const struct attribute_group **bus_groups;//总线属性
const struct attribute_group **dev_groups;//设备属性
const struct attribute_group **drv_groups;//驱动属性
int (*match)(struct device *dev, struct device_driver *drv);驱动与设备是否匹配的检测函数
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*online)(struct device *dev);
int (*offline)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
const struct dev_pm_ops *pm;
const struct iommu_ops *iommu_ops;
struct subsys_private *p;//和kobject有关包含一个设备链表(struct klist klist_devices)和一个驱动链表( struct klist klist_drivers)
struct lock_class_key lock_key;
};
其中涉及到和kobject和sysfs相关的 subsys_private结构体定义
struct subsys_private {
struct kset subsys;//bus_kset,class_kset
struct kset *devices_kset;//devices_kset,sys/devices
struct list_head interfaces;
struct mutex mutex;
struct kset *drivers_kset;//drivers_kset,sys/driver
struct klist klist_devices;;/*挂接在该总线的设备链表头*/
struct klist klist_drivers;/*与该总线相关的驱动程序链表头*/
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1;
struct bus_type *bus;
struct kset glue_dirs;
struct class *class;
};
总线初始化做了哪些事情,创建了2个目录,sys/bus,sys/devices/system
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);//sys/bus
if (!bus_kset)
return -ENOMEM;
system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);//sys/devices/sytem
if (!system_kset)
return -ENOMEM;
return 0;
}
总线如何注册到系统中,注册本质即init and add ,比如device_register,driver_register
bus_register过程代码注释
**
* bus_register - register a driver-core subsystem
* @bus: bus to register
*
* Once we have that, we register the bus with the kobject
* infrastructure, then register the children subsystems it has:
* the devices and drivers that belong to the subsystem.
*/
int bus_register(struct bus_type *bus)
{
int retval;
struct subsys_private *priv;//bus private
struct lock_class_key *key = &bus->lock_key;
priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);//priv alloc
if (!priv)
return -ENOMEM;
priv->bus = bus;//fill priv
bus->p = priv;//指针赋值,priv和bus互指
BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);//设置新的总线名字
if (retval)
goto out;
priv->subsys.kobj.kset = bus_kset;// bus 放到总线集合下面
priv->subsys.kobj.ktype = &bus_ktype;//都是总线类型
priv->drivers_autoprobe = 1;//fill priv
retval = kset_register(&priv->subsys);//生成一个新的总线目录,在bus下面的都是kset
if (retval)
goto out;
retval = bus_create_file(bus, &bus_attr_uevent);//在新生成的总线目录下生成总线属性文件
if (retval)
goto bus_uevent_fail;
priv->devices_kset = kset_create_and_add("devices", NULL,
&priv->subsys.kobj);//sys/bus/xx/devices
if (!priv->devices_kset) {
retval = -ENOMEM;
goto bus_devices_fail;
}
priv->drivers_kset = kset_create_and_add("drivers", NULL,
&priv->subsys.kobj);//sys/bus/xx/drivers
if (!priv->drivers_kset) {
retval = -ENOMEM;
goto bus_drivers_fail;
}
INIT_LIST_HEAD(&priv->interfaces);
__mutex_init(&priv->mutex, "subsys mutex", key);
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);//链表头初始化
klist_init(&priv->klist_drivers, NULL, NULL);//driver头初始化
retval = add_probe_files(bus);
if (retval)
goto bus_probe_files_fail;
retval = bus_add_groups(bus, bus->bus_groups);//创建属性组里面的文件
if (retval)
goto bus_groups_fail;
pr_debug("bus: '%s': registered\n", bus->name);
return 0;
bus_groups_fail:
remove_probe_files(bus);
bus_probe_files_fail:
kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
kset_unregister(bus->p->devices_kset);
bus_devices_fail:
bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
kset_unregister(&bus->p->subsys);
out:
kfree(bus->p);
bus->p = NULL;
return retval;
}