usb驅動結構體分析
1.usb幾個結構體總結
(1)usb_bus_type usb匯流排型別結構體
drivers/usb/core/driver.c
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
};
(2) usb_interface 介面是裝置的介面
struct usb_interface
{
struct usb_host_interface *altsetting;
struct usb_host_interface *cur_altsetting; /* the currently active alternate setting *
}
(3) usb_host_interface 設定是介面的設定
struct usb_host_interface {
struct usb_interface_descriptor desc; //介面描述符
struct usb_host_endpoint *endpoint; //端點結構體
}
(4)usb_host_endpoint 端點結構體 usb資料傳輸的終點
{
struct usb_endpoint_descriptor desc; //端點描述符
}
(5)usb_device usb裝置結構體
struct usb_device
{
struct usb_bus *bus; //匯流排
struct usb_host_endpoint ep0; //端點0
struct usb_device_descriptor descriptor; //裝置描述符
struct usb_host_config *config; //裝置擁有的所有配置
struct usb_host_config *actconfig; // 裝置當前的配置
struct usb_host_endpoint *ep_in[16];
struct usb_host_endpoint *ep_out[16]; //一個裝置在高速模式下最多有15個 ep_in和ep_out端點
}
(6)usb_host_config usb裝置的配置結構體
struct usb_host_config
{
struct usb_config_descriptor desc; //usb配置描述符
}
2.USB描述符
USB描述符資訊儲存在USB裝置中,在列舉過程中,USB主機會向USB裝置傳送GetDescriptor請求,USB裝置在收到這個請求之後,會將USB描述符資訊返回給USB主機,USB主機分析返回來的資料,判斷出該裝置是哪一種USB裝置,建立相應的資料鏈接通道。
通用的USB描述符資訊包括裝置描述符、配置描述符、介面描述符和端點描述符,具體不同的USB裝置還包括其它型別的描述符,例如,USB滑鼠、鍵盤還包括HID描述符和報告描述符,還有可能包括字串描述符。
(1)裝置描述符 struct usb_device_descriptor
(2)配置描述符 struct usb_config_descriptor
(3)介面描述符 struct usb_interface_descriptor
(4)端點描述符 struct usb_endpoint_descriptor
(1)裝置描述符 struct usb_device_descriptor
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
#define USB_DT_DEVICE_SIZE 18
我們的usb裝置描述符的資訊:
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x18d1 Google Inc.
idProduct 0xd002
bcdDevice ff.ff
iManufacturer 5 Android
iProduct 6 Android
iSerial 7 ingenic-halley2_v10-6
bNumConfigurations 1
bLength: 描述符的長度,裝置描述符的長度為18個位元組。
bDescriptorType: 描述符的型別,裝置描述符的型別為0x01。
bcdUSB: USB裝置所遵循的協議版本號,例如2.0協議為0x0200。
bDeviceClass: USB裝置類程式碼,由USB-IF分配,如果該欄位為0x00,表示由介面描述符來指定(有可能該USB裝置是一個複合裝置,USB裝置的各個介面相互獨立,分別屬於不同的裝置類)。如果是0x01~0xfe,表示為USB-IF定義的裝置類,例如0x03為HID裝置,0x09為HUB裝置。如果是0xff,表示由廠商自定義裝置型別。
bDeviceSubClass: USB子類程式碼,由USB-IF分配,如果bDeviceClass為0x00,那麼該欄位也必須為 0x00,其它情況可以參考USB關於對於USB Device Class的定義。
bDeviceProtocol: 協議程式碼,由USB-IF分配,如果bDeviceClass和bDeviceSubClass定義為0x00,那麼該欄位也必須為0x00。
bMaxPacketSize0: 端點0最大資料包長度,必須為8、16、32和64。
idVendor: 廠商ID,由USB-IF分配,需要向USB-IF組織申請。
idProduct: 產品ID,由廠商指定。
bcdDevice: 裝置序列號,由廠商自行設定。
iManufacturer: 用於描述廠商的字串描述符索引。
iProduct: 用於描述產品的字串描述符索引。
iSerialNumber: 用於描述產品序列號的字串描述符索引,注意,所有的字串描述符是可選的,如果沒有字串描述符,指定這些索引為0x00。
bNumConfigurations:配置描述符數量。
(2)配置描述符 struct usb_config_descriptor
一個USB裝置只有一個USB裝置描述符,可以有多個配置描述符
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
#define USB_DT_CONFIG_SIZE 9
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 55
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 500mA
bLength: 配置描述符長度,配置描述符長度為9位元組大小。
bDescriptorType: 描述符型別,配置描述符型別為0x02。
wTotalLength: 配置描述符資訊總的大小,包括介面描述符、端點描述符等等。
bNumInterfaces: USB介面數量。
bConfigurationValue: 當使用SetConfiguration和GetConfiguration請求時所指定的配置索引值。
iConfiguration: 描述配置的字串描述符索引。
bmAttributes: 供電配置,位詳細定義如下:
D7 保留,必須置1
D6 自供電模式
D5 遠端喚醒
D4~D0 保留
bMaxPower: 最大功耗,以2mA為單位,例如0x32為50*2=100mA。
(3)介面描述符 struct usb_interface_descriptor
一個配置中可以有一個或多個介面,一個介面中有0個或多個端點,介面描述符和端點描述符不能直接通過GetDescriptor請求返回,必須連同配置描述符一起返回
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
#define USB_DT_INTERFACE_SIZE 9
Interface Descriptor:(第一個介面描述符)
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2 兩個端點描述符
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk-Only
iInterface 4 Mass Storage
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Interface Descriptor:
bLength: 描述符長度,介面描述符長度為9個位元組。
bDescriptorType: 描述符型別,介面描述符的型別為0x04。
bInterfaceNumber: 該介面編號,介面編號從0開始分配,當一個配置有多個介面時,就用該欄位來區分不同的介面。
bAlternateSetting:
bNumEndpoints: 端點數量,不包括端點0。
bInterfaceClass
bInterfaceSubClass
bInterfaceProtocol: 和裝置描述符中的bDeviceClass、bDeviceSubClass、bDeviceProtocol類似。
iInterface: 描述該介面的字串描述符索引
(4)端點描述符 struct usb_endpoint_descriptor
端點0沒有端點描述符
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__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));
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
Interface Descriptor:(第二個介面描述符)
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 66
bInterfaceProtocol 1
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
bLength: 描述符長度,這裡有兩個值如果是audio裝置的端點,那麼端點描述符長度就為9個位元組,對於其它裝置端點,端點描述符長度就為7個位元組。
bDescriptorType: 描述符型別,端點描述符型別為0x05。
bEndpointAddress: 端點地址,詳細定義如下:
D7 端點方向
0 OUT端點
1 IN端點
D6~D4 保留
D3~D0 端點編號
bmAttributes: 端點型別,詳細定義如下:
D5~D4 用途
00 資料端點
01 反饋端點
10 隱式反饋資料端點
11 保留
D3~D2 同步型別
00 非同步
01 非同步
10 自適應
11 同步
D1~D0 傳輸型別
00 控制傳輸
01 同步傳輸
10 塊傳輸
11 中斷傳輸
如果該端點不是同步端點,D5~D2保留且必須置0。
wMaxPacketSize: 端點所支援最大資料包的長度,詳細定義如下:
D10~D0 最大資料包長度
D12~D11
其餘位保留且必須置0。
bInterval:端點資料傳輸的訪問時間間隔。對於全速/低速的中斷端點,取值範圍為 1~255,對於高速中斷端點,取值範圍為1~16,詳細定義可以參考USB協議。
(5)HID描述符
struct hid_class_descriptor {
__u8 bDescriptorType;
__le16 wDescriptorLength;
} __attribute__ ((packed));
struct hid_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdHID;
__u8 bCountryCode;
__u8 bNumDescriptors;
struct hid_class_descriptor desc[1];
} __attribute__ ((packed));
bLength: 描述符長度。
bDescriptorType:描述符型別,HID描述符的型別為0x21。
bcdHID: 所遵循的HID協議版本。
bCountryCode: 國家程式碼。
bNumDescriptors: 下級描述符數量,通常至少需要一個報告描述符。
bDescriptorType: 下級描述符型別,例如報告描述符。
wDescriptorLength: 下級描述符長度。