PCI 热插拔代码将调用 pci_do_scan_bus() 来遍历所有插槽,看看我们是否找到了设备/网桥并将它们添加到我们的设备树中:
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) {
max = pci_scan_child_bus(bus) //scan bus for all slots and devices in them
pci_bus_add_devices(bus); //add what we find
...
}
struct device 中的字段实际上是在调用 pci_scan_child_bus() 时填充的。这是调用图(有点:)):
pci_scan_child_bus > pci_scan_slot(扫描总线上的插槽)> pci_scan_single_device > pci_device_add > device_initialize。
注意 device_initialize() 是 device_register() 的第一部分。您将看到在调用 device_initialize() 之后,struct device 的字段在 pci_device_add 中填充。您可以在内核源代码的 drivers/pci/probe.c 下找到它。struct pci_dev 也将被填充,稍后将由设备特定的驱动程序使用。
将 kobject 实际添加到设备层次结构中发生在 pci_bus_add_devices 中。这是调用图:
pci_bus_add_devices > pci_bus_add_device > device_add。
如您所见,此调用流程完成了 device_register() 函数的第二部分。
因此,简而言之,device_register() 包括:1. 初始化设备和 2. 添加设备。pci_device_add 执行第 1 步, pci_bus_add_device 执行第 2 步。
感兴趣的文件是:drivers/pci/{pci.c,bus.c,probe.c}