2.6 USB攝像頭驅動之USB描述符

學習目標:分析USB攝像頭驅動的描述符;數組

1、USB設備描述符數據結構

在usb設備驅動分析那一節,也用到了usb描述符。學習

usb描述符可分爲:ui

USB設備描述符(usb_device_descriptor);atom

USB配置描述符(usb_config_descriptor);spa

USB接口描述符(usb_interface_descriptor);指針

USB端點描述符(usb_endpoint_descriptor);code

其中,一個USB設備描述符能夠有多個配置描述符;配置描述符能夠有多個接口描述符(好比聲卡驅動,就有兩個接口:錄音接口和播放接口);一個接口描述符能夠有多個端點描述符。視頻

2、結構體分析blog

一、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特定的數據結構
  };

二、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));

三、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)

四、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));

五、接口關聯描述符 (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));
相關文章
相關標籤/搜索