本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aaa6695798/archive/2009/11/06/4776202.aspx


在USB描述符中,从上到下分为四个层次:

USB设备描述符(usb_device_descriptor)、

USB配置描述符(usb_config_descriptor)、

USB接口描述符(usb_interface_descriptor)、

USB端点描述符(usb_endpoint_descriptor)、

一个设置描述符可以有多个配置描述符

一个配置描述符可以有多个接口描述符(比如声卡驱动,就有两个接口:录音接口和播放接口)

一个接口描述符可以有多个端点描述符

1.其中USB设备描述符结构体如下所示:

struct usb_device_descriptor {
__u8 bLength; //本描述符的size
__u8 bDescriptorType; //描述符的类型,这里是设备描述符DEVICE
__u16 bcdUSB; //指明usb的版本,比如usb2.0
__u8 bDeviceClass; //类
__u8 bDeviceSubClass; //子类
__u8 bDeviceProtocol; //指定协议
__u8 bMaxPacketSize0; //端点0对应的最大包大小
__u16 idVendor; //厂家ID
__u16 idProduct; //产品ID
__u16 bcdDevice; //设备的发布号
__u8 iManufacturer; //字符串描述符中厂家ID的索引
__u8 iProduct; //字符串描述符中产品ID的索引
__u8 iSerialNumber; //字符串描述符中设备序列号的索引
__u8 bNumConfigurations; //配置描述符的个数,表示有多少个配置描述符
} __attribute__ ((packed));

USB设备描述符位于USB设备结构体usb_device中的成员descriptor中

同样地,配置、接口、端点描述符也是位于USB配置、接口、端点结构体中,不过这3个对于我们写驱动的不是很常用

usb_device结构体如下所示:

struct usb_device {
   int devnum;           //设备号,是在USB总线的地址
   char devpath [];       //用于消息的设备ID字符串
   enum usb_device_state state; //设备状态:已配置、未连接等等
   enum usb_device_speed speed; //设备速度:高速、全速、低速或错误
  
   struct usb_tt *tt;       //处理传输者信息;用于低速、全速设备和高速HUB
   int ttport;           //位于tt HUB的设备口
  
   unsigned int toggle[];    //每个端点的占一位,表明端点的方向([0] = IN, [1] = OUT)  
   struct usb_device *parent;  //上一级HUB指针
   struct usb_bus *bus;       //总线指针
   struct usb_host_endpoint ep0; //端点0数据
   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[];     //输入端点数组
   struct usb_host_endpoint *ep_out[];     //输出端点数组
  
   char **rawdescriptors;             //每个配置的raw描述符
  
   unsigned short bus_mA;         //可使用的总线电流    u8 portnum;               //父端口号
   u8 level;                //USB HUB的层数
  
   unsigned can_submit:;         //URB可被提交标志
   unsigned discon_suspended:;      //暂停时断开标志
   unsigned persist_enabled:;       //USB_PERSIST使能标志
   unsigned have_langid:;         //string_langid存在标志
   unsigned authorized:;
   unsigned authenticated:;
   unsigned wusb:;             //无线USB标志
   int string_langid;             //字符串语言ID
  
   /* static strings from the device */ //设备的静态字符串
   char *product;               //产品名
   char *manufacturer;             //厂商名
   char *serial;                 //产品串号
  
   struct list_head filelist;         //此设备打开的usbfs文件
  #ifdef CONFIG_USB_DEVICE_CLASS
   struct device *usb_classdev;       //用户空间访问的为usbfs设备创建的USB类设备
  #endif
  #ifdef CONFIG_USB_DEVICEFS
   struct dentry *usbfs_dentry;        //设备的usbfs入口
  #endif
  
   int maxchild;                     //(若为HUB)接口数
   struct usb_device *children[USB_MAXCHILDREN];//连接在这个HUB上的子设备
   int pm_usage_cnt;                 //自动挂起的使用计数
   u32 quirks;
   atomic_t urbnum;                   //这个设备所提交的URB计数
  
   unsigned long active_duration;         //激活后使用计时   #ifdef CONFIG_PM                 //电源管理相关
   struct delayed_work autosuspend;       //自动挂起的延时
   struct work_struct autoresume;       //(中断的)自动唤醒需求
   struct mutex pm_mutex;           //PM的互斥锁 
 
   unsigned long last_busy;         //最后使用的时间
   int autosuspend_delay;
   unsigned long connect_time;       //第一次连接的时间
  
   unsigned auto_pm:;           //自动挂起/唤醒
   unsigned do_remote_wakeup:;     //远程唤醒
   unsigned reset_resume:;       //使用复位替代唤醒
   unsigned autosuspend_disabled:;   //挂起关闭
   unsigned autoresume_disabled:;   //唤醒关闭
   unsigned skip_sys_resume:;     //跳过下个系统唤醒
  #endif
   struct wusb_dev *wusb_dev;     //(如果为无线USB)连接到WUSB特定的数据结构
  };

2. 配置描述符结构如下所示:

 struct usb_config_descriptor {
__u8 bLength; //描述符的长度
__u8 bDescriptorType; //描述符类型的编号 __le16 wTotalLength; //配置 所返回的所有数据的大小
__u8 bNumInterfaces; //配置 所支持的接口个数, 表示有多少个接口描述符
__u8 bConfigurationValue; //Set_Configuration命令需要的参数值
__u8 iConfiguration; //描述该配置的字符串的索引值
__u8 bmAttributes; //供电模式的选择
__u8 bMaxPower; //设备从总线提取的最大电流
} __attribute__ ((packed));

3.接口描述符结构如下所示: 

USB接口只处理一种USB逻辑连接。一个USB接口代表一个逻辑上的设备,比如声卡驱动,就有两个接口:录音接口和播放接口

这可以在windows系统中看出,有时插入一个USB设备后,系统会识别出多个设备,并安装相应多个的驱动。

 struct usb_interface_descriptor {
__u8 bLength; //描述符的长度
__u8 bDescriptorType; //描述符类型的编号 __u8 bInterfaceNumber; //接口的编号
__u8 bAlternateSetting; //备用的接口描述符编号,提供不同质量的服务参数.
__u8 bNumEndpoints; //要使用的端点个数(不包括端点0), 表示有多少个端点描述符,比如鼠标就只有一个端点
__u8 bInterfaceClass; //接口类型,与驱动的id_table
__u8 bInterfaceSubClass; //接口子类型
__u8 bInterfaceProtocol; //接口所遵循的协议
__u8 iInterface; //描述该接口的字符串索引值
} __attribute__ ((packed)

它位于usb_interface->cur_altsetting->desc 这个成员结构体里,

 usb_interface结构体如下所示:

struct usb_interface { 
struct usb_host_interface *altsetting; /* 包含所有可用于该接口的可选设置的接口结构数组。每个 struct usb_host_interface 包含一套端点配置(即struct usb_host_endpoint结构所定义的端点配置。这些接口结构没有特别的顺序。*/

struct usb_host_interface *cur_altsetting; /* 指向altsetting内部的指针,表示当前激活的接口配置*/

unsigned num_altsetting; /* 可选设置的数量*/

/* If there is an interface association descriptor then it will list the associated interfaces */
struct usb_interface_assoc_descriptor *intf_assoc; int minor; /* 如果绑定到这个接口的 USB 驱动使用 USB 主设备号, 这个变量包含由 USB 核心分配给接口的次设备号. 这只在一个成功的调用 usb_register_dev后才有效。*/
... ...
}

cur_altsetting成员的结构体是usb_host_interface,如下: 

struct usb_host_interface {
struct usb_interface_descriptor desc; //当前被激活的接口描述符
struct usb_host_endpoint *endpoint;   /* 这个接口的所有端点结构体的联合数组*/
char *string;                /* 接口描述字符串 */
unsigned char *extra;           /* 额外的描述符 */
int extralen;
};

4.端点描述符结构如下所示:

struct usb_endpoint_descriptor {
__u8 bLength; //描述符的长度
__u8 bDescriptorType; //描述符类型的编号 __u8 bEndpointAddress; //端点编号,比如端点1,就是1
__u8 bmAttributes; //端点的属性, 比如中断传输类型,输入类型
__le16 wMaxPacketSize; //一个端点的最大包大小,
__u8 bInterval; //间隔时间,用在中断传输上,比如间隔时间查询鼠标的数据 /* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress; } __attribute__ ((packed));

比如端点0,就位于usb_interface->cur_altsetting->desc->endpoint[0].desc

其中endpoint的结构体为usb_host_endpoint,如下所示:

struct usb_host_endpoint {
struct usb_endpoint_descriptor desc; //端点描述符
struct usb_ss_ep_comp_descriptor ss_ep_comp;//超快速端点描述符
struct list_head urb_list; //本端口对应的urb链表
void *hcpriv;
struct ep_device *ep_dev; /* For sysfs info */ unsigned char *extra; /* Extra descriptors */
int extralen;
int enabled;//使能的话urb才能被提交到此端口
};

USB_4大描述符的更多相关文章

  1. python2.7高级编程 笔记二(Python中的描述符)

    Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...

  2. 【python】描述符descriptor

    开始看官方文档,各种看不懂,只看到一句Properties, bound and unbound methods, static methods, and class methods are all ...

  3. Python描述符(descriptor)解密(转)

    原文:http://www.geekfan.net/7862/ Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装 ...

  4. linux专题一之文件描述符、重定向、管道符、tee命令

    本节讨论一下几个问题: 1. 文件描述符. 2. 重定向. 3. 管道符 4. tee的用法. 1. 文件描述符. 在linux系统中一切皆文件.文件夹和设备都是文件.如何用来区别不同的文件呢?这里的 ...

  5. CentOS最大文件描述符限制更改

    系统级的限制:/proc/sys/fs/file-max中设定了系统最大能打开的文件数. 查看该值可以用如下方式: [root@#panda ~]# cat /proc/sys/fs/file-max ...

  6. 自己总结的USB数据结构及其描述符

    背景: USB理论知识光看着空想总觉着丢三落四,好像哪里没法理解到位,自己做个总结. 正文: 1. USB通信的最基本单位是“包”.如果把“包”肢解的话,可以分为各种“域”(7类,即一串二进制数.每类 ...

  7. [转]jni数据类型映射、域描述符说明

    在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与Java比较起来,其范围更具严格性,如下: 1.primitive types ---- ...

  8. Linux中断技术、门描述符、IDT(中断描述符表)、异常控制技术总结归类

    相关学习资料 <深入理解计算机系统(原书第2版)>.pdf http://zh.wikipedia.org/zh/%E4%B8%AD%E6%96%B7 独辟蹊径品内核:Linux内核源代码 ...

  9. Python 描述符(descriptor) 杂记

    转自:https://blog.tonyseek.com/post/notes-about-python-descriptor/ Python 引入的“描述符”(descriptor)语法特性真的很黄 ...

随机推荐

  1. Redis宕机的问题

    在主从模式下宕机要分为区分来看: slave从redis宕机 ​ 在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据: ​ 如果从数据库实现了持久化,只要重新假如到主从架构中会实现增 ...

  2. 进程间通讯:有名管道FIFO

    接收端: #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include < ...

  3. 使用JSch远程执行shell命令

    package com.nihaorz.jsch; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import ...

  4. linux常用命令(个人总结)

    1.快捷键: ctrl + l           --------------------清屏 ctrl + c          --------------------退出当前命令 ctrl + ...

  5. npm、webpack、vue-cli

    Node.js   npm 什么是Node.js  以及npm 简单的来说 Node.js 就是运行在服务端的JavaScript,基于Chrome V8 引擎的. npm 是Node.js 的包管理 ...

  6. ElasticHD Windows环境下安装

    ElasticHD Linux环境下安装教程        ElasticHD windows环境下安装教程   习惯了T-SQL 查询,Elasticsearch的DSL查询语法简直就是反人类呀,一 ...

  7. Paths on a Grid POJ - 1942 组合数学 (组合数的快速计算)

    题意:格路问题 没什么难度 难点在于如何快速计算相对较大的组合数 思路:运用手写计算组合数的方式进行计算  如c(8,3) 如果手算就是   8*7*6/(3*2*1)这样可以很快得解出 计算代码为: ...

  8. P2084 进制转换

    原题链接 https://www.luogu.org/problemnew/show/P2084 这个题的思路就是先将输入的数字存到字符数组里,然后求出这一串数字中的非0元素的个数total,并记录最 ...

  9. 【BZOJ1578】【USACO2009Feb】股票市场 背包DP

    题目大意 告诉你\(n\)只股票在这\(m\)天内的价格,给你\(s\)元的初始资金,问你\(m\)天后你最多拥有多少钱. \(n\leq 50,m\leq 10,s\leq 200000,\)答案\ ...

  10. LOJ#2019. 「AHOI / HNOI2017」影魔

    题意: 在一个序列中 如果有一个子区间 它有一个端点是区间最大值 另一个端点不是这个区间的次大值 就会有p2的贡献 它两个端点分别是最大值次大值 就会有p1的贡献 我们发现这两个条件有一个重合的部分 ...