When the realtek8168 Nic is a PCI interface Nic, its driver is a driver instance of the PCI device. Let's take a look at its process.
1. First, the initialization module calls the static inline int pci_register_driver (struct pci_driver * driver) function to register the device driver. The parameter of this function is the struct pci_driver * driver, which corresponds to r8168, which is
Static struct pci_driver rtl8168_pci_driver = {
. Name = modulename,
. Id_table = rtl8168_pci_tbl,
. Probe = rtl8168_init_one,
. Remove = _ devexit_p (rtl8168_remove_one ),
# If linux_version_code> kernel_version (2, 6, 11)
. Shutdown = rtl8168_shutdown,
# Endif
# Ifdef config_pm
. Suspend = rtl8168_suspend,
. Resume = rtl8168_resume,
# Endif
};
This struct defines the devices supported by the driver (rtl8168_pci_tbl) and the probe function (rtl8168_init_one). We will use the following two parts to match the struct and rtl8168_init_one, whether the device is in the system. Check whether the device can match the driver.
2. The pci_register_driver function calls _ pci_register_driver to complete the task, while _ pci_register_driver re-encapsulates the driver to be registered as the PCI bus, that is
Int _ pci_register_driver (struct pci_driver * DRV, struct module * owner)
{
......
DRV-> driver. Bus = & pci_bus_type;
......
DRV-> driver. kobj. ktype = & pci_driver_kobj_type;
......
}
Next, call the device driver model function, mount the driver we want to register to the device queue of the PCI bus, and scan the device queue of the PCI bus, check whether there is a device that can match the driver. This is consistent with the mounting of the USB driver, but the PCI bus is mounted here, and the USB Bus is mounted here. The general process is
Driver_register () --- à bus _ add_driver () ---- à driver _ attach () -- à _ driver_attach () -- à driver _ probe_device () --- à Dev-> bus-> probe (), that is, 2. the probe member function in the pci_bus_type struct in, that is, static int pci_device_probe (struct device * Dev)
3. the parameter Dev of the static int pci_device_probe (struct device * Dev) function traverses the device linked list on the PCI bus for one-to-one matching, because we call _ driver_attach () bus_for_each_dev (DRV-> bus, null, DRV, _ driver_attach );
4. static int pci_device_probe (struct device * Dev) uses two macros to convert to_pci_driver and to_pci_dev to obtain the device and driver to match. Call static int _ pci_device_probe (struct pci_driver * DRV, struct pci_dev * pci_dev) function for matching
5. the _ pci_device_probe function first compares the rtl8168_pci_tbl table in the device driver with the vendorid and productid table obtained from the device to check whether the table is consistent. If the table is consistent, the address of the table is returned, it indicates that the device does not match the driver, and you do not need to continue the following operations and exit directly.
6. if the same device table is found in step 1, it indicates that the device IDs are consistent and further detection is required. Next, we need to call the detection function in our device driver for more specific detection, that is, pci_call_probe (DRV, pci_dev, ID) --- à DRV-> probe (Dev, ID). Here, we start to call the probe function in our device driver.
7. static int _ devinit partition (struct pci_dev * pdev, const struct pci_device_id * ent) is the test function of r8168. It calls rtl8168_init_board (pdev, & Dev, & ioaddr) to complete the detection related to the PCI device driver.
8. static int _ devinit rtl8168_init_board (struct pci_dev * pdev, struct net_device ** dev_out, void _ iomem ** ioaddr_out) function calls the pci_enable_device function to enable PCI devices, only successfully enabled PCI devices can be used properly.
9. Call the pci_set_mwi function to determine whether the device supports the memory-Write-invalidate function.
10. Call the pci_find_capability function to determine whether the device has the power management function.
11. Call the pci_resource_flags function to determine whether PCI is in memory ing mode or I/O mode.
12. Call the pci_resource_len function to determine whether the memory space is smaller than the memory space required by the device.
13. Call the pci_request_regions function to notify the kernel. The current PCI will use these memory addresses, and other devices will no longer be able to use them.
14. Call the pci_set_master (pdev) function and set the device to have the ability to obtain the bus. That is, call this function so that the device can apply for using the PCI bus.
15. Call the ioremap function to map the newly applied physical memory to the virtual memory because the process uses the virtual memory address instead of the physical memory address.
16. Return the virtual memory mapped by ioremap to the calling function.
17. At this point, the PCI-related Initialization is complete, and the device can work normally.