Linux USB driver workflow 1. in the Linux driver of a USB host, the USB driver is at the bottom of the USB host controller hardware. The driver runs on it and the USB core layer on the host controller, the upper layer is the driver layer of the USB device (the USB flash drive, mouse, USB to serial port, and other device drivers are inserted on the host ). Www.2cto.com therefore, in the Host-side hierarchy, there are two types of USB drivers to be implemented: USB Host Controller drivers and USB device drivers. The former controls the USB devices to be inserted into it, the latter controls how the USB device communicates with the host. The Linux kernel USB core is responsible for USB driver management and protocol processing. The USB core between the host controller driver and the device driver is very important. Its functions include: providing programming interfaces for the device driver by defining some data structures, macros, and function functions, provides a programming interface for the USB host controller driver, maintains the information of the USB device of the entire system through global variables, and controls the hot swapping of devices and bus data transmission. 2. In the Linux kernel of a USB device, the driver on the USB device side is divided into three layers: 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 a callback function for hardware-related operations at the upper layer. The current Gadget API is a simple packaging of UDC driver callback functions. The Gadget driver specifically controls the implementation of USB device functions, so that the device shows "network connection", "Printer", "USB Mass Storage" and other features, 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, so that the function implementation can be separated from the underlying communication when writing the USB device-side driver in Linux. 3. In the USB device structure, there are four layers: device, config, interface, and endpoint. The USB device program is bound to the interface. A brief description of these four levels is as follows: a device usually has one or more configuration configurations, and often has one or more interface interfaces and more than one endpoint.
4. the most basic form of USB communication is through four types: endpoints (Interrupt), Bulk, ISO, and Control, for different purposes, the USB endpoint can only transmit data to one direction, from the host to the device or from the device to the host, the endpoint can be seen as a one-way pipe (pipe ). The driver registers the driver object to the USB subsystem, and later uses the manufacturer and device identifier to determine whether the hardware has been installed. The USB core uses a list (a struct containing the manufacturer ID and device ID) to determine which driver to use for a device, the hot plug-in script uses it to determine which driver Probe is automatically executed when a specific device is inserted into the system. 5. data Structure 1) USB device: Corresponding data structure struct usb_device2) configuration: struct usb_host_config (only one configuration takes effect at any time) 3) USB interface: struct usb_interface (the USB core transmits it to the driver of the USB device, and the driver of the USB device is responsible for subsequent control. A usb interface represents a basic function, and each USB driver controls an interface. Therefore, a physical hardware device may need more than one driver .) Www.2cto.com 4) Endpoint: struct usb_host_endpoint, which contains real endpoint information in another structure: struct usb_endpoint_descriptor (endpoint descriptor, including 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 transmit data to one direction (from the host to the device (called the output endpoint) or from the device to the host (called the input endpoint )). An endpoint can be considered as a one-way pipeline. There are four different types of USB endpoints, with different data transmission methods:
1) The CONTROL endpoint is used to CONTROL access to different parts of USB devices. It is usually used to configure devices, obtain device information, send commands to devices, or obtain device status reports. These endpoints are usually small. Each USB device has a control endpoint called "endpoint 0", which is used by the USB core to configure the device during insertion. The USB protocol ensures that there is always enough bandwidth for the control endpoint to transmit data to the device. 2) INTERRUPT whenever the USB host requests data to the device, the INTERRUPT endpoint transmits a small amount of data at a fixed rate. This is the main data transfer method for USB keyboard and mouse. It is also used to transmit data to USB devices to control devices. It is usually not used to transmit a large amount of data. The USB protocol ensures that there is always enough bandwidth left for the interrupt endpoint to transmit data to the device. 3) BULK batch ends are used to transmit a large amount of data. These endpoints are generally much larger than the interrupt endpoints. They are generally used to prevent any data loss. The USB protocol does not guarantee that the transmission is completed within a specific time range. If there is not enough space on the bus to send the entire BULK package, it is divided into multiple packages for transmission. These endpoints are generally used on printers, USB Mass Storage, and USB network devices.
4) When ISOCHRONOUS is used, the endpoint also transfers a large amount of data in batches, but this data cannot be delivered. These endpoints are used on devices that can process data loss and are more dependent on continuous data streams. Such as audio and video devices. The control and batch endpoints are used for asynchronous data transmission, while the endpoints are periodic during interruption and other operations. This means that these endpoints are set to continuously transmit data at a fixed time, and the USB core reserves the corresponding bandwidth for them.
7. endpointstruct usb_host_endpoint {struct usb_endpoint_descriptor desc; // The endpoint descriptor struct list_head urb_list; // The URB column of this endpoint. 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 the urb request, add this urb to the tail of urb_list by calling int usb_hcd_link_urb_to_ep (struct usb_hcd * hcd, struct urb * urb. (Hcd: Host Controller Driver, corresponding to the data structure struct usb_hcd) www.2cto.com 8. All USB communication in urb is request-> response mode, and the USB device does not send data to the Host. Write Data: The USB device driver sends a urb request to the USB device, and the USB device does not need to return data. Read data: the USB device driver sends a urb request to the USB device, and the USB device needs to return data. The USB device driver communicates with all USB devices through urb. Urb uses the struct urb structure description (include/linux/usb. h ). Urb sends or receives data asynchronously from a specific endpoint of the same USB device. A USB device driver can allocate multiple URBS to one endpoint or reuse a single urb to multiple different endpoints Based on the driver's needs. Each endpoint in the device processes an urb queue, So multiple URBS can be sent to the same endpoint before the queue is cleared. A typical life cycle of an urb is as follows: (1) created; (2) specific Endpoint allocated to a specific USB device; (3) submitted to the USB core; (4) the driver is submitted by the USB core to a specific USB Host Controller drive of a specific device. (5) The driver is processed by the USB Host Controller and transferred 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 submitted drive; if the device is removed, urb can be canceled by the USB core. Urb is dynamically created and contains an internal reference count so that they can be automatically released when the last user releases them. 8.1 submit urb once urb is correctly created and initialized, it can be submitted to the USB core to send to the USB device. this is achieved by calling the sb_submit_urb function. int usb_submit_urb (struct urb * urb, gfp_t mem_flags); parameter: struct urb * urb: pointer to the submitted urb gfp_t mem_flags: The same parameter is called using the pointer passed to kmalloc, the mem_flags variable must be correctly set to tell the USB core how to allocate memory buffer in a timely manner because the function usb_submit_urb can be called at any time (including from an interrupt context. according to the time when usb_submit_urb is called, only three valid values are available: GFP_ATOMIC www.2cto.com. This value should be used as long as the following conditions are met: 1) the caller is in an urb end processing routine, interrupt processing routine, the bottom half, tasklet, or a timer callback function. 2) The caller holds the spin lock or read/write lock. note that this value is unnecessary if a semaphore is being held. 3) current-> state is not TASK_RUNNING. unless the driver has changed the current status, the status should always be TASK_RUNNING. the GFP_NOIO driver is in block I/O processing. it should also be used for error handling of all storage types. GFP_KERNEL all other situations that are not mentioned earlier after urb is successfully submitted to the USB core until the processing routine function is called, all members of the urb structure cannot access the 8.2 urb end processing routine. If usb_submit_urb is successfully called and the control of urb is passed to the USB core, the function returns 0; otherwise, a negative error code is returned. if the function is called successfully, the processing routine will be called once when urb ends. when this function is called, the USB core completes the urb and returns its control to the device driver. there are only three cases where urb ends and the end processing routine is called: (1) urb is successfully sent to the device and the device returns the correct confirmation. in this case, the status variable in urb is set to 0. (2) When an error occurs, the error value is recorded in the status variable in the urb structure. (3) urb from USB core unlink. this occurs either when the driver notifies the USB core to cancel a submitted urb by calling usb_unlink_urb or usb_kill_urb, or when a urb has been submitted to it, the device is removed from the system. 9. test and disconnect www.2cto.com In the struct usb_driver structure, there are two USB cores that are called when appropriate: (1) when the device is inserted, if the USB core thinks this driver can be processed (the USB core uses a list (a struct containing the manufacturer ID and device ID) to determine which driver should be used for a device), call the probe function to check the device information passed to it and determine whether the driver is suitable for the device.
(2) For some reason, when the device is removed or the driver no longer controls the device, call the disconnect function for proper cleaning. both the probe and disconnect callback functions are called in the context of the USB hub kernel thread, so their sleep is legal. to shorten the USB detection time, most of the work should be completed when the device is turned on. this is because the USB core processes the addition and removal of USB devices in one thread, so any slow device driver can make the USB device probe longer. 9.1 test function analysis in the test callback function, the USB device driver should initialize it to manage all local structures of the USB device and save all required device information to the local structure, it is usually easier to do this at this time. to communicate with the device, the USB driver usually needs to detect the device's endpoint address and buffer size. author: Tommy_wxie