註冊匯流排。
來自:dirvers/base/bus.c:
int bus_register(struct bus_type
*bus)
{
int retval;
struct bus_type_private *priv;
priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
if
(!priv)
return -ENOMEM;
priv->bus = bus;
//bus_type的私人成員
bus->p = priv;
BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
retval =
kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
//設定匯流排子系統kobject的名稱
if (retval)
goto out;
priv->subsys.kobj.kset = bus_kset; //設定匯流排子系統kobject的所屬集合,其實對應sys/bus/
目錄
priv->subsys.kobj.ktype = &bus_ktype;
//kobj_type類型變數,和sysfs有關
priv->drivers_autoprobe = 1;
//這個變數如果置位,則會執行一個函數,在驅動註冊會看到它的運用
retval =
kset_register(&priv->subsys); //註冊匯流排子系統,會在sys/bus/ 目錄下產生一個新的匯流排目錄
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); //為該匯流排建立並添加裝置集合
if
(!priv->devices_kset) {
retval = -ENOMEM;
goto
bus_devices_fail;
}
priv->drivers_kset =
kset_create_and_add("drivers", NULL,
&priv->subsys.kobj); //為該匯流排建立並添加驅動集合
if
(!priv->drivers_kset) {
retval = -ENOMEM;
goto
bus_drivers_fail;
}
klist_init(&priv->klist_devices,
klist_devices_get, klist_devices_put); //初始化匯流排裝置鏈表
klist_init(&priv->klist_drivers, NULL,
NULL); //初始化匯流排驅動鏈表
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;
}
感覺怎麼樣,簡單吧,理解起來那是相當的清楚,我認為這就是當初我選擇簡化分析的結果,到這裡,我們可以相當的明白,如果你有一條匯流排要註冊,那麼註冊後,會在sys/bus/目錄下產生你的匯流排目錄名,並且會在你的匯流排目錄下在產生兩個關於裝置和驅動的目錄,顯然,它們記錄了這條匯流排上所有的裝置和驅動。
這裡提一下,可能你會問,這裡也涉及了到sysfs的內容啊,不是產生了目錄嗎,呵呵,這些都是在第一層搞定的,我們不去理會的,我們只是把第二層的sysfs給踢掉了!