Linux 驱动开发之USB设备分析2(基于Linux6.6)---数据结构介绍
一、struct usb_interface 接口函数
include/linux/usb.h
struct usb_interface {
/* array of alternate settings for this interface,
* stored in no particular order */
struct usb_host_interface *altsetting;
struct usb_host_interface *cur_altsetting; /* the currently
* active alternate setting */
unsigned num_altsetting; /* number of alternate settings */
/* If there is an interface association descriptor then it will list
* the associated interfaces */
struct usb_interface_assoc_descriptor *intf_assoc;
int minor; /* minor number this interface is
* bound to */
enum usb_interface_condition condition; /* state of binding */
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 resetting_device:1; /* true: bandwidth alloc after reset */
unsigned authorized:1; /* used for interface authorization */
struct device dev; /* interface specific device info */
struct device *usb_dev;
struct work_struct reset_ws; /* for resets in atomic context */
};
#define to_usb_interface(d) container_of(d, struct usb_interface, dev)
struct usb_interface中的struct usb_host_interface *cur_altsetting成员,表示当前正在使用的设置,
1.1、struct usb_host_interface
include/linux/usb.h
/* host-side wrapper for one interface setting's parsed descriptors */
struct usb_host_interface {
struct usb_interface_descriptor desc;
int extralen;
unsigned char *extra; /* Extra descriptors */
/* array of desc.bNumEndpoints endpoints associated with this
* interface setting. these will be in no particular order.
*/
struct usb_host_endpoint *endpoint;
char *string; /* iInterface string, if present */
};
具体到接口描述符,它当然就是描述接口本身的信息的。一个接口可以有多个设置,使用不同的设置,描述接口的信息会有些不同,所以接口描述符并没有放在struct usb_interface结构里,而是放在表示接口设置的struct usb_host_interface结构里。
二、struct usb_host_endpoint 端点函数
include/linux/usb.h
struct usb_host_endpoint {
struct usb_endpoint_descriptor desc;
struct usb_ss_ep_comp_descriptor ss_ep_comp;
struct usb_ssp_isoc_ep_comp_descriptor ssp_isoc_ep_comp;
struct list_head urb_list;
void *hcpriv;
struct ep_device *ep_dev; /* For sysfs info */
unsigned char *extra; /* Extra descriptors */
int extralen;
int enabled;
int streams;
};
三、struct usb_device 设备函数
include/linux/usb.h
struct usb_device {
int devnum;
char devpath[16];
u32 route;
enum usb_device_state state;
enum usb_device_speed speed;
unsigned int rx_lanes;
unsigned int tx_lanes;
enum usb_ssp_rate ssp_rate;
struct usb_tt *tt;
int ttport;
unsigned int toggle[2];
struct usb_device *parent;
struct usb_bus *bus;
struct usb_host_endpoint ep0;
struct device dev;
struct usb_device_descriptor descriptor;
struct usb_host_bos *bos;
struct usb_host_config *config;
struct usb_host_config *actconfig;
struct usb_host_endpoint *ep_in[16];
struct usb_host_endpoint *ep_out[16];
char **rawdescriptors;
unsigned short bus_mA;
u8 portnum;
u8 level;
u8 devaddr;
unsigned can_submit:1;
unsigned persist_enabled:1;
unsigned reset_in_progress:1;
unsigned have_langid:1;
unsigned authorized:1;
unsigned authenticated:1;
unsigned wusb:1;
unsigned lpm_capable:1;
unsigned lpm_devinit_allow:1;
unsigned usb2_hw_lpm_capable:1;
unsigned usb2_hw_lpm_besl_capable:1;
unsigned usb2_hw_lpm_enabled:1;
unsigned usb2_hw_lpm_allowed:1;
unsigned usb3_lpm_u1_enabled:1;
unsigned usb3_lpm_u2_enabled:1;
int string_langid;
/* static strings from the device */
char *product;
char *manufacturer;
char *serial;
struct list_head filelist;
int maxchild;
u32 quirks;
atomic_t urbnum;
unsigned long active_duration;
#ifdef CONFIG_PM
unsigned long connect_time;
unsigned do_remote_wakeup:1;
unsigned reset_resume:1;
unsigned port_is_suspended:1;
#endif
struct wusb_dev *wusb_dev;
int slot_id;
struct usb2_lpm_parameters l1_params;
struct usb3_lpm_parameters u1_params;
struct usb3_lpm_parameters u2_params;
unsigned lpm_disable_count;
u16 hub_delay;
unsigned use_generic_driver:1;
};
#define to_usb_device(d) container_of(d, struct usb_device, dev)
四、struct usb_host_config 配置函数
include/linux/usb.h
struct usb_host_config {
struct usb_config_descriptor desc;
char *string; /* iConfiguration string, if present */
/* List of any Interface Association Descriptors in this
* configuration. */
struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];
/* the interfaces associated with this configuration,
* stored in no particular order */
struct usb_interface *interface[USB_MAXINTERFACES];
/* Interface information available even when this is not the
* active configuration */
struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];
unsigned char *extra; /* Extra descriptors */
int extralen;
};
五、总结
5.1、主要的 USB 数据结构及其联系
1. usb_device
-
定义:
usb_device
结构体表示一个 USB 设备,包含了与设备相关的所有信息。它是大多数 USB 操作的核心。 -
字段:
dev
: 设备的 Linux 设备结构体,通常包含设备的基本信息,如设备文件系统路径、设备节点等。bus
: 表示该设备所在的 USB 总线,类型为usb_bus
。descriptor
: 存储设备描述符信息(包括设备的类、子类、协议等)。configuration
: 配置描述符,指向当前的配置。maxchild
: 最大子设备数,用于支持 USB 集线器。ep0
: 设备的默认端点 0(控制端点),一个指向usb_endpoint
的指针。
-
联系:
usb_device
是 USB 设备的核心结构体,每个 USB 设备都会有一个usb_device
实例。- 它关联了 USB 总线 (
usb_bus
),描述了 USB 设备的硬件信息,并包含了设备的配置、端点信息等。
2. usb_interface
-
定义:表示设备的一个接口,USB 设备可能有多个接口,每个接口代表了设备的一个功能。
-
字段:
altsetting
: 存储设备接口的替代设置信息,每个接口可以有多个配置,代表不同的操作模式。cur_altsetting
: 当前活动的接口设置。num_altsetting
: 接口设置的数量。dev
: 关联的设备的usb_device
结构体。
-
联系:
- 一个 USB 设备可能有多个接口,每个接口都有自己的接口描述符(如
interface descriptor
)。 - 每个
usb_interface
结构体指向一个usb_device
结构体,表示该接口属于哪个设备。
- 一个 USB 设备可能有多个接口,每个接口都有自己的接口描述符(如
3. usb_endpoint_descriptor
-
定义:表示 USB 端点的描述符,用于描述一个端点的属性(如端点的方向、类型、最大包大小等)。
-
字段:
bEndpointAddress
: 端点的地址(包括方向)。bmAttributes
: 端点的类型(如批量、控制、中断、等时)。wMaxPacketSize
: 最大包大小。bInterval
: 中断传输的间隔(适用于中断端点)。
-
联系:
usb_endpoint_descriptor
与usb_interface_descriptor
紧密相关,因为每个接口都可能有多个端点。- 端点描述符是
usb_interface
的一部分,表示设备与主机之间的数据传输通道。
4. usb_host_interface
-
定义:该结构体表示 USB 主机端的接口信息,通常在 USB 主机驱动中使用。
-
字段:
desc
: 存储 USB 接口描述符,描述接口的类型、功能等。endpoint
: 该接口的所有端点信息。
-
联系:
usb_host_interface
和usb_interface
结构体之间有紧密的联系,因为它们分别代表主机端和设备端的接口信息。
5. usb_driver
-
定义:表示 USB 驱动程序的结构体,用于描述如何与设备交互。
-
字段:
name
: 驱动程序的名称。probe
: 驱动的探测函数,当一个 USB 设备插入时,会调用此函数来匹配设备。disconnect
: 驱动的断开函数,当设备被移除时,调用此函数。id_table
: 设备 ID 表,用于与特定设备匹配。
-
联系:
usb_driver
与usb_device
紧密相关。每当有 USB 设备插入时,驱动程序会根据设备的 ID 信息(如设备描述符)来匹配是否需要该驱动。
6. usb_bus
-
定义:表示一个 USB 总线,包含所有通过该总线连接的 USB 设备。
-
字段:
devices
: 指向该总线连接的设备列表。root_hub
: 表示 USB 总线的根集线器。
-
联系:
usb_device
和usb_bus
之间的关系是每个 USB 设备都属于某个总线。一个总线上可以有多个设备。
7. usb_request
(usb_control_msg
)
-
定义:表示一个 USB 控制请求,用于发起控制传输。
-
字段:
bRequest
: 请求类型。wValue
和wIndex
: 请求参数。data
: 要传输的数据,或者用于接收数据的缓冲区。length
: 数据的长度。
-
联系:
- 控制请求通常通过
usb_device
的端点 0 发送。 usb_request
或usb_control_msg
用于发送控制传输请求,通常是驱动程序向设备发送命令,或获取设备信息。
- 控制请求通常通过
5.2、Linux USB 设备数据结构联系图
+--------------------------+
| usb_device | <---------------------------------------+
|--------------------------| |
| - dev | |
| - bus | |
| - descriptor | |
| - configuration | |
| - ep0 | |
| - maxchild | |
| - ... | |
+--------------------------+ |
| |
v |
+--------------------------+ |
| usb_interface | <---------------------+ |
|--------------------------| | |
| - num_altsetting | | |
| - altsetting | | |
| - dev | | |
| - cur_altsetting | | |
+--------------------------+ | |
| | |
v | |
+---------------------------+ | |
| usb_interface_descriptor | | |
|---------------------------| | |
| - bInterfaceClass | | |
| - bInterfaceSubClass | | |
| - bInterfaceProtocol | | |
| - bNumEndpoints | | |
+---------------------------+ | |
| | |
v | |
+---------------------------+ | |
| usb_endpoint_descriptor | | |
|---------------------------| | |
| - bEndpointAddress | | |
| - bmAttributes | | |
| - wMaxPacketSize | | |
| - bInterval | | |
+---------------------------+ | |
| | |
v | |
+---------------------------+ | |
| usb_endpoint | <--------------------+ |
|---------------------------| |
| - desc | |
| - ep_type | |
| - maxpacket | |
| - transfer_flags | |
+---------------------------+ |
| |
v |
+--------------------------+ |
| usb_driver | |
|--------------------------| |
| - name | |
| - probe | |
| - disconnect | |
| - id_table | |
+--------------------------+ |
| |
v |
+--------------------------+ |
| usb_bus | |
|--------------------------| |
| - devices | |
| - root_hub | |
+--------------------------+ |
说明:
-
usb_device
:- 表示一个 USB 设备,包含设备的基本信息、USB 总线 (
usb_bus
)、接口配置、端点 (ep0
是默认控制端点) 等。每个 USB 设备由usb_device
结构表示,它是其他结构体(如接口、端点)的容器。 - 它是 USB 子系统的核心数据结构,所有的 USB 设备都通过它来管理。
- 表示一个 USB 设备,包含设备的基本信息、USB 总线 (
-
usb_interface
:- 每个 USB 设备可能有多个接口,表示设备的不同功能(例如:音频接口、存储接口等)。每个接口由
usb_interface
结构表示。 - 一个
usb_interface
可以有多个配置(altsetting
),每个配置可能对应不同的工作模式。usb_interface_descriptor
是接口的描述符,包含了接口的基本属性。
- 每个 USB 设备可能有多个接口,表示设备的不同功能(例如:音频接口、存储接口等)。每个接口由
-
usb_endpoint_descriptor
:- 描述设备的端点特性,每个接口可以包含多个端点(用于数据传输)。每个端点的属性(如地址、最大包大小、类型等)通过
usb_endpoint_descriptor
描述。
- 描述设备的端点特性,每个接口可以包含多个端点(用于数据传输)。每个端点的属性(如地址、最大包大小、类型等)通过
-
usb_endpoint
:- 表示端点的实例,包含具体的端点信息(如类型、最大包大小等)。它是与设备进行数据传输的通道。
-
usb_driver
:- USB 驱动程序的数据结构,负责处理设备的探测、断开以及数据传输。驱动程序会在
probe()
函数中与设备进行匹配,并且与设备的usb_device
结构进行交互。
- USB 驱动程序的数据结构,负责处理设备的探测、断开以及数据传输。驱动程序会在
-
usb_bus
:- 每个 USB 总线包含一组设备。
usb_bus
结构包含了与总线相关的设备列表和根集线器。每个设备都会连接到某个 USB 总线。
- 每个 USB 总线包含一组设备。
5.3、主要数据结构之间的关系:
usb_device
和usb_interface
:一个usb_device
可能有多个接口,每个接口由usb_interface
表示。usb_interface
和usb_interface_descriptor
:每个接口都有一个描述符usb_interface_descriptor
,用来描述该接口的属性。usb_interface
和usb_endpoint_descriptor
:每个接口可能有多个端点,它们由usb_endpoint_descriptor
来描述。usb_endpoint
:与usb_endpoint_descriptor
对应,它包含了具体的端点实现和传输相关的信息。usb_driver
:与设备进行交互,并通过usb_device
结构来管理设备的生命周期。usb_bus
:一个usb_device
属于一个usb_bus
,每个总线上可能有多个设备。