Linux Device Driver Learning (17)-USB driver (2)

Source: Internet
Author: User

Kernel 2.6.29.4
USB devices are actually complicated, but the Linux Kernel provides a subsystem called USB core to handle most of the complicated work. Therefore, the interface between the driver and USB core is described here.
In the USB device organization structure, there are four layers: device, config, interface, and endpoint.
A brief description of these four layers is as follows:
A device usually has one or more configurations.
Configuration often has one or more interfaces
An interface usually has one or more settings.
The interface does not have or has more than one endpoint
Device
It is obvious that a USB device is inserted, and the data structure struct usb_device is used in the kernel to describe the entire USB device. (Include/Linux/USB. h)

Struct usb_device {int devnum; // device number, which is the address char devpath [16] on the USB bus; // The device ID string Enum usb_device_state state for the message; // device status: configured, unconnected, and so on Enum usb_device_speed speed; // device speed: high speed, full speed, low speed, or wrong struct usb_tt * tt; // process the transmitter information; used for low-speed, full-speed devices, and high-speed hubint ttport; // The device port unsigned int toggle located in the TT hub [2]; // occupies one position for each endpoint, indicates the direction of the endpoint ([0] = In, [1] = out) struct usb_device * parent; // The upper-level hub pointer struct usb_bus * bus; // The bus pointer struct usb_host_endpoint ep0; // struct device dev; // the data structure of the device interface in general. struct usb_device_descriptor descriptor; // USB device descriptor struct usb_host_config * config; // configure struct usb_host_config * actconfig for all devices; // configure struct usb_host_endpoint * ep_in [16] for activated devices; // input the endpoint array struct usb_host_endpoint * ep_out [16]; // output the endpoint array char ** rawdescriptors; // The raw descriptor unsigned short bus_ma for each configuration; // The available bus current u8 portnum; // The parent port number u8 level; // USB hub layers unsigned can_submit: 1; // urb can be submitted with the flag unsigned discon_suincluded: 1; // The unsigned persist_enabled: 1 when paused; // usb_persist enable flag unsigned have_langid: 1; // string_langid indicates unsigned authorized: 1; unsigned authenticated: 1; unsigned WUSB: 1; // wireless USB flag int string_langid; // string language ID/* Static strings from the device * // static string char * product of the device; // product name char * manufacturer; // vendor name char * serial; // product serial number struct list_head filelist; // The usbfs file opened by this device # ifdef config_usb_device_classstruct device * usb_classdev; // USB devices created for usb fs devices accessed by the user space # endif # ifdef config_usb_devicefsstruct dentry * usbfs_dentry; // the usb fs entry of the device # endifint maxchild; // (if it is hub) interface count struct usb_device * Children [usb_maxchildren]; // The Sub-device int pm_usage_cnt connected to the hub; // The Count u32 quirks for automatic suspension; atomic_t urbnum; // The urb count submitted by this device unsigned long active_duration; // use the timer after activation # ifdef config_pm // struct delayed_work autosuspend related to power management; // automatically suspended delayed struct work_struct autoresume; // (interrupted) Automatic wake-up request struct mutex pm_mutex; // The PM mutex lock unsigned long last_busy; // The Last Time used: int autosuspend_delay; unsigned long connect_time; // The first connection time: Unsigned auto_pm: 1; // automatically suspend/wake up unsigned do_remote_wakeup: 1; // remote wakeup unsigned reset_resume: 1; // use reset to replace unsigned autosuspend_disabled: 1; // suspend unsigned autoresume_disabled: 1; // wake up and close unsigned skip_sys_resume: 1; // skip the next system wake-up # endifstruct wusb_dev * wusb_dev; // (if it is a wireless USB) connect to the WUSB-specific data structure };

Configuration

A USB device can have multiple configurations and can be switched between them to change the status of the device. For example, if a device can change the Usage Status of the device by downloading the firmware (firmware) (I think it is similar to FPGA or CPLD), the USB device must switch the configuration to complete this task. Only one configuration can be activated at a time. In Linux, the structure struct usb_host_config is used to describe the USB configuration. The USB driver we write usually does not need to read or write any value of these structures. You can find the descriptions in the kernel source code file include/Linux/USB. h.

Struct usb_host_config {struct usb_config_descriptor DESC; // configure the descriptor char * string;/* configure the string pointer (if any) */struct usb_interface_assoc_descriptor * intf_assoc [usb_maxiads]; // The configured interface federated descriptor chain table struct usb_interface * interface [usb_maxinterfaces]; // interface descriptor chain table struct usb_interface_cache * intf_cache [usb_maxinterfaces]; unsigned char * extra; /* extra descriptor */INT extralen ;};

Interface

The USB endpoint is bound as an interface, and the USB interface only processes one type of USB logical connection. 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. This can be seen in the "Dizzy fart" system. Sometimes, after a USB device is inserted, the system identifies multiple devices and installs multiple drivers.

The USB interface can have other settings, which are different options for interface parameters. The interface initialization status is the first setting, numbered 0. Other settings can control independent endpoints in different ways.

The USB interface is described using struct usb_interface in the kernel. The USB core transmits it to the USB driver, and the USB driver is responsible for subsequent control.

Struct usb_interface {struct usb_host_interface * altsetting;/* contains an array of all interface structures available for this interface. Each struct usb_host_interface contains an endpoint configuration defined by the struct usb_host_endpoint structure. These interface structures have no special order. */Struct usb_host_interface * cur_altsetting;/* points to the internal pointer of altsetting, indicating the current active interface configuration */unsigned num_altsetting; /* optional quantity * // * if there is an interface Association descriptor then it will list the associated interfaces */struct usb_interface_assoc_descriptor * intf_assoc; int minor; /* If the USB driver bound to this interface uses the USB master device number, this variable contains the secondary device number allocated to the interface by the USB core. this is only valid after a successful call of usb_register_dev. * // * The following data should not be considered in the driver we write. The system will automatically set */Enum usb_interface_condition condition;/* state of binding */unsigned is_active: 1; /* the interface is not suincluded */unsigned sysfs_files_created: 1;/* The sysfs attributes exist */unsigned ep_devs_created: 1;/* endpoint "devices" exist */unsigned unregistering: 1;/* unregistration is in progress */unsigned needs_remote_wakeup: 1;/* driver requires remote wakeup */unsigned needs_altsetting0: 1; /* switch to altsetting 0 is pending */unsigned needs_binding: 1;/* Needs delayed unbind/rebind */unsigned reset_running: 1; struct device dev; /* interface-specific device information */struct device * usb_dev; int pm_usage_cnt;/* usage counter for autosuspend */struct work_struct reset_ws;/* For resets in atomic context */}; struct usb_host_interface {struct usb_interface_descriptor DESC; // interface descriptor struct usb_host_endpoint * endpoint;/* the Union array of all endpoint struct of this interface */char * string; /* interface description string */unsigned char * extra;/* extra descriptor */INT extralen ;};

Endpoint

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.

A usb endpoint has four different types of data transmission methods:

Control

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.

Interrupt interrupt

Each time a USB host requests data from a 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.

Bulk

Batch endpoints are used to transmit large amounts of data. These endpoints are often 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.

Isochronous

The endpoint also transmits 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.

Control and batch endpoints are used for asynchronous data transmission, while interrupt and synchronization endpoints are periodic. 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.

The endpoint is described in the kernel using the structure struct usb_host_endpoint. The actual endpoint information contained in the endpoint is in another structure: struct usb_endpoint_descriptor (the endpoint descriptor, containing all USB-specific data ).

Struct usb_host_endpoint {struct usb_endpoint_descriptor DESC; // The endpoint descriptor struct list_head urb_list; // The urb column of this endpoint. Void * hcpriv is maintained by the USB core; struct ep_device * ep_dev; /* For sysfs info */unsigned char * extra;/* extra descriptors */INT extralen; int enabled ;};/* optional */* usb_dt_endpoint: endpoint descriptor */struct usb_endpoint_descriptor {_ _ U8 blength; _ u8 bdescriptortype; _ u8 bendpointaddress;/* the USB address of the specific endpoint. The 8-bit data contains the endpoint direction, which is used in combination with the bit mask usb_dir_out and usb_dir_in, determine the data direction of this endpoint. */_ U8 bmattributes; // This is the type of the endpoint. The bitmask is as follows: _ le16 wmaxpacketsize;/* the maximum number of bytes that the endpoint can process at a time. The driver can send data larger than this value to the endpoint, but when it is actually sent to the device, the data will be divided into wmaxpakcetsize blocks. For high-speed devices, several extra bits are used to support the high-bandwidth mode of the endpoint. */_ U8 binterval; // If the endpoint is of the interrupt type, this value is the interval setting of the endpoint, that is, the interval between the interrupt requests of the endpoint, in milliseconds/* Note: These two are _ only _ in audio endpoints. * // * use usb_dt_endpoint * _ size in blength, not sizeof. */_ u8 brefresh; _ u8 bsynchaddress;} _ attribute _ (packed )); # define usb_dt_endpoint_size 7 # define Route 9/* audio extension * // ** endpoints */# define route 0x0f/* In bendpointaddress endpoint USB Address Mask */# define usb_endpoint_dir_mask 0 x 80/* In bendpointaddress data direction mask */# define usb_dir_out 0/* To device */# define usb_dir_in 0x80/* to host */# define usb_endpoint_xfertype_mask 0x03 /* bmattributes bit mask */# define usb_endpoint_xfer_control 0 # define limit 1 # define limit 2 # define usb_endpoint_xfer_int 3 # define usb_endpoint_max_adjustable 0x80/* limit /*-------------------------------------------------------------------------*/

USB and sysfs

Because of the complexity of a single USB physical device, the representation of the device in sysfs is also very complex.Both the physical USB device (represented by struct usb_device) and a single USB interface (represented by struct usb_interface) appear in sysfs as a single device because both structures contain a struct device structure.The following is the directory tree of My USB mouse in sysfs:

/Sys/devices/pci0000: 00/0000: 00: 1A. 0/usb3/3-1 (indicating the usb_device structure)

.

| -- 3-. 0 (USB _ interface corresponding to the mouse)

| -- 0003: 046d: c018.0003

| -- Driver-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/../bus/hid/drivers/generic-usb

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/../bus/hid

| '-- Uevent

| -- Balternatesetting

| -- Binterfaceclass

| -- Binterfacenumber

| -- Binterfaceprotocol

| -- Binterfacesubclass

| -- Bnumendpoints

| -- Driver-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/bus/usb/drivers/usbhid

| -- Ep_81-> usb_endpoint/usbdev3.4 _ ep81

| -- Input

| '-- Input6

| -- Capabilities

| -- ABS

| -- EV

| -- FF

| -- Key

| -- Led

| -- MSC

| -- REL

| -- SND

| '-- SW

| -- Device-> http://www.cnblogs.com/../3-1:1.0

| -- Event3

| -- Dev

| -- Device-> http://www.cnblogs.com/input6

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/../class/input

| '-- Uevent

| -- ID

| -- Bustype

| -- Product

| -- Vendor

| '-- Version

| -- Modalias

| -- Mouse1

| -- Dev

| -- Device-> http://www.cnblogs.com/input6

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/../class/input

| '-- Uevent

| -- Name

| -- Phys

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/class/input

| -- Uevent

| '-- Uniq

| -- Modalias

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/bus/usb

| -- Supports_autosuspend

| -- Uevent

| '-- Usb_endpoint

| '-- Usbdev3.4 _ ep81

| -- Bendpointaddress

| -- Binterval

| -- Blength

| -- Bmattributes

| -- Dev

| -- Device-> http://www.cnblogs.com/../3-1:1.0

| -- Direction

| -- Interval

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/class/usb_endpoint

| -- Type

| -- Uevent

| '-- Wmaxpacketsize

| -- Authorized

| -- Bconfigurationvalue

| -- Bdeviceclass

| -- Bdeviceprotocol

| -- Bdevicesubclass

| -- Bmaxpacketsize0

| -- Bmaxpower

| -- Bnumconfigurations

| -- Bnuminterfaces

| -- Bcddevice

| -- Bmattributes

| -- Busnum

| -- Configuration

| -- Descriptors

| -- Dev

| -- Devnum

| -- Driver-> http://www.cnblogs.com/http://www.cnblogs.com/../bus/usb/drivers/usb

| -- Ep_00-> usb_endpoint/usbdev3.4 _ ep00

| -- Idproduct

| -- Idvendor

| -- Manufacturer

| -- Maxchild

| -- Power

| -- Active_duration

| -- Autosuspend

| -- Connected_duration

| -- Level

| -- Persist

| '-- Wakeup

| -- Product

| -- Quirks

| -- Speed

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/../bus/usb

| -- Uevent

| -- Urbnum

| -- Usb_endpoint

| '-- Usbdev3.4 _ ep00

| -- Bendpointaddress

| -- Binterval

| -- Blength

| -- Bmattributes

| -- Dev

| -- Device-> http://www.cnblogs.com/../3-1

| -- Direction

| -- Interval

| -- Power

| '-- Wakeup

| -- Subsystem-> http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/../class/usb_endpoint

| -- Type

| -- Uevent

| '-- Wmaxpacketsize

'-- Version

38 directories, 91 files

The USB sysfs device name is: root_hub-hub_port: config. Interface

As the USB hub hierarchy increases, the hub port number is added to the string to the hub port number that follows the link. For a layer-2 tree, the device is:Root_hub-hub_port-hub_port: config. interface.And so on.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.