转自:
http://blog.youkuaiyun.com/lidaqiang99/article/details/6591459
在每个usb设备内部,同样也包含了类似于PCI配置寄存器这样的固定格式的数据,通过这些数据,usb主机就可以获取usb设备的类型,生产商等信息。这组固定的数据称为usb描述符。标准的usb设备有5种usb描述符:
设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。
一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。
-
就像我们平时程序设计经常使用的方法一样,一个对象由一个结构体来表示,但还会再用来一个结
构体来描述这个对象的一些属性。usb驱动框架也采用了这样的设计思想,usb框架中每一个组成部分都用两个结构体来描述:一个结构体表示成员组成,另一
个结构体表示属性组成。Linux-USB核心定义了4个usb描述符。
-
struct usb_device <--->
struct usb_device_descriptor
-
struct usb_host_config; <--> struct usb_config_descriptor
-
struct usb_host_interface; <--> struct usb_interface_descriptor
-
struct usb_host_endpoint; <--> struct usb_endpoint_descriptor
由此可见 struct usb_device的名称应该改为 struct
usb_host_device
设备描述
linux内核使用struct
usb_device来描述一个usb设备
struct usb_device
{
int
devnum;
usb设备号
char
devpath
[16];
设备id字符串
enum
usb_device_state
state;
设备状态:未连接,已配置
enum
usb_device_speed
speed;
高速,全速,低速
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;
usb设备描述符
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;
unsigned
can_submit:1;
unsigned
discon_suspended:1;
unsigned
persist_enabled:1;
unsigned
have_langid:1;
unsigned
authorized:1;
unsigned authenticated:1;
unsigned
wusb:1;
int
string_langid;
char *product;
char *manufacturer;
char *serial;
struct
list_head filelist;
#ifdef CONFIG_USB_DEVICE_CLASS
struct
device *usb_classdev;
#endif
#ifdef CONFIG_USB_DEVICEFS
struct
dentry *usbfs_dentry;
#endif
int
maxchild;
struct
usb_device *children[USB_MAXCHILDREN];
int
pm_usage_cnt;
u32
quirks;
atomic_t
urbnum;
unsigned
long active_duration;
#ifdef CONFIG_PM
struct
delayed_work autosuspend;
struct
work_struct autoresume;
struct mutex pm_mutex;
unsigned long last_busy;
int
autosuspend_delay;
unsigned
long connect_time;
unsigned
auto_pm:1;
unsigned
do_remote_wakeup:1;
unsigned
reset_resume:1;
unsigned
autosuspend_disabled:1;
unsigned
autoresume_disabled:1;
unsigned
skip_sys_resume:1;
#endif
struct
wusb_dev *wusb_dev;
};
linux内核使用struct
usb_device_descriptor来对应usb描述符中的设备描述符
struct usb_device_descriptor {
__u8
bLength;描述符长度,固定为0x12
__u8
bDescriptorType;设备描述符类型,固定为0x01
__le16
bcdUSB;规范发布号。表示本设备能适用哪种协议,如2.0=0200
__u8 bDeviceClass;类型代码
__u8
bDeviceSubClass;子类型代码
__u8 bDeviceProtocol;协议代码
__u8
bMaxPacketSize0;端点0最大分组大小
__le16
idVendor;供应商ID
__le16
idProduct;产品ID,由厂家自行设置
__le16
bcdDevice;设备出厂编码,由厂家自行设置
__u8
iManufacturer;厂商描述符字符串索引,索引到对应的字符串描述符。为0表示没有。
__u8 iProduct;产品描述符字符串索引
__u8
iSerialNumber;设备序列号字符串索引
__u8
bNumConfigurations;可能的配置数。
} __attribute__
((packed));
按字节对齐
上面的这个结构是根据usb协议而来的
Table 9-8. Standard Device
Descriptor
配置描述
linux内核使用struct
usb_host_config来描述一个usb配置:
struct
usb_host_config{
struct
usb_config_descriptor
desc;
配置描述符
char
*string;
配置的字符串(如果存在)
struct
usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];
struct
usb_interface *interface[USB_MAXINTERFACES];接口链表
struct
usb_interface_cache *intf_cache[USB_MAXINTERFACES];
unsigned
char *extra;
int
extralen;
};
配置描述
linux内核使用struct
usb_config_descriptor来对应usb描述符中的配置描述符
struct usb_config_descriptor
{
__u8 bLength;
__u8 bDescriptorType;
__le16
wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
上面的这个结构是根据usb协议而来的
Table 9-10. Standard Configuration
Descriptor
接口描述
linux 内核使用struct
usb_interface来描述usb接口。
struct
usb_interface
{
struct usb_host_interface
*altsetting; 接口设置数组
struct usb_host_interface
*cur_altsetting;
unsigned
num_altsetting;
设置数
struct
usb_interface_assoc_descriptor *intf_assoc;
int
minor;
enum
usb_interface_condition
condition;
unsigned
is_active:1;
unsigned
sysfs_files_created:1;
unsigned
ep_devs_created:1;
unsigned
unregistering:1;
unsigned
needs_remote_wakeup:1;
unsigned
needs_altsetting0:1;
unsigned
needs_binding:1;
unsigned
reset_running:1;
struct
device dev;
struct
device *usb_dev;
int
pm_usage_cnt;
struct
work_struct reset_ws;
};
一个配置包含一个或多个接口,一个接口包含一个或多个设置
struct usb_host_interface {
struct
usb_interface_descriptor
desc;接口描述符
struct
usb_host_endpoint *endpoint;接口包含的端点不包含0号端点,它是控制端点。
char
*string;
unsigned
char *extra;
int
extralen;
};
接口描述
struct usb_interface_descriptor
{
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;接口包含的端点个数,不包含0号端点,它是控制端点。
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
上面的这个结构是根据usb协议而来的
Table 9-12. Standard Interface Descriptor
端点描述
struct usb_host_endpoint {
struct
usb_endpoint_descriptor
desc;端点描述符
struct
list_head
urb_list;
void
*hcpriv;
struct
ep_device
*ep_dev;
unsigned
char *extra;
int
extralen;
int
enabled;
};
端点描述
struct
usb_endpoint_descriptor
{
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16
wMaxPacketSize;
__u8 bInterval;
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
Table 9-13. Standard Endpoint
Descriptor
struct _STRING_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小,为0x12
BYTE bDescriptorType; //描述符类型编号,为0x01
BYTE SomeDescriptor[36]; //UNICODE编码的字符串
}