linux设备模型分析之bus_register()

来源:互联网 发布:淘宝粉星便利店靠谱么 编辑:程序博客网 时间:2024/05/01 11:01

bus_register()大致分析:

struct bus_type mini_bus_type ={.name = "mini",.match = mini_match};static int __init test_init(void){return bus_register(&mini_bus_type);}bus_register:工作就是完成bus_type_private的初始化.创建 注册的这条总线需要的目录文件.             在这条总线目录下创建/device  /driver 目录             初始化这条总线上的设备链表:struct klist klist_devices;             初始化这条总线上的驱动链表:struct klist klist_drivers;             int bus_register(struct bus_type *bus){int retval;struct bus_type_private *priv;//是上面mini_bus_type的成员.priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);if (!priv)return -ENOMEM;priv->bus = bus;//struct bus_type_private *p;所指向的内容动态分配.bus->p = priv;//p关联到mini_bus_typeBLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);//kobject对应一个目录,这个目录就是我们看到的总线名字/bus/miniif (retval)goto out;//bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);priv->subsys.kobj.kset = bus_kset;//mini目录在bus下,即/bus/mini:初始化kset的成员kobject,为kset_register()做准备.   priv->subsys.kobj.ktype = &bus_ktype;//static struct kobj_type bus_ktype = {    .sysfs_ops = &bus_sysfs_ops, };    priv->drivers_autoprobe = 1;//设置该标志,当有driver注册时,会自动匹配devices上的设备并用probe初始化,//当有device注册时,也同样找到driver并会初始化  //int bus_add_driver(struct device_driver *drv)//if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); }                                                                                       retval = kset_register(&priv->subsys);//注册kset,创建目录结构,以及层次关系  生成/bus/mini                               if (retval)                                                                                                                           goto out;                                 //kset_register(&priv->subsys);//kobject_add_internal(&k->kobj);//error = create_dir(kobj); //error = sysfs_create_dir(kobj);//&priv->subsys---->mini_bus_type->p->subsys  //priv->subsys.kobj.kset = bus_kset;                      retval = bus_create_file(bus, &bus_attr_uevent);//mini目录下生成bus_attr_uevent属性文件 if (retval)goto bus_uevent_fail;priv->devices_kset = kset_create_and_add("devices", NULL,//在mini下面创建一个mini/device,是mini这条总线的device的根目录. &priv->subsys.kobj);//为什么在mini目录下?  (device这个目录:kset->kobj) kset->kobj.parent = &priv->subsys.kobj;//在某个目录下:kset->kob.kset =  x    这个目录在x目录下,这个目录下面“还可有”目录//             kobj.parent =     y这个目录在y目录下,这个目录下面“没有”有目录if (!priv->devices_kset) {retval = -ENOMEM;goto bus_devices_fail;}priv->drivers_kset = kset_create_and_add("drivers", NULL,//在mini下面创建一个mini/driver,是mini这条总线的driver的根目录. &priv->subsys.kobj);//struct kset *drivers_kset  指针.  if (!priv->drivers_kset) {retval = -ENOMEM;goto bus_drivers_fail;}klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);//初始化 mini_bus_type->p->klist_devices  就是初始化device的list_headklist_init(&priv->klist_drivers, NULL, NULL);// 就是初始化driver的list_head//device,driver注册都挂在对应的链表上.retval = add_probe_files(bus);//创建文件if (retval)goto bus_probe_files_fail;retval = bus_add_attrs(bus);if (retval)goto bus_attrs_fail;pr_debug("bus: '%s': registered\n", bus->name);return 0;bus_attrs_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;}struct bus_type {const char*name;//总线名称struct bus_attribute*bus_attrs;//总线属性(设备节点和这个有关系么?)struct device_attribute*dev_attrs;//设备属性   struct driver_attribute*drv_attrs;//驱动属性int (*match)(struct device *dev, struct device_driver *drv);//用于匹配总线下的dev和driverint (*uevent)(struct device *dev, struct kobj_uevent_env *env);//用于总线环境变量的添加int (*probe)(struct device *dev);//总线和驱动匹配成功调用,platform不是设备和驱动匹配才调用么?没搞清楚.int (*remove)(struct device *dev);void (*shutdown)(struct device *dev);//关机int (*suspend)(struct device *dev, pm_message_t state);//挂起int (*resume)(struct device *dev);const struct dev_pm_ops *pm;//电源管理.struct bus_type_private *p;//将bus device sysfs关联起来,怎么关联的不明白呀};struct bus_type_private {struct kset subsys;//sysfsstruct kset *drivers_kset;//bus目录下的 drvier子目录struct kset *devices_kset;//bus目录下的 device子目录struct klist klist_devices;//bus目录下的设备列表struct klist klist_drivers;//bus目录下的驱动列表struct blocking_notifier_head bus_notifier;unsigned int drivers_autoprobe:1;struct bus_type *bus;};struct bus_attribute {struct attributeattr;ssize_t (*show)(struct bus_type *bus, char *buf);ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);};#define BUS_ATTR(_name, _mode, _show, _store)\struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)#define __ATTR(_name,_mode,_show,_store) { \.attr = {.name = __stringify(_name), .mode = _mode },\.show= _show,\.store= _store,\}#define __stringify_1(x...)#x#define __stringify(x...)__stringify_1(x)struct klist {spinlock_tk_lock;struct list_headk_list;void(*get)(struct klist_node *);void(*put)(struct klist_node *);} __attribute__ ((aligned (sizeof(void *))));


                                             
0 0