本文來自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 [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. 配置描述符結構如下所示:
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才能被提交到此端口 };