1. USB driver introduction
USB (full name Universal Serial Bus) has become the most commonly used and convenient communication interface in PCs and embedded devices.
The Linux USB subsystem is relatively large, this article mainly summarizes the USB bus driver framework under the Linux system, and the key details will be expanded in subsequent articles.
When we plug in the USB device, the Linux system prints the relevant log output.
Prompt after unplugging: USB 1-1: USB disconnect, address 2
1.1 Hardware structure of USB
The hardware structure of USB – Linux USB bus driver framework analysis
As shown in the figure, the two data lines (D+D-) at the end of the hub (USB Root Hub) are connected with a pull-down resistor of 15K, and when no device is connected, the voltage of the hub data line D+D- is low.
When the device is connected, one data line is pulled high because the data line of the device is connected to a 1.5K pull-up resistor.
The hub knows that a device is connected according to whether the data cable is pulled high, and determines whether the connected device is a full-speed USB device (D+ is high) or a low-speed USB device (D- is high) according to whether D+ is high or D- is high.
1.2 USB access identification process
When a USB device is recognized as plugged in, the USB bus driver in Linux issues a command to the device, talks to the device, and asks for device information (descriptor), and the device receives the request and replies to the device descriptor to the bus driver.
And the bus driver will assign an address to the device, such as the above address is 2, when a USB device is accessed later, it will pass this address number, and when the newly accessed USB device is accessed for the first time, it will be accessed with address 0.
When the USB bus driver recognizes the device, it will find the USB device driver for it, such as keyboard, mouse, USB stick.
The USB communication process is a master-slave structure, the USB host initiates a communication request, the device replies to the data, and the USB device does not have the ability to actively communicate with the host.
2. USB bus driver frame
As above, we have a general understanding of the simple communication process of USB, so what is a USB bus driver? What is a USB device driver?
2.1 USB bus driver framework
The USB bus framework is summarized as follows:
USB devices driver
2.2 USB Core
USB Core is a pure software part, does not represent a device, is a hardware-independent protocol stack, it is the module on which all USB devices live, that is, the core of the USB subsystem. The code is located in the kernel/drivers/usb/core directory.
USB Core provides services for device drivers, providing an interface for accessing and controlling USB hardware, regardless of which HOST Controller the system is currently using.
USB Core maps the user’s request to the relevant HCD, which the user cannot access directly. USB Core is the bridge between HCD and USB devices.
The initialization function of USB is defined in kernel/drivers/usb/core/usb.c, which mainly completes bus_register (USB bus registration), usb_major_init (registering USB master character device), usb_register (registering USB ffs driver), usb_hub_init (USB Hub initialization, registering hub driver, Create a kernel daemon thread to monitor the state change of the hub port), etc., and then analyze it in detail.
2.3 USB HCD（Host Controller Driver）
Hardware host controller Host Controller runs HCD, which is an abstraction of the host controller hardware that implements the dialogue interface between the core layer and the controller, and USB HCD contains a variety of USB interface specifications:
(1) UHCI: Intel provides, universal host control interface, USB1.0/1.1;
(2) OHCI: provided by Microsoft, open host control interface, USB1.0/1.1;
(3) EHCI: enhanced host control interface, USB2.0;
A USB device is composed of a number of configurations, interfaces and endpoints, that is, a USB device can contain one or more configurations, each configuration can contain one or more interfaces, and each interface can contain several endpoints.
A USB device driver may contain multiple subdrivers. A USB device subdriver corresponds to a USB interface, not the entire USB device.
USB devices use various descriptors to describe their device architecture, including device descriptors, configuration descriptors, interface descriptors, endpoint descriptors, string descriptors. USB device descriptors are discussed separately.
The object of USB transmission is an endpoint (endpoint), each endpoint has a transmission type, transmission direction, except for endpoint 0, each endpoint only supports data transmission in one direction, endpoint 0 is used to control transmission, both output and input. Input (IN), Output (OUT) “both” is based on the position of the USB host.
For example, the data of the mouse is transmitted from the mouse to the PC, and the corresponding endpoint is called the “input endpoint”.
USB transmission type:
a. Control transmission: reliable, time-guaranteed, e.g. USB device identification process
b. Batch transfer: reliable, time is not guaranteed, such as: USB flash drive
c. Interrupt transmission: reliable, real-time, e.g. USB mouse
d. Real-time transmission: unreliable, real-time, such as: USB camera
Specific USB drivers need to be implemented for different types of USB devices. Such as HID (Human Interface Device), which belongs to the human-computer interaction category, such as USB mouse, USB keyboard, etc. Such devices must comply with HID design specifications.
In the Linux kernel, struct usb_driver struct is used to describe a USB driver, which is registered with the kernel by usb_register USB driver.
Therefore, USB device driver development mainly includes the following two parts:
Allocate/set usb_driver structs, implement and populate struct contents
A detailed analysis of the USB mouse driver will follow, and its code is found in kernel/drivers/hid/usbhid/usbmouse.c
3. USB device identification process
Through the above analysis, the USB device driver model can be summarized as follows.
It mainly contains three parts: USB controller driver, USB core, USB device driver. As shown in the figure above, khubd is a USB daemon, when the USB device is plugged in, the daemon is detected, the USB host controller will generate a hub_irq interrupt, and the controller calls the hub’s probe function to parse the device information.
Let’s analyze the identification process of USB devices.
The device is inserted into the function flow called by the USB device driver, and a chapter will be taken out to further analyze what is done in the USB device identification.
Through the above content, we understand the USB hardware identification process, USB bus framework and USB device driver framework as a whole. Follow-up will be a thematic analysis of some key knowledge. The main ones include:
USB device descriptor parsing
USB four types of transmission
USB packet format analysis
USB mouse device driver code analysis
USB initialization code analysis
USB enumeration process code analysis