2.6 USB摄像头驱动之USB描述符

学习目标:分析USB摄像头驱动的描述符;

一、USB设备描述符

在usb设备驱动分析那一节,也用到了usb描述符。

usb描述符可分为:

USB设备描述符(usb_device_descriptor);

USB配置描述符(usb_config_descriptor);

USB接口描述符(usb_interface_descriptor);

USB端点描述符(usb_endpoint_descriptor);

其中,一个USB设备描述符可以有多个配置描述符;配置描述符可以有多个接口描述符(比如声卡驱动,就有两个接口:录音接口和播放接口);一个接口描述符可以有多个端点描述符。

二、结构体分析

1、USB设备描述符(usb_device_descriptor)

定义

    struct usb_device *dev = interface_to_usbdev(intf);
    struct usb_device_descriptor *descriptor = &dev->descriptor;

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_device结构体下

struct usb_device {
   int devnum;           //设备号,是在USB总线的地址
   char devpath [16];       //用于消息的设备ID字符串
   enum usb_device_state state; //设备状态:已配置、未连接等等
   enum usb_device_speed speed; //设备速度:高速、全速、低速或错误
  
   struct usb_tt *tt;       //处理传输者信息;用于低速、全速设备和高速HUB
   int ttport;           //位于tt HUB的设备口
  
   unsigned int toggle[2];    //每个端点的占一位,表明端点的方向([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[16];     //输入端点数组
   struct usb_host_endpoint *ep_out[16];     //输出端点数组
  
   char **rawdescriptors;             //每个配置的raw描述符
  
   unsigned short bus_mA;         //可使用的总线电流

   u8 portnum;               //父端口号
   u8 level;                //USB HUB的层数
  
   unsigned can_submit:1;         //URB可被提交标志
   unsigned discon_suspended:1;      //暂停时断开标志
   unsigned persist_enabled:1;       //USB_PERSIST使能标志
   unsigned have_langid:1;         //string_langid存在标志
   unsigned authorized:1; 
   unsigned authenticated:1;
   unsigned wusb:1;             //无线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: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;     //(如果为无线USB)连接到WUSB特定的数据结构
  };

2、USB配置描述符(usb_config_descriptor)

变量定义

    struct usb_host_config *hostconfig;
    struct usb_config_descriptor *config;

位于:usb_device结构体下

源码

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_interface_descriptor)

一个USB接口代表一个逻辑上的设备,例如摄像头驱动有两种接口:VC和VS。

定义

  struct usb_interface *intf;

  struct usb_interface_descriptor *interface;

  interface = &intf->altsetting[j].desc; 

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)

4、USB端点描述符(usb_endpoint_descriptor)

定义

    struct usb_endpoint_descriptor  *endpoint;

    endpoint = &intf->altsetting[j].endpoint[m].desc;

源码

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才能被提交到此端口
};
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));

5、接口关联描述符 (Interface Association Descriptor

作用:描述设备功能需要的一个视频控制接口VC和一个或多个视频流接口VS的视频接口集合。

定义

      struct usb_interface_assoc_descriptor *assoc_desc;
           assoc_desc = hostconfig->intf_assoc[0];

源码

/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
struct usb_interface_assoc_descriptor {
 __u8  bLength;         //描述符的长度
 __u8  bDescriptorType;     //描述符类型的编号
 __u8  bFirstInterface;
 __u8  bInterfaceCount;    //接口数目
 __u8  bFunctionClass;           //接口类型,与驱动的id_table 
 __u8  bFunctionSubClass;   //接口子类型
 __u8  bFunctionProtocol;   //接口所遵循的协议
 __u8  iFunction;
} __attribute__ ((packed));

 

posted @ 2019-01-25 17:17  程序猿爱吃鸡  阅读(806)  评论(0编辑  收藏  举报