[Linux 驱动] -- Linux USB 驱动开发(二)------ USB 驱动几个重要数据结构

前面我们学习了 USB 驱动的一个描述符,下面来学习 USB 驱动的几个重要数据结构

 

一、struct usb_interface 接口函数

struct usb_interface
{
    struct usb_host_interface *altsetting;
    
    struct usb_host_interface *cur_altsetting;
    unsigned num_altsetting;
    
    int minor;
    enum usb_interface_condition condition;
    unsigned is_active: 1;
    unsigned needs_remote_wakeup: 1;
    
    struct device dev;
    struct device *usb_dev;
    int pm_usage_cnt;
};

struct usb_interface 中的 struct usb_host_interface *cur_altsetting 成员,表示当前正在使用的设置

1、struct usb_host_interface

struct usb_host_interface 
{
    struct usb_interface_descriptor desc; //usb 描述符,主要有四种 usb 描述符,设备描述符,配置描述符,接口描述符和端点描述符,协议里规定一个 usb 设备是必须支持这四大描述符的。
    //usb 描述符放在 usb 设备的 eeprom 里面
    /* array of desc.bNumEndpoint endpoints associated with this 
     * interface setting. these will be in no particular order.
     */
    struct usb_host_endpoint *endpoint; //这个设置所使用的端点

    char *srting;            /* iInterface string, if present */
    unsigned char *extra;    /* Extra descriptors */ //关于额外描述符
    int extralen;
};

具体到接口描述符,它当然就是描述接口本身的信息的。一个接口可以有多个设置,使用不同的设置,描述接口的信息会有些不同,所以接口描述符并没有放在struct usb_interface 结构里,而是放在表示接口设置的 struct usb_host_interface 结构里。

二、struct usb_host_endpoint 端点函数

struct usb_host_endpoint
{
    struct usb_endpoint_descriptor desc;
    struct list_head    urb_list;    //端点要处理的 urb 队列。urb 是 usb 通信的主角,设备中的每个端点都可以处理一个 urb 队列。要想和你的 usb 通信,就得创建一个 urb,并且为它赋好值,交给咱们的 usb core,它会找到合适的 host controller,从而进行具体的数据传输
    void *hcpriv;    //这是提供给 HCD (host controller dirver) 用的
    struct ep_device  *ep_dev;    /* For sysfs info */

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

三、struct usb_device 设备函数

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,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_ubs *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],359行,ep_out[16],除了端点0,一个设备即使在高速模式下也最多只能再有15个IN端点和15个OUT端点,端点0太特殊了
    struct usb_host_endpoint *ep_out[16]; //对应的管道是Message管道,又能进又能出特能屈能伸的那种,所以这里的ep_in和ep_out数组都有16个值

    char **rawdescriptors;    /* Raw descriptors for each config */
    
    unsigned short bus_mA;    /* Current avilable 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,依此类推

    unsigned discon_suspended:1;  /* Disconnected while suspended */
    unsigned have_langid:1;       /* whether string_langid is valid */
    int string_langid;            /* language ID for strings */

    /* static strings from the device */
    char *product;    /* iProduct string,if present */
    char *manufacturer;    /* iManufacturer string,if present */
    char *serial;        /* iSerialNumber string,if present */
                        //分别用来保存产品、厂商和序列号对应的字符串描述符信息
    struct list_head filelist;

#ifdef CONFIG_USB_DEVICE_CLASS
    struct device *usb_classdev;
#endif

#ifdef CONFIG_USB_DEVICEFS
    struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
#endif

    /*
     * Child devices - these can be either new devices
     * (if this if a hub device),or different instances
     * of this same device.
     * 
     * Each instance needs its own set of data structures.
     */
    
    int maxchild;    /* Number of ports if hub */
    struct usb_device *children[USB_MAXCHILDREN];

    int pm_usage_cnt; /* usage counter for autosuspend */
    u32 quirks;    //quirk就是用来判断这些有毛病的产品啥毛病的

#ifdef CONFIG_PM
    struct delayed_work autosuspend;  /* for delayed autosuspends */
    struct mutex pm_mutex;    /* protects PM  operatinos */
    
    unsigned long last_busy;  /* time of last use */
    int autosuspend_delay;    /* in jiffies */

    unsigned auto_pm: 1;    /* autosuspend/resume in progress */
    unsigned do_remote_wakeup: 1;    /* remote wakeup should be enabled */
    unsigned autosuspend_disabled: 1; /* autosuspend and autoresume */
    unsigned autoresume_disabled: 1; /* disabled by the user */
#endif
};
    

















}

四、struct usb_host_config 配置函数

struct usb_host_config
{
    struct usb_config_descriptor desc;

    char *string;
    
    struct usb_interface *interface[USB_MAXINTERFACES];    //配置所包含的接口,这个数组的顺序未必是按照配置里接口号的顺序
    
    struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];    //usb接口的缓存
    
    unsigned char *extra;
    int extralen;
};

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值