This chapter is a supplement to the previous chapter. It mainly describes how the kernel associates the driver with the device.
Common Data Structures of PCI Layer
Struct pci_device_id {// device identifier is used to uniquely identify a device
Unsigned int vendor, device,
Subvendor, subdevice,
Class, class_mark;
Unsigned long driver_data;
};
Strcut pci_dev // PCI device, similar to the net_device structure struct pci_driver {// interface between the PCI layer and the device driver
Char * Name;
Const struct pci_device_id * id_table; // The device corresponding to the driver. The driver of a specific version can correspond to multiple types of devices.
INT (* probe) (strcut pci_dev * Dev, const struct pci_device_id * ID ){
... // Call when the new device identifier matches an item in the driver's id_table. Assign the net_device structure and initialize registration for this new device.
}
Void (* remove) (struct pci_dev * Dev) {// call when the kernel uninstalls the driver or the hot swapping device is pulled out, release the IO port, Io address space, unmount the device, and release the net_device Structure
....
}
INT (* suspend) (struct pci_dev * Dev) {// sleep
....
}
INT (* resume) (struct pci_dev * Dev) {// wake up
....
}
INT (* enable_wake) (struct pci_dev * Dev, u32 state, int enable) {// enable, disable wake-on-lan Function
....
}
Struct pci_dynids dynids; // dynamic ID
};
PCI Layer
When the system starts, a PCI bus descriptor is created and the detected PCI devices are linked to the device list field in the PCI bus descriptor. Each PCI device in the linked list is uniquely identified by pci_device_id. When the device driver is loaded (think back to the previous chapter, the driver can be statically loaded or the dynamic module can be loaded after startup) the kernel calls pci_register_driver (pci_driver) pairing id_table with PCI device list (find which or which devices use this driver) calls probe (...) for each paired device (...) create and assign a network device,