1. 程式人生 > >usb驅動結構體分析

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: 下級描述符長度。