目的:對USB作深入學習,在此留下筆記。歡迎討論。
[Linux 3.2] [driver/usb/core/driver.c]
定義:usb_bus_type
- struct bus_type usb_bus_type = {
- .name = "usb",
- .match = usb_device_match,
- .uevent = usb_uevent,
- };
[Linux 3.2] [driver/base/bus.c]
函數:bus_register(struct bus_type *bus)
- /**
- * bus_register - register a bus with the system.
- * @bus: bus.
- *
- * Once we have that, we registered the bus with the kobject
- * infrastructure, then register the children subsystems it has:
- * the devices and drivers that belong to the bus.
- */
- int bus_register(struct bus_type *bus)
- {
- int retval;
- struct subsys_private *priv;
-
- priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->bus = bus;
- bus->p = priv;
-
- 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;
- priv->subsys.kobj.ktype = &bus_ktype;
- priv->drivers_autoprobe = 1;
-
- retval = kset_register(&priv->subsys);
- 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;
- }
- EXPORT_SYMBOL_GPL(bus_register);
bus_register的目的主要是處理Linux設備模型的相關事宜。
此函數的主要作用如下:
1. line 21 : 初始化一個blocking的通知鏈。
2. line 23 ~ 31: 將USB總線加入總線集,並在/sys/bus下面創建usb子目錄。
3. line 35 : 在/sys/bus/usb/下面創建uevent的屬性文件。
4. line 39 ~ 51: 在usb總線子集上面創建devices, drivers兩個子集,同時創建目錄。
5. line 53 ~54 : 初始化兩條鏈表:klist_devices, klist_drivers。
6. line 56 : 添加bus的drivers_probe,drivers_autoprobe屬性文件。(需要CONFIG_HOTPLUG的支持)
7. line 60 : 添加bus的其余屬性文件,對USB來說,沒有。
這些完成之後,可以在/sys/bus下面看到usb目錄,
在USB目錄下面可以看到:
# ls /sys/bus/usb
devices drivers_autoprobe uevent drivers drivers_probe