Three important concepts in the Linux device model are bus, device, and driver. That is, bus, device, driver, and in fact, the kernel defines some data structures such as struct bus_type, struct device, and struct device_driver. These three important data structures come from one place, include/linux/device.h. We know that there are many types of buses, such as PCI bus, SCSI bus, and USB bus, so we see variables like pci_bus_type, scsi_bus_type, usb_bus_type in the Linux kernel code. They are all of type struct bus_type. Two very important members in the struct bus_type structure are struct kset drivers and struct kset devices. kset and another called kobject are the basic elements of the Linux Kernel 2.6 device model, but we won’t elaborate on them here as they are not necessary to understand for now. In our lives, we encounter many people and events, but more of them merely pass by us, just transient guests in our lives. In the movie of our lives, they may only have one shot, and that shot might even be cut later. Here, we just need to know that the existence of drivers and devices connects struct bus_type with two linked lists: one is the devices linked list, and the other is the drivers linked list. That is to say, by knowing the data structure corresponding to a bus, we can find out what devices are associated with that bus and what driver programs support those devices.
To achieve this, it is required that every time a device appears, it must report to the bus or register itself, and every time a driver appears, it must also report to the bus or register itself. For example, during system initialization, the system scans which devices are connected and creates a struct device variable for each device. Each time a driver program is present, a struct device_driver structure variable must be prepared. All these variables are added to their respective linked lists: device is inserted into the devices linked list, and driver is inserted into the drivers linked list. In this way, every device and every driver can be found through the bus.
However, if there are devices in the computer but no corresponding drivers, then the devices cannot work. Conversely, if there are only drivers but no devices, the drivers will also be ineffective. Before they meet each other, both sides are like wild grass on the roadside, one drifting and the other swaying, neither knowing where the future lies, only swaying in the winds of life. Thus, many lonely souls gradually hung on the two tables on the bus. Devices began to increase, drivers began to increase; they were like two worlds, devices warming each other, drivers celebrating together, but they shared one thing in common: they were all waiting for their other half.
As someone who looks at code, I have always been curious to know whether they are like us in reality, with some people destined to wait for others, while some are destined to be waited for.
In struct bus_type, two linked lists are prepared for devices and drivers, while the structure representing device, struct device, has two members: struct bus_type *bus and struct device_driver *driver. Similarly, the structure representing driver, struct device_driver, also has two members: struct bus_type *bus and struct list_head devices. The definitions of struct device and struct device_driver are the same as struct bus_type, found in include/linux/device.h. With a man’s intuition, it can be known that the bus in struct device records which bus this device is connected to, and the driver records which driver this device uses. Conversely, in struct device_driver, the bus represents which bus this driver belongs to, and devices record the devices supported by this driver. Yes, it is devices (plural) and not device (singular), because a driver can support one or more devices, while a device will only bind to one driver.
So we want to know how bus, device, and driver are related. In other words, how are the pointers in these three data structures assigned? It is absolutely impossible for a struct bus_type data structure to know what will be included in its devices list and drivers list once it is allocated; these items certainly cannot be innate, they can only be filled in later. Specifically for the USB system, this work is done by the USB core. The USB core’s code will initialize the entire USB system, for example, applying for struct bus_type usb_bus_type, and then scanning the USB bus to see which USB devices are connected, or which USB devices are connected to the root hub. For instance, if a USB keyboard is connected, a struct device will be prepared for it, and the struct device will be assigned values based on its actual situation and inserted into the devices linked list. If a regular hub is connected to the root hub, then in addition to preparing a struct device for this hub, it also needs to continue scanning to see if other devices are connected to this hub. If so, the previous actions are repeated until the entire scan is completed, ultimately establishing the devices linked list in usb_bus_type. What about the drivers linked list? This does not require the bus to take the initiative; instead, each driver must register itself with the bus.
The two linked lists on the bus record each device and driver, but how are device and driver connected? At this moment, a question must be raised: which came first, device or driver? Long ago, in those passionate years, the device came first. Each device that needed to be used was already plugged in before the computer started, placed in its proper position. Then the computer starts, and the operating system begins initialization, the bus starts scanning devices. For each device found, a struct device structure is allocated and added to the devices linked list on the bus. Then each driver program starts initialization, begins to register its struct device_driver structure, and it goes to the devices linked list on the bus to look for (traverse) each device whose struct device_driver pointer is still empty. It then observes the characteristics of such devices to see if they are supported. If so, it calls a function called device_bind_driver, and then they are bound together. In other words, the struct device’s struct device_driver driver points to this driver, and the struct device_driver adds the struct device to its struct list_head devices linked list. Thus, the bus, device, and driver, or rather the connections between any two of them, are established. Knowing one of them allows you to find the other two. One shares honor and disgrace, one suffers together.
But now the situation has changed. In these days of blooming red lotus, in these days of cherry blossoms fading, a new term has emerged: hot-swappable. Devices can be inserted or removed from the computer after it has started. Therefore, it is difficult to say which came first, device or driver, because both are possible. A device can appear at any time, and a driver can also be loaded at any time. So the situation arises that whenever a struct device is born, it will go to the drivers linked list of the bus to find its other half. Conversely, whenever a struct device_driver is born, it will go to the devices linked list of the bus to find its devices. If a suitable match is found, then it calls device_bind_driver to bind them. If not found, there is no problem; just wait, wait for the ephemeral flower to bloom again, wait for the scenery to become clear, and believe in your heart that there is always someone in this world waiting for you, just that you have not met yet.