search
HomeSystem TutorialLINUXDetailed explanation of Linux USB driver workflow

Detailed explanation of Linux USB driver workflow

Feb 09, 2024 pm 06:40 PM
linuxlinux tutoriallinux systemlinux commandshell scriptdata lostb netembeddedlinuxGetting started with linuxlinux learning

Linux kernel driver is one of the most important components of the Linux system. They are responsible for communicating with hardware devices so that the operating system can correctly identify and use the hardware. However, developing Linux kernel drivers is not an easy task. In this article, we will delve into the implementation method of Linux kernel driver and provide readers with comprehensive understanding and guidance.

详解Linux USB驱动工作流程

1. USB host

In Linux drivers, the bottom layer of the USB driver is the USB host controller hardware. Running on top of it is the USB host controller driver. Above the host controller is the USB core layer, and the upper layer is the USB device driver. layer (insert device drivers such as U disk, mouse, USB to serial port, etc. on the host computer).

Therefore, in the host-side hierarchy, the USB driver to be implemented includes two categories: USB host controller driver and USB device driver. The former controls the USB device inserted into it, and the latter controls how the USB device communicates with the host. The Linux kernel USB core is responsible for the main work of USB driver management and protocol processing. The USB core between the host controller driver and the device driver is very important. Its functions include: by defining some data structures, macros and functions, it provides a programming interface for the device driver upwards and provides a programming interface for the USB host controller driver downwards; Global variables maintain USB device information of the entire system; complete device hot-plug control, bus data transmission control, etc.

\2. USB device

The USB device side driver in the Linux kernel is divided into three levels: UDC driver, Gadget API and Gadget driver. The UDC driver directly accesses the hardware, controls the underlying communication between the USB device and the host, and provides callback functions for hardware-related operations to the upper layer. The current Gadget API is a simple wrapper around the UDC driver callback functions. The Gadget driver specifically controls the implementation of USB device functions, allowing the device to display features such as "network connection", "printer" or "USB Mass Storage". It uses the Gadget API to control UDC to implement the above functions. The Gadget API isolates the lower-layer UDC driver from the upper-layer Gadget driver, making it possible to separate the implementation of functions from the underlying communication when writing a USB device-side driver in a Linux system.

\3. In the USB device organizational structure, it is divided into four levels from top to bottom: device (device), configuration (config), interface (interface) and endpoint (endpoint). The USB device program is bound to the interface.

A brief description of these four levels is as follows:
Devices typically have one or more configuration
Configurations often have one or more interfaces
The interface has no or more than one endpoint

详解Linux USB驱动工作流程

\4. The most basic form of USB communication is through endpoints (USB endpoints are divided into four types: Interrupt, Bulk, ISO, and Control. Each (different uses), USB endpoints can only transmit data in one direction, from the host to the device or from the device to the host. The endpoint can be regarded as a one-way pipe. The driver registers the driver object with the USB subsystem and later uses the manufacturer and device identification to determine whether the hardware has been installed. The USB core uses a list (a structure containing the manufacturer ID and device ID) to determine which driver to use for a device, and the hotplug script uses this to determine when a specific device is plugged into the system. Which driver's Probe should be automatically executed.

\5. Data structure

\1) USB device: corresponding data structure struct usb_device

\2) Configuration: struct usb_host_config (only one configuration can take effect at any time)

3) USB interface: struct usb_interface (The USB core passes it to the USB device driver, and the USB device driver is responsible for subsequent control. A USB interface represents a basic function, and each USB driver controls an interface. So a physical Hardware devices on may require more than one driver.)

4) Endpoint: struct usb_host_endpoint, the real endpoint information it contains is in another structure: struct usb_endpoint_descriptor (endpoint descriptor, contains all USB-specific data).

\6. USB endpoint classification

The most basic form of USB communication is through something called an endpoint. A USB endpoint can only transfer data in one direction (from the host to the device (called an output endpoint) or from the device to the host (called an input endpoint)). An endpoint can be thought of as a one-way pipe.

There are 4 different types of USB endpoints, each with different data transmission methods:

1) CONTROL
Control endpoints are used to control access to different parts of a USB device. They are typically used to configure the device, obtain device information, send commands to the device, or obtain device status reports. These endpoints are usually smaller. Every USB device has a control endpoint called "Endpoint 0", which is used by the USB core to configure the device when plugged in. The USB protocol ensures that there is always enough bandwidth left for the control endpoint to transmit data to the device.

2) Interrupt INTERRUPT
Whenever the USB host requests data from the device, the interrupt endpoint transfers a small amount of data at a fixed rate. This is the primary data transfer method for USB keyboards and mice. It is also used to transfer data to USB devices to control the device. Usually not used to transfer large amounts of data. The USB protocol ensures that there is always enough bandwidth left for the interrupt endpoint to transmit data to the device.

3) Batch BULK
Bulk endpoints are used to transfer large amounts of data. These endpoints are usually much larger than interrupt endpoints. They are commonly used in situations where there cannot be any data loss. The USB protocol does not guarantee that the transfer will be completed within a specific time frame. If there is not enough space on the bus to send the entire BULK packet, it is divided into multiple packets for transmission. These endpoints are commonly used on printers, USB Mass Storage, and USB network devices.

4) ISOCHRONOUS
Isochronous endpoints also transfer large amounts of data in batches, but this data is not guaranteed to be delivered. These endpoints are used in devices that can handle data loss and rely more on maintaining a continuous flow of data. Such as audio and video equipment and so on.

Control and bulk endpoints are used for asynchronous data transfer, while interrupt and isochronous endpoints are periodic. This means that these endpoints are set up to transmit data continuously at a fixed time, and the USB core reserves the corresponding bandwidth for them.

\7. endpoint

struct usb_host_endpoint{  struct usb_endpoint_descriptor desc;//端点描述符  struct list_head urb_list;//此端点的URB对列,由USB核心维护  void *hcpriv;  struct ep_device *ep_dev; /* For sysfs info */  unsigned char*extra;/* Extra descriptors */  int extralen;  int enabled;};

When the USB device driver is called to call usb_submit_urb to submit an urb request, int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb) will be called to add this urb to the tail of the urb_list. (hcd: Host Controller Driver, corresponding data structure struct usb_hcd)

\8. urb

All USB communications are in request->response mode, and USB devices will not actively send data to the Host. Write data: The USB device driver sends an urb request to the USB device, and the USB device does not need to return data. Read data: The USB device driver sends an urb request to the USB device, and the USB device needs to return data.

USB device driver communicates with all USB devices through urb. urb is described by the struct urb structure (include/linux/usb.h).
urb sends or receives data in an asynchronous manner to a specific endpoint of a specific USB device. A USB device driver can assign multiple urbs to a single endpoint or reuse a single urb for multiple different endpoints, depending on the driver's needs. Each endpoint in the device handles an urb queue, so multiple urbs can be sent to the same endpoint before the queue is emptied.

The typical life cycle of an urb is as follows:
(1) Created;
(2) A specific endpoint assigned to a specific USB device;
(3) Submitted to USB core;
(4) Submitted by the USB core to a specific USB host controller driver for a specific device;
(5) Processed by the USB host controller driver and transmitted to the device;
(6) After the above operations are completed, the USB host controller driver notifies the USB device driver.

urb can also be canceled at any time by the driver that submitted it; if the device is removed, urb can be canceled by the USB core. urbs are created dynamically and contain an internal reference count so that they can be automatically released when the last user releases them.

8.1 Submit urb

Once the urb is properly created and initialized, it can be submitted to the USB core to be sent out to the USB device. This is achieved by calling the function sb_submit_urb.

int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
parameter:
struct urb *urb: pointer to the submitted urb
gfp_t mem_flags: Uses the same parameters passed to the kmalloc call to tell the USB core how to allocate memory buffers in a timely manner

Because function usb_submit_urb can be called at any time (including from an interrupt context), the mem_flags variable must be set correctly. Depending on the time usb_submit_urb is called, only 3 valid values ​​are available:

GFP_ATOMIC
This value should be used as long as the following conditions are met:
\1) The caller is in an urb end handler, interrupt handler, bottom half, tasklet or a timer callback function.
\2) The caller holds a spin lock or a read-write lock. Note that if a semaphore is being held, this value is unnecessary.
\3) current->state is not TASK_RUNNING. Unless the driver has changed the current state by itself, the state should always be TASK_RUNNING.

GFP_NOIO
The driver is in block I/O processing. It should also be used in error handling for all storage types.

GFP_KERNEL
All other situations that do not fall into the categories previously mentioned

After the urb is successfully submitted to the USB core, no members of the urb structure can be accessed until the end processing routine function is called

8.2 urb end processing routine

If usb_submit_urb is successfully called and transfers control of the urb to the USB core, the function returns 0; otherwise a negative error code is returned. If the function call is successful, the end processing routine will be called when the urb is ended. Called once. When this function is called, the USB core completes the urb and returns its control to the device driver.

There are only 3 situations to end urb and call the end processing routine:
(1)urb is successfully sent to the device, and the device returns the correct confirmation. If so, the status variable in urb is set to 0.
(2) An error occurs, and the error value is recorded in the status variable in the urb structure.
(3) URB unlink from the USB core. This occurs either when the driver tells the USB core to cancel a submitted urb by calling usb_unlink_urb or usb_kill_urb, or when an urb has been submitted to it and the device is removed from the system.

\9. Detection and Disconnect

In the struct usb_driver structure, there are 2 functions that the USB core calls at the appropriate time:
(1) When the device is plugged in, if the USB core thinks that the driver can handle it (the USB core uses a list (a structure containing the manufacturer ID and device number ID) to determine which driver to use for a device) , the probe function is called. The probe function checks the device information passed to it and determines whether the driver is truly suitable for this device.
(2) For some reasons, when the device is removed or the driver no longer controls the device, call the disconnect function and do appropriate cleanup.

Both the detection and disconnection callback functions are called in the USB hub kernel thread context, so it is legal for them to sleep. In order to shorten the USB detection time, most of the work is completed when the device is turned on as much as possible. This is because the USB core is The addition and removal of USB devices is handled in a thread, so any slow device driver may make USB device detection time longer.

9.1 Detection function analysis
In the probe callback function, the USB device driver should initialize any local structures it may use to manage the USB device and save all required device information to the local structures, because it is usually easier to do this at this time. In order to communicate with the device, the USB driver Usually the endpoint address and buffer size of the device are detected.

In this article, we introduce the implementation method of Linux kernel driver in detail, including the kernel driver framework, kernel module writing, device driver registration and unregistration, etc. We believe that through studying this article, readers can have a deeper understanding of the implementation principles of the Linux kernel driver and provide more reference and help for their own development work.

The above is the detailed content of Detailed explanation of Linux USB driver workflow. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:良许Linux教程网. If there is any infringement, please contact admin@php.cn delete
How does the availability of developer tools differ between Linux and Windows?How does the availability of developer tools differ between Linux and Windows?May 12, 2025 am 12:04 AM

Linuxoffersmoredevelopertools,especiallyopen-sourceandcommand-linebased,whileWindowshasimprovedwithWSLbutstilllagsinsomeareas.Linuxexcelsinopen-sourcetools,command-lineefficiency,andsystemoptimization,makingitidealfordevelopersfocusedontheseaspects.W

7 Windows-Like Linux Distros You Should Try Out7 Windows-Like Linux Distros You Should Try OutMay 11, 2025 am 10:35 AM

This article explores the best Linux distributions offering a Windows-like desktop experience. The shift from Windows, particularly from Windows 10 (released July 29, 2015) and its successor Windows 11 (October 5, 2021), is often considered by users

10 Best Open Source Security Firewalls for Linux10 Best Open Source Security Firewalls for LinuxMay 11, 2025 am 10:25 AM

As an administrator with more than ten years of experience in Linux management, my main responsibility is always the security management of Linux servers. Firewalls play a vital role in protecting Linux systems and network security. They are like security guards between internal and external networks, controlling and managing in and out of network traffic according to a set of predefined rules. These firewall rules allow legal connections and block unspecified connections. There are many open source firewall applications available these days, and choosing the right application for your needs can be challenging. In this article, we will explore the ten most popular open source firewalls that can help protect your Linux servers in 2024. Iptables /

7 Must-Try X-Window (GUI-Based) Linux Commands - Part 27 Must-Try X-Window (GUI-Based) Linux Commands - Part 2May 11, 2025 am 10:01 AM

This article explores additional valuable X-based Linux commands and programs, expanding on our previous coverage of GUI-based Linux commands. xwininfo: Unveiling Window Details xwininfo is a command-line utility providing comprehensive information

How to Monitor MySQL or MariaDB Using Netdata in LinuxHow to Monitor MySQL or MariaDB Using Netdata in LinuxMay 11, 2025 am 09:50 AM

Netdata: A powerful tool to easily monitor the performance of MySQL databases on Linux systems Netdata is a free and open source real-time system performance and health monitoring application suitable for Unix-like systems such as Linux, FreeBSD and macOS. It collects and visualizes various metrics, allowing you to monitor the system's operation in real time. Netdata supports a variety of plug-ins that can monitor the current system status, running applications and services, such as MySQL database servers, etc. This article will guide you on how to use Netdata to monitor the performance of MySQL database servers on RHEL-based distributions. After reading, you will be able to go through Netdata's web interface,

How to Compare and Merge Files Using diff3 Command on LinuxHow to Compare and Merge Files Using diff3 Command on LinuxMay 11, 2025 am 09:49 AM

Linux diff3 command: a powerful tool for comparing and merging three files The diff3 command is a powerful tool in Linux that compares three files and shows their differences. This is very useful for programmers and system administrators who often deal with multiple versions of the same file, needing to merge these versions or identify changes between different versions. This article will introduce the basic usage of the diff3 command, common options, and some examples to help you understand how it works in Linux. What is the diff3 command? diff3 is a tool for comparing three files line by line, which recognizes differences and displays them in an easy to understand format. It can be used for: Find three articles

How to Run an SMS Portal with playSMS in LinuxHow to Run an SMS Portal with playSMS in LinuxMay 11, 2025 am 09:41 AM

This guide provides a comprehensive walkthrough for installing the open-source SMS management software, playSMS, on a Linux server. It's a powerful tool for efficient SMS communication management. System Requirements: Before beginning, ensure your s

Clementine: A Feature-Rich Music Player for LinuxClementine: A Feature-Rich Music Player for LinuxMay 11, 2025 am 09:31 AM

Clementine: Your Versatile and User-Friendly Music Player for Linux, macOS, and Windows Clementine is a modern, lightweight music player designed for ease of use, particularly on Linux systems. Inspired by Amarok, Clementine surpasses its predecessor

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.