1、usb 设备
1.1 usb_device
// 拓扑重点关注
struct usb_device {
struct usb_host_endpoint ep0; //端点0 的特殊地位决定了它必将受到特殊的待遇,在struct usb_device 对象产生的时候它就要初始化
struct usb_device_descriptor descriptor; /* Descriptor 设备描述符,此结构体的bMaxPacketSize0 filed保存了端点0的maximum packet size*/
struct usb_host_config *config; //设备拥有的所有配置
struct usb_host_config *actconfig; //设备正在使用的配置
struct usb_host_endpoint *ep_in[16]; //ep_in[16],ep_out[16],除了端点0,一个设备即使在高速模式下也最多只能再有15个IN端点和15个OUT端点,端点0太特殊了
struct usb_host_endpoint *ep_out[16]; //对应的管道是Message管道,又能进又能出的那种,所以这里的ep_in和ep_out数组都有16个值
};
// 完整解释
struct usb_device {
int devnum; //devnum 只是usb设备在一条usb总线上的编号.一条usb_bus_type类型的总线上最多可以连上128个设备
char devpath [16]; /* Use in messages: /port/port/...*/ //对于root hub.会将dev->devpath[0]=’0’
enum usb_device_state state; //设备的状态Attached,Powered,Default,Address,Configured,Suspended;
//Attached 表示设备已经连接到usb接口上了,是hub检测到设备时的初始状态。那么这里所谓的USB_STATE_NOTATTACHED就是表示设备并没有Attached。
//Address 状态表示主机分配了一个唯一的地址给设备,此时设备可以使用缺省管道响应主机的请求
//Configured 状态表示设备已经被主机配置过了,也就是协议里说的处理了一个带有非0值的SetConfiguration()请求,此时主机可以使用设备提供的所有功能
//Suspended 挂起状态,为了省电,设备在指定的时间内,3ms吧,如果没有发生总线传输,就要进入挂起状态。此时,usb设备要自己维护包括地址、配置在内的信息
enum usb_device_speed speed; /* high/full/low (or error) */
struct usb_tt *tt; //如果一个高速设备里有这么一个TT,那么就可以连接低速/全速设备,如不然,那低速/全速设备没法用,只能连接到OHCI/UHCI那边出来的hub口里。
int ttport; //如果一个高速设备里有这么一个TT,那么就可以连接低速/全速设备,如不然,那低速/全速设备没法用,只能连接到OHCI/UHCI那边出来的hub口里。
unsigned int toggle[2]; /* one bit for each endpoint //他实际上就是一个位图.IN方向的是toggle[0].OUT方向的是toggle[1].其实,这个数组中的每一位表示ep的toggle值
* ([0] = IN, [1] = OUT) 它里面的每一位表示的就是每个端点当前发送或接收的数据包是DATA0还是DATA1*/
struct usb_device *parent; /* our hub, unless we're the root */
//USB设备是从Root Hub开始,一个一个往外面连的,比如Root Hub有4个口,每个口连一个USB设备,比如其中有一个是Hub,那么这个Hub有可以继续有多个口,于是一级一级的往下连,
//最终连成了一棵树。
struct usb_bus *bus; /* Bus we're part of 设备所在的总线*/
struct usb_host_endpoint ep0; //端点0 的特殊地位决定了她必将受到特殊的待遇,在struct usb_device 对象产生的时候它就要初始化
struct device dev; /* Generic device interface 嵌入到struct usb_device结构里的struct device结构*/
struct usb_device_descriptor descriptor; /* Descriptor 设备描述符,此结构体的bMaxPacketSize0 filed保存了端点0的maximum packet size*/
struct usb_host_config *config; //设备拥有的所有配置
struct usb_host_config *actconfig; //设备正在使用的配置
struct usb_host_endpoint *ep_in[16]; //ep_in[16],ep_out[16],除了端点0,一个设备即使在高速模式下也最多只能再有15个IN端点和15个OUT端点,端点0太特殊了,
struct usb_host_endpoint *ep_out[16]; //对应的管道是Message管道,又能进又能出特能屈能伸的那种,所以这里的ep_in和ep_out数组都有16个值
unsigned short bus_mA; /* Current available from the bus 这个值是在host controller的驱动程序中设置的,通常来讲,计算机的usb端口可以提供500mA的电流*/
u8 portnum; //不管是root hub还是一般的hub,你的USB设备总归要插在一个hub的端口上才能用,portnum就是那个端口号。
u8 level; //层次,也可以说是级别,表征usb设备树的级连关系。Root Hub的level当然就是0,其下面一层就是level 1,再下面一层就是level 2,依此类推
/* static strings from the device */
char *product; /* iProduct string, if present */
char *manufacturer; /* iManufacturer string, if present */
char *serial; /* iSerialNumber string, if present */
//分别用来保存产品、厂商和序列号对应的字符串描述符信息
int maxchild; /* Number of ports if hub */
struct usb_device *children[USB_MAXCHILDREN];
int pm_usage_cnt; /* usage counter for autosuspend */
u32 quirks; //quirk就是用来判断这些有毛病的产品啥毛病的
};
1.2 usb_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));
2、usb 配置
2.1 usb_host_config
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;
};
2.2 usb_config_descriptor
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
3、usb 接口
3.1 usb_interface
struct usb_interface {
struct usb_host_interface *altsetting; // 当前接口的可选设置
struct usb_host_interface *cur_altsetting; // 当前接口使用的设置
unsigned num_altsetting; // 当前接口具有的可选设置总数
int minor; // 当前接口的在主设备号为USB_MAJOR时的子设备号,minor只在USB_MAJOR起作用时起作用。
//usb 设备没有与其它任何子系统关联,就需要在对应驱动的 probe 函数里使用 usb_register_dev 函数来注册并获得主设备号USB_MAJOR。
//如果usb设备关联了其它子系统,则需要在对应驱动的probe函数里使用相应的注册函数,USB_MAJOR 也就该干吗干吗去,用不着它了。
//比如,usb 键盘关联了 input 子系统,驱动对应 drivers/hid/usbhid 目录下的 usbkbd.c文件,
//在它的probe函数里可以看到使用了input_register_device 来注册一个输入设备。
enum usb_interface_condition condition; /* state of binding */ // 当前接口 所处的连接绑定阶段
struct device dev; /* interface specific device info */ // linux设备模型里的device嵌在这儿的对象
struct device *usb_dev; // 当接口使用USB_MAJOR作为主设备号时,usb_dev才会用到, usb_register_dev和usb_deregister_dev使用这个结构体,usb_dev指向的
//就是usb_register_dev函数里创建的usb class device。
}
3.2 usb_host_interface
struct usb_host_interface {
struct usb_interface_descriptor desc;
int extralen;
unsigned char *extra; /* Extra descriptors */
/* array of desc.bNumEndpoints endpoints associated with this
* interface setting. these will be in no particular order.
*/
struct usb_host_endpoint *endpoint;
char *string; /* iInterface string, if present */
};
3.3 usb_interface_descriptor
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
4、usb 端点
4.1 usb_host_endpoint
struct usb_host_endpoint {
struct usb_endpoint_descriptor desc;
struct usb_ss_ep_comp_descriptor ss_ep_comp;
struct usb_ssp_isoc_ep_comp_descriptor ssp_isoc_ep_comp;
struct list_head urb_list;
void *hcpriv;
struct ep_device *ep_dev; /* For sysfs info */
unsigned char *extra; /* Extra descriptors */
int extralen;
int enabled;
int streams;
};
4.2 usb_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));