linux bus_register过程

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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值