在USB描述符中,从上到下分为四个层次
USB设备描述符(usb device descriptor)
USB 配置描述符(usbconfig descriptor)
USB接口描述符(usb config descriptor)
USB端点描述符(usb endpoint descriptor)
一个设置描述符可以有多个配置描述符
一个配置描述符可以有多个接口描述符(比如声卡驱动 就有两个接口 录音接口和播放接口)
一个接口描述符可以有多个端点描述符
1. 其中USB设备描述符结构体如下所示
1 struct usb_device_descriptor { 2 __u8 bLength; //本描述符的size 3 __u8 bDescriptorType; //描述符的类型,这里是设备描述符DEVICE 4 __u16 bcdUSB; //指明usb的版本,比如usb2.0 5 __u8 bDeviceClass; //类 6 __u8 bDeviceSubClass; //子类 7 __u8 bDeviceProtocol; //指定协议 8 __u8 bMaxPacketSize0; //端点0对应的最大包大小 9 __u16 idVendor; //厂家ID 10 __u16 idProduct; //产品ID 11 __u16 bcdDevice; //设备的发布号 12 __u8 iManufacturer; //字符串描述符中厂家ID的索引 13 __u8 iProduct; //字符串描述符中产品ID的索引 14 __u8 iSerialNumber; //字符串描述符中设备序列号的索引 15 __u8 bNumConfigurations; //配置描述符的个数,表示有多少个配置描述符 16 } __attribute__ ((packed));
USB设备描述符位于usb设备结构体usb device 中的成员descriptor中
同样的配置接口端点描述符也是位于usb配置接口端点结构体中不过这三个对于我们写驱动的不是很常用。
USB device结构体如下所示:
1 struct usb_device { 2 int devnum; //设备号,是在USB总线的地址 3 char devpath [16]; //用于消息的设备ID字符串 4 enum usb_device_state state; //设备状态:已配置、未连接等等 5 enum usb_device_speed speed; //设备速度:高速、全速、低速或错误 6 7 struct usb_tt *tt; //处理传输者信息;用于低速、全速设备和高速HUB 8 int ttport; //位于tt HUB的设备口 9 10 unsigned int toggle[2]; //每个端点的占一位,表明端点的方向([0] = IN, [1] = OUT) 11 struct usb_device *parent; //上一级HUB指针 12 struct usb_bus *bus; //总线指针 13 struct usb_host_endpoint ep0; //端点0数据 14 struct device dev; //一般的设备接口数据结构 15 16 struct usb_device_descriptor descriptor; //USB设备描述符, 17 struct usb_host_config *config; //设备的所有配置结构体,配置结构体里包含了配置描述符 18 struct usb_host_config *actconfig; //被激活的设备配置 19 struct usb_host_endpoint *ep_in[16]; //输入端点数组 20 struct usb_host_endpoint *ep_out[16]; //输出端点数组 21 22 char **rawdescriptors; //每个配置的raw描述符 23 24 unsigned short bus_mA; //可使用的总线电流 25 26 u8 portnum; //父端口号 27 u8 level; //USB HUB的层数 28 29 unsigned can_submit:1; //URB可被提交标志 30 unsigned discon_suspended:1; //暂停时断开标志 31 unsigned persist_enabled:1; //USB_PERSIST使能标志 32 unsigned have_langid:1; //string_langid存在标志 33 unsigned authorized:1; 34 unsigned authenticated:1; 35 unsigned wusb:1; //无线USB标志 36 int string_langid; //字符串语言ID 37 38 /* static strings from the device */ //设备的静态字符串 39 char *product; //产品名 40 char *manufacturer; //厂商名 41 char *serial; //产品串号 42 43 struct list_head filelist; //此设备打开的usbfs文件 44 #ifdef CONFIG_USB_DEVICE_CLASS 45 struct device *usb_classdev; //用户空间访问的为usbfs设备创建的USB类设备 46 #endif 47 #ifdef CONFIG_USB_DEVICEFS 48 struct dentry *usbfs_dentry; //设备的usbfs入口 49 #endif 50 51 int maxchild; //(若为HUB)接口数 52 struct usb_device *children[USB_MAXCHILDREN];//连接在这个HUB上的子设备 53 int pm_usage_cnt; //自动挂起的使用计数 54 u32 quirks; 55 atomic_t urbnum; //这个设备所提交的URB计数 56 57 unsigned long active_duration; //激活后使用计时 58 59 #ifdef CONFIG_PM //电源管理相关 60 struct delayed_work autosuspend; //自动挂起的延时 61 struct work_struct autoresume; //(中断的)自动唤醒需求 62 struct mutex pm_mutex; //PM的互斥锁 63 64 unsigned long last_busy; //最后使用的时间 65 int autosuspend_delay; 66 unsigned long connect_time; //第一次连接的时间 67 68 unsigned auto_pm:1; //自动挂起/唤醒 69 unsigned do_remote_wakeup:1; //远程唤醒 70 unsigned reset_resume:1; //使用复位替代唤醒 71 unsigned autosuspend_disabled:1; //挂起关闭 72 unsigned autoresume_disabled:1; //唤醒关闭 73 unsigned skip_sys_resume:1; //跳过下个系统唤醒 74 #endif 75 struct wusb_dev *wusb_dev; //(如果为无线USB)连接到WUSB特定的数据结构 76 };
2. 配置描述符结构如下所示
1 struct usb_config_descriptor { 2 __u8 bLength; //描述符的长度 3 __u8 bDescriptorType; //描述符类型的编号 4 5 __le16 wTotalLength; //配置 所返回的所有数据的大小 6 __u8 bNumInterfaces; //配置 所支持的接口个数, 表示有多少个接口描述符 7 __u8 bConfigurationValue; //Set_Configuration命令需要的参数值 8 __u8 iConfiguration; //描述该配置的字符串的索引值 9 __u8 bmAttributes; //供电模式的选择 10 __u8 bMaxPower; //设备从总线提取的最大电流 11 } __attribute__ ((packed));
3. 接口描述符结构如下所示
USB接口只处理一种USB逻辑连接,一个USB接口代表一个逻辑上的设备 比如声卡驱动就有两个接口一个是录音接口另一个是播放接口这个可以再windows系统中看出 有的时候插入一个usb设备后,系统会识别出或各设备并安装相应多个驱动。
1 struct usb_interface_descriptor { 2 __u8 bLength; //描述符的长度 3 __u8 bDescriptorType; //描述符类型的编号 4 5 __u8 bInterfaceNumber; //接口的编号 6 __u8 bAlternateSetting; //备用的接口描述符编号,提供不同质量的服务参数. 7 __u8 bNumEndpoints; //要使用的端点个数(不包括端点0), 表示有多少个端点描述符,比如鼠标就只有一个端点 8 __u8 bInterfaceClass; //接口类型,与驱动的id_table 9 __u8 bInterfaceSubClass; //接口子类型 10 __u8 bInterfaceProtocol; //接口所遵循的协议 11 __u8 iInterface; //描述该接口的字符串索引值 12 } __attribute__ ((packed)
它位于usb_interface->cur_altsetting->desc 这个成员结构体里,
usb_interface结构体如下所示:
1 struct usb_interface { struct usb_host_interface *altsetting; /* 包含所有可用于该接口的可选设置的接口结构数组。每个 struct usb_host_interface 包含一套端点配置(即struct usb_host_endpoint结构所定义的端点配置。这些接口结构没有特别的顺序。*/ 2 struct usb_host_interface *cur_altsetting; /* 指向altsetting内部的指针,表示当前激活的接口配置*/ 3 unsigned num_altsetting; /* 可选设置的数量*/ 4 /* If there is an interface association descriptor then it will list the associated interfaces */ struct usb_interface_assoc_descriptor *intf_assoc; 5 int minor; /* 如果绑定到这个接口的 USB 驱动使用 USB 主设备号, 这个变量包含由 USB 核心分配给接口的次设备号. 这只在一个成功的调用 usb_register_dev后才有效。*/ 6 ... ... 7 }
4 端点描述符结构如下所示:
1 struct usb_endpoint_descriptor { 2 __u8 bLength; //描述符的长度 3 __u8 bDescriptorType; //描述符类型的编号 4 5 __u8 bEndpointAddress; //端点编号,比如端点1,就是1 6 __u8 bmAttributes; //端点的属性, 比如中断传输类型,输入类型 7 __le16 wMaxPacketSize; //一个端点的最大包大小, 8 __u8 bInterval; //间隔时间,用在中断传输上,比如间隔时间查询鼠标的数据 9 10 11 /* NOTE: these two are _only_ in audio endpoints. */ 12 /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ 13 __u8 bRefresh; 14 __u8 bSynchAddress; 15 16 } __attribute__ ((packed));
比如端点0 就位于usb interface->cur_altsetting->desc->endpoint[0].desc
其中endpoint的结构体为usb-host endpoint
1 struct usb_host_endpoint { 2 struct usb_endpoint_descriptor desc; //端点描述符 3 struct usb_ss_ep_comp_descriptor ss_ep_comp;//超快速端点描述符 4 struct list_head urb_list; //本端口对应的urb链表 5 void *hcpriv; 6 struct ep_device *ep_dev; /* For sysfs info */ 7 8 unsigned char *extra; /* Extra descriptors */ 9 int extralen; 10 int enabled;//使能的话urb才能被提交到此端口 11 };