usb描述符

在每个usb设备内部,同样也包含了类似于PCI配置寄存器这样的固定格式的数据,通过这些数据,usb主机就可以获取usb设备的类型,生产商等信息。这组固定的数据称为usb描述符。标准的usb设备有5种usb描述符:

设备描述符配置描述符接口描述符端点描述符字符串描述符

一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。


  1. 就像我们平时程序设计经常使用的方法一样,一个对象由一个结构体来表示,但还会再用来一个结构体来描述这个对象的一些属性。usb驱动框架也采用了这样的设计思想,usb框架中每一个组成部分都用两个结构体来描述:一个结构体表示成员组成,另一个结构体表示属性组成。Linux-USB核心定义了4个usb描述符。

  2. struct usb_device  <--->  struct usb_device_descriptor
  3. struct usb_host_config; <--> struct usb_config_descriptor
  4. struct usb_host_interface; <--> struct usb_interface_descriptor
  5. struct usb_host_endpoint; <--> struct usb_endpoint_descriptor

 

由此可见 struct usb_device的名称应该改为 struct usb_host_device


设备描述

linux内核使用struct usb_device来描述一个usb设备

struct usb_device

{

    int        devnum;           usb设备号
    char        devpath [16];     设备id字符串
    enum usb_device_state    state;            设备状态:未连接,已配置
    enum usb_device_speed    speed;          高速,全速,低速

    struct usb_tt    *tt;
    int        ttport;

    unsigned int toggle[2];

    struct usb_device *parent;
    struct usb_bus *bus;
    struct usb_host_endpoint ep0;

    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;

    unsigned short bus_mA;
    u8 portnum;
    u8 level;

    unsigned can_submit:1;
    unsigned discon_suspended:1;
    unsigned persist_enabled:1;
    unsigned have_langid:1;
    unsigned authorized:1;
     unsigned authenticated:1;
    unsigned wusb:1;
    int string_langid;

    /* static strings from the device */
    char *product;
    char *manufacturer;
    char *serial;

    struct list_head filelist;
#ifdef CONFIG_USB_DEVICE_CLASS
    struct device *usb_classdev;
#endif
#ifdef CONFIG_USB_DEVICEFS
    struct dentry *usbfs_dentry;
#endif

    int maxchild;
    struct usb_device *children[USB_MAXCHILDREN];

    int pm_usage_cnt;
    u32 quirks;
    atomic_t urbnum;

    unsigned long active_duration;

#ifdef CONFIG_PM
    struct delayed_work autosuspend;
    struct work_struct autoresume;

    struct mutex pm_mutex;

    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;

};


linux内核使用struct usb_device_descriptor来对应usb描述符中的设备描述符

/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
    __u8  bLength;描述符长度,固定为0x12
    __u8  bDescriptorType;设备描述符类型,固定为0x01

    __le16 bcdUSB;规范发布号。表示本设备能适用哪种协议,如2.0=0200
    __u8  bDeviceClass;类型代码
    __u8  bDeviceSubClass;子类型代码
    __u8  bDeviceProtocol;协议代码
    __u8  bMaxPacketSize0;端点0最大分组大小
    __le16 idVendor;供应商ID
    __le16 idProduct;产品ID,由厂家自行设置
    __le16 bcdDevice;设备出厂编码,由厂家自行设置
    __u8  iManufacturer;厂商描述符字符串索引,索引到对应的字符串描述符。为0表示没有。
    __u8  iProduct;产品描述符字符串索引
    __u8  iSerialNumber;设备序列号字符串索引
    __u8  bNumConfigurations;可能的配置数。
} __attribute__ ((packed));
     按字节对齐

上面的这个结构是根据usb协议而来的

Table 9-8. Standard Device Descriptor


配置描述

linux内核使用struct usb_host_config来描述一个usb配置:

struct usb_host_config{
    struct usb_config_descriptor    desc;     配置描述符

    char *string;        /* iConfiguration string, if present */配置的字符串(如果存在)

    /* List of any Interface Association Descriptors in this
     * configuration. */
    struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];

    /* the interfaces associated with this configuration,
     * stored in no particular order */
    struct usb_interface *interface[USB_MAXINTERFACES];接口链表

    /* Interface information available even when this is not the
     * active configuration */
    struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];

    unsigned char *extra;   /* Extra descriptors */
    int extralen;
};


配置描述

linux内核使用struct usb_config_descriptor来对应usb描述符中的配置描述符

struct usb_config_descriptor {
    __u8  bLength;
    __u8  bDescriptorType;

    __le16 wTotalLength;
    __u8  bNumInterfaces;
    __u8  bConfigurationValue;
    __u8  iConfiguration;
    __u8  bmAttributes;
    __u8  bMaxPower;
} __attribute__ ((packed));

上面的这个结构是根据usb协议而来的

Table 9-10. Standard Configuration Descriptor


接口描述

linux 内核使用struct usb_interface来描述usb接口。

struct usb_interface

{
    /* array of alternate settings for this interface,
     * stored in no particular order */
    struct usb_host_interface *altsetting; 接口设置数组

    struct usb_host_interface *cur_altsetting;    /* the currently当前设置
                     * active alternate setting */
    unsigned num_altsetting;    /* number of alternate settings */设置数

    /* If there is an interface association descriptor then it will list
     * the associated interfaces */
    struct usb_interface_assoc_descriptor *intf_assoc;

    int minor;            /* minor number this interface is
                     * bound to */
    enum usb_interface_condition condition;        /* state of binding */
    unsigned is_active:1;        /* the interface is not suspended */
    unsigned sysfs_files_created:1;    /* the sysfs attributes exist */
    unsigned ep_devs_created:1;    /* endpoint "devices" exist */
    unsigned unregistering:1;    /* unregistration is in progress */
    unsigned needs_remote_wakeup:1;    /* driver requires remote wakeup */
    unsigned needs_altsetting0:1;    /* switch to altsetting 0 is pending */
    unsigned needs_binding:1;    /* needs delayed unbind/rebind */
    unsigned reset_running:1;

    struct device dev;        /* interface specific device info */
    struct device *usb_dev;
    int pm_usage_cnt;        /* usage counter for autosuspend */
    struct work_struct reset_ws;    /* for resets in atomic context */
};


一个配置包含一个或多个接口,一个接口包含一个或多个设置

struct usb_host_interface {
    struct usb_interface_descriptor    desc;接口描述符

    /* array of desc.bNumEndpoint endpoints associated with this
     * interface setting.  these will be in no particular order.
     */
    struct usb_host_endpoint *endpoint;接口包含的端点不包含0号端点,它是控制端点。

    char *string;        /* iInterface string, if present */
    unsigned char *extra;   /* Extra descriptors */
    int extralen;
};


接口描述

struct usb_interface_descriptor {
    __u8  bLength;
    __u8  bDescriptorType;

    __u8  bInterfaceNumber;
    __u8  bAlternateSetting;
    __u8  bNumEndpoints;接口包含的端点个数,不包含0号端点,它是控制端点。
    __u8  bInterfaceClass;
    __u8  bInterfaceSubClass;
    __u8  bInterfaceProtocol;
    __u8  iInterface;
} __attribute__ ((packed));
上面的这个结构是根据usb协议而来的
Table 9-12. Standard Interface Descriptor


端点描述

struct usb_host_endpoint {
    struct usb_endpoint_descriptor    desc;端点描述符
    struct list_head        urb_list;
    void                *hcpriv;
    struct ep_device         *ep_dev;    /* For sysfs info */

    unsigned char *extra;   /* Extra descriptors */
    int extralen;
    int enabled;
};

端点描述

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

Table 9-13. Standard Endpoint Descriptor


struct _STRING_DEscriptOR_STRUCT

{

BYTE bLength; //设备描述符的字节数大小,为0x12

BYTE bDescriptorType; //描述符类型编号,为0x01

BYTE SomeDescriptor[36]; //UNICODE编码的字符串

}

Logo

更多推荐