For many devices, there is only one PCI domain. In this case, they call pci_domain_scan_bus. It calls pci_scan_bus for all devfns (0x00-0xff) on link[0] starting with bus number 0. pci_scan_bus scans a bus from min_devfn-max_devfn, and assigns bus numbers for any bridges it finds. It starts by removing all the children of the bus, and putting them in a list of old_devices. Then, for each devfn it searches the list (pci_get_dev) and probes the bus (pci_probe_dev.) There are 4 possibilities here: 00 not in the tree and not responding, 01 not in the tree and responding, 10 in the tree and not responding, and 11 in the tree and responding. 00 - The device is not there; skip it and all functions if it is function 0. 01 - The device responds but was not specified in the dts. pci_probe_dev creates a new device with dtsname dynamic- and fills in the device structure. 10 - The device is in the tree, but doesn't respond to probing. The device is marked as disabled, and a warning message is issued. 11 - The device is in the tree and responds to probing. pci_probe_dev uses the device struct returned from pci_get_dev, and fills in the information. Now that the devices have been probed from min_devfn to max_devfn, any leftover children in the old_devices list are printed with a warning. At this point all of the children on the bus have been found and assigned device structures. Each child that has a dev_phase3_scan method (bridges) is then scanned and passed the current bus number (curr_bus) to number subordinate buses. The return value for the function is the curr_bus number, which is the highest bus number that has been assigned so far. Bridge Scanning The default function for scanning subordinate pci busses (phase3_scan) is pci_scan_bridge. It takes a device and the curent bus number as parameters. It simply calls do_pci_scan_bridge with pci_scan_bus as a parameter. do_pci_scan_bridge takes a scanning function as a parameter so that devices can use the basic functionality with a custom bus scanning function, if needed. do_pci_scan_bridge gets the bus to be enumerated from dev->link[0] and sets dev->links to 1. ** I'm not sure why it sets this to one here! ** Then it sets the starting child bus number (bus->secondary) to the next bus number, and the and the ending child bus number (bus->subordinate) to 0xff so that all of them get enumerated. Note that this is only in the bus structure, not in hardware yet. Next the device is disabled and the status bits are cleared so that the devices do not generate or respond to traffic while they are being configured. Now the bus numbers are written to hardware, and the do_scan_bus function is called to find the child devices of the bridge. After the subordinate buses are scanned, the true value for the maximum bus number of the child (bus->subordinate) is known, so it is set in hardware and the device is returned to its previous enable state. Information in the device struct set during probing pci_probe_dev initializes many fields in the device struct based on information that the hardware returns. It is passed a pointer to the device struct from the dts tree, or NULL if this devfn had no matching device. If there was no matching device but a device responds at that devfn, a new one is created as a child of the currently scanned bus. Otherwise no child is added, and NULL is returned. If there was a matching device, its magic enable sequence is called if defined. Some devices require initialization before they will respond to PCI configuration cycles. They will not be found if there is not a matching device in the dts. If the device does not respond, it is disabled and the function returns. Responding devices have their configuration space information (header type, class, status, revision, etc.) saved in the device structure. They also get pci_ops set if they were not set in the dts. set_pci_ops uses the information from the device header to decide what "driver" (set of functions implemented by the device) to use. There are three ways the device can get a driver: 1. It has one assigned in the dts 2. It matches a driver in the list all_device_operations (find_device_operations) 3. It gets a default driver based on if it is a bridge, normal, or cardbus device. If it is a bridge, get_pci_bridge_ops assigns the ops based on the values of CONFIG__PLUGIN_SUPPORT.