http://blog.csdn.net/u011279649/article/details/11059433

USB gadget driver的框架可分为三部分:UDC-core, composite.c and Android.c,其中 composite.c是核心,其他两部分都要bind 到 composit上。

1. UDC-core

结构体usb_gadget中包含指向usb_ep的link head,通过该link head,可以访问
所有的usb_ep, usb_ep中包含了具体的,最终的ops.

这些endpoint的ops是何时赋值的?
我们先看下udc的框架,它提供了一组所有usb device controller都有的属性文件,

static struct class *udc_class;

实现为class属性文件组;通过属性文件可以控制udc如:  softconnect

static struct attribute *usb_udc_attrs[] = {
    &dev_attr_srp.attr,
    &dev_attr_soft_connect.attr,
    &dev_attr_current_speed.attr,
    &dev_attr_maximum_speed.attr,

&dev_attr_is_dualspeed.attr,
    &dev_attr_is_otg.attr,
    &dev_attr_is_a_peripheral.attr,
    &dev_attr_b_hnp_enable.attr,
    &dev_attr_a_hnp_support.attr,
    &dev_attr_a_alt_hnp_support.attr,
    NULL,
};

通过属性文件可以控制udc如:  softconnect

static ssize_t usb_udc_softconn_store(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t n)
{
    struct usb_udc        *udc = container_of(dev, struct usb_udc, dev);

if (sysfs_streq(buf, "connect")) {
        if (udc_is_newstyle(udc))
            usb_gadget_udc_start(udc->gadget, udc->driver);
        usb_gadget_connect(udc->gadget);
    } else if (sysfs_streq(buf, "disconnect")) {
        usb_gadget_disconnect(udc->gadget);
        if (udc_is_newstyle(udc))
            usb_gadget_udc_stop(udc->gadget, udc->driver);
    } else {
        dev_err(dev, "unsupported command '%s'\n", buf);
        return -EINVAL;
    }

return n;
}

另外提供static LIST_HEAD(udc_list);
指向所有的通过函数usb_add_gadget_udc添加的usb_udc,

向外提供了接口函数usb_add_gadget_udc把具体的usb device controller加入到框架中。

函数usb_add_gadget_udc的参数是usb_gadget,此时endpoint的ops已经被赋
值了,可以以此为线索跟踪,就可看明白。

usb_gadget数据结构间的关系:

最上层是usb_udc,

crash> usb_udc
struct usb_udc {
    struct usb_gadget_driver *driver;
    struct usb_gadget *gadget;
    struct device dev;
    struct list_head list;
}
其中包含了 usb_gadget_driver and usb_gadget等

先看usb_gadget_driver,driver不是应该包含怎样操作设备的方法吗?但它的成员只是包含

setup/ suspend/resume等。

usb gadget 的操作方法都是设备本身的属性决定的和自己写的driver没什么关系。但是USB host请求设备描述符等的返回值时,

usb_gadget_driver是可以决定的。

crash> usb_gadget_driver
struct usb_gadget_driver {
    char *function;
    enum usb_device_speed max_speed;
    void (*unbind)(struct usb_gadget *);
    int (*setup)(struct usb_gadget *, const struct usb_ctrlrequest *);
    void (*disconnect)(struct usb_gadget *);
    void (*suspend)(struct usb_gadget *);
    void (*resume)(struct usb_gadget *);
    struct device_driver driver;
}

crash> usb_gadget
struct usb_gadget {
    const struct usb_gadget_ops *ops;
    struct usb_ep *ep0;
    struct list_head ep_list;
    enum usb_device_speed speed;
    enum usb_device_speed max_speed;
    unsigned int sg_supported : 1;
    unsigned int is_otg : 1;
    unsigned int is_a_peripheral : 1;
    unsigned int b_hnp_enable : 1;
    unsigned int a_hnp_support : 1;
    unsigned int a_alt_hnp_support : 1;
    const char *name;
    struct device dev;
}

usb_gadget中包含属性的描述如是否具有OTG功能等,还有怎样使用usb_gadget的方法。方法包含两部分:

1】usb_gadget_ops

crash> usb_gadget_ops
struct usb_gadget_ops {
    int (*get_frame)(struct usb_gadget *);
    int (*wakeup)(struct usb_gadget *);
    int (*set_selfpowered)(struct usb_gadget *, int);
    int (*vbus_session)(struct usb_gadget *, int);
    int (*vbus_draw)(struct usb_gadget *, unsigned int);
    int (*pullup)(struct usb_gadget *, int);
    int (*ioctl)(struct usb_gadget *, unsigned int, unsigned long);
    void (*get_config_params)(struct usb_dcd_config_params *);
    int (*udc_start)(struct usb_gadget *, struct usb_gadget_driver *);
    int (*udc_stop)(struct usb_gadget *, struct usb_gadget_driver *);
    int (*start)(struct usb_gadget_driver *, int (*)(struct usb_gadget *));
    int (*stop)(struct usb_gadget_driver *);
}

2】有关endpoit的操作

crash> usb_ep
struct usb_ep {
    void *driver_data;
    const char *name;
    const struct usb_ep_ops *ops;
    struct list_head ep_list;
    unsigned int maxpacket : 16;
    unsigned int max_streams : 16;
    unsigned int mult : 2;
    unsigned int maxburst : 5;
    u8 address;
    const struct usb_endpoint_descriptor *desc;
    const struct usb_ss_ep_comp_descriptor *comp_desc;
}

crash> usb_ep_ops
struct usb_ep_ops {
    int (*enable)(struct usb_ep *, const struct usb_endpoint_descriptor *);
    int (*disable)(struct usb_ep *);
    struct usb_request *(*alloc_request)(struct usb_ep *, gfp_t);
    void (*free_request)(struct usb_ep *, struct usb_request *);
    int (*queue)(struct usb_ep *, struct usb_request *, gfp_t);
    int (*dequeue)(struct usb_ep *, struct usb_request *);
    int (*set_halt)(struct usb_ep *, int);
    int (*set_wedge)(struct usb_ep *);
    int (*fifo_status)(struct usb_ep *);
    void (*fifo_flush)(struct usb_ep *);
}

2.android.c提供用户设置的功能

android_dev中**functions指向该系统能支持的所有功能,而

Listhead指向所有当前使能的功能;

android_usb_function是怎样加入到usb_configuration中的那?

usb_configuation中的成员为usb_function.

composite/function数据结构间的关系

根据用户需要的功能设置android_dev, 进而得到 usb_composite_dev

crash> android_dev
struct android_dev {
    struct android_usb_function **functions;
    struct list_head enabled_functions;
    struct usb_composite_dev *cdev;
    struct device *dev;
    bool enabled;
    int disable_depth;
    struct mutex mutex;
    bool connected;
    bool sw_connected;
    struct work_struct work;
}

从usb_composite_dev得到所有的 usb_configure, 由struct list_head configs管理:
crash> usb_composite_dev
struct usb_composite_dev {
    struct usb_gadget *gadget;
    struct usb_request *req;
    unsigned int bufsiz;
    struct usb_configuration *config;
    unsigned int suspended : 1;
    struct usb_device_descriptor desc;
    struct list_head configs;
    struct usb_composite_driver *driver;
    u8 next_string_id;
    u8 manufacturer_override;
    u8 product_override;
    u8 serial_override;
    unsigned int deactivations;
    int delayed_status;
    spinlock_t lock;
}

usb_configuration使用struct list_head functions管理所有的usb_function,注意其中的

struct list_head list是为了接收usb_configuration所在链表的管理。

crash> usb_configuration
struct usb_configuration {
    const char *label;
    struct usb_gadget_strings **strings;
    const struct usb_descriptor_header **descriptors;
    void (*unbind)(struct usb_configuration *);
    int (*setup)(struct usb_configuration *, const struct usb_ctrlrequest *);
    u8 bConfigurationValue;
    u8 iConfiguration;
    u8 bmAttributes;
    u8 bMaxPower;
    struct usb_composite_dev *cdev;
    struct list_head list;
    struct list_head functions;
    u8 next_interface_id;
    unsigned int superspeed : 1;
    unsigned int highspeed : 1;
    unsigned int fullspeed : 1;
    struct usb_function *interface[16];
}

struct list_head list是为了接收usb_function所在链表的管理。
crash> usb_function
struct usb_function {
    const char *name;struct list_head list;
    struct usb_gadget_strings **strings;
    struct usb_descriptor_header **descriptors;
    struct usb_descriptor_header **hs_descriptors;
    struct usb_descriptor_header **ss_descriptors;
    struct usb_configuration *config;
    int (*bind)(struct usb_configuration *, struct usb_function *);
    void (*unbind)(struct usb_configuration *, struct usb_function *);
    int (*set_alt)(struct usb_function *, unsigned int, unsigned int);
    int (*get_alt)(struct usb_function *, unsigned int);
    void (*disable)(struct usb_function *);
    int (*setup)(struct usb_function *, const struct usb_ctrlrequest *);
    void (*suspend)(struct usb_function *);
    void (*resume)(struct usb_function *);
    int (*get_status)(struct usb_function *);
    int (*func_suspend)(struct usb_function *, u8);
    struct list_head list;
    unsigned long endpoints[1];
}

3. composite.c

Composite框架要向外提供两类接口:

或者说提供这两点的通用性.

1]用户定义具体的功能;

2]具体的USBdevice controller

从数据结构上看:usb_composite_dev包含在上层提供具体功能的数据结构

android_dev中,usb_composite_dev包含了controller具体的usb_gadget

的成员;

usb_composite_dev中包含了指向所有usb_configuration的linkhead,而

usb_configuration中包含了指向说有usb_function的linkhead.

这里的数据结构的层次,体现了USB的描述的层次关系,注意usb_function中

并没有指向usb_ep的指针。

4.以android.c文件中init函数为线索,看usbgadget driver的初始化过程:

1.所有的usbdevice都会处理setuppacket。函数composite.c提供了一个common的

usb_gadget_driver: composite_driver,用户定义的function可能增加一些处理;

2.android.c文件中提供全局变量

提供了usb_composite_driver , usb_gadget_driver and usb_configure类型的全局变量

drivers/usb/gadget/android.c

struct usb_composite_driver

android_usb_driver = {

.name        = "android_usb",
    .dev        = &device_desc,
    .strings    = dev_strings,
    .unbind        = android_usb_unbind,
    .max_speed    = USB_SPEED_HIGH,
};

static struct usb_configuration

android_config_driver = {
    .label        = "android",
    .unbind        = android_unbind_config,
    .bConfigurationValue = 1,
    .bmAttributes    = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
    .bMaxPower    = 0xFA, /* 500ma */
};

drivers/usb/gadget/composite.c

static struct usb_gadget_driver

composite_driver = {

.unbind        = composite_unbind,

.setup        = composite_setup,
    .disconnect    = composite_disconnect,

.suspend    = composite_suspend,
    .resume        = composite_resume,

.driver    = {
        .owner        = THIS_MODULE,
    },
};

3.调用函数usb_composite_probe(&android_usb_driver,android_bind);把上层android.c

的信息usb_composite_driver类型的android_usb_driver和如何绑定 usb_composite_dev

的函数android_bind 传递到composite.c.

4.usb_composite_probe ->

usb_gadget_probe_driver(&composite_driver,composite_bind);

调用定义在udc-core.c中的函数usb_gadget_probe_driver,把定义在composite.c中的

usb_gadget_driver类型的composite_driver 和如何绑定usb_gadget的函数composite_bind传递到udc-core.c;

5.usb_gadget_probe_driver从udc_list中得到通过usb_add_gadget_udc注册的usb_udc,从

而usb_udc得到usb_gadget,进而调用composite_bind绑定 usb_gadget;

6.composite_bind(usb_gadget)

a.创建了核心usb_composite_dev;

b.调用USBgadget API (就是Endpointops and gadget ops的函数指针封装)处理EP0;

c.调用函数android_bind绑定创建并适当初始化的usb_composite_dev和上层功能配置;

7.android_bind主要调用了函数android_init_functions(android_usb_function,usb_composite_dev);

android_init_functions调用所有支持的android_usb_function的init函数,该函数处理和function具

体相关的初始化;

8.init函数到此就执行完了.

1]

android.c 提供输入参数android_usb_driver and android_bind

struct usb_composite_driver

android_usb_driver = {

.name        = "android_usb",
    .dev        = &device_desc,
    .strings    = dev_strings,
    .unbind        = android_usb_unbind,
    .max_speed    = USB_SPEED_HIGH,
};

and

int android_bind(struct usb_composite_dev *cdev);

1.1] android.c 然后调用定义在文件 composite.c中的函数

usb_composite_probe(&android_usb_driver, android_bind);

2] composite.c会提供输入参数struct usb_gadget_driver composite_driver 和如何绑定 usb_gadget到usb_composite_dev的方法

composite_bind(struct usb_gadget *gadget)。

2.1] composite.c然后调用定义在udc-core.c文件中的函数usb_gadget_probe_driver。

3] 函数usg_gadget_probe_driver从已经注册的udc中得到对应的udc,对udc赋值,并

3.1] 调用composite.c传入的参数composite_bind绑定usb_gadget[udc->usb_gadget]到composite_dev.

4] composite.c实现了函数composite_bind,composite创建了usb_composite_dev, 然后调用了实现在 android.c文件中的函数android_bind。

这个init过程包含两部分:

上层提过输出参数和回调函数先下调用: android.c/ composite.c/ udc-core.c

然后根据回调函数从udc-core.c/composite.c/android.c向上回调。

5.到现在为止,当USBhost发送setuppacket:getconfigure descriptor,怎么上报端点描述符?

端点和接口是怎样绑定的?

我们先来看,USBfunction是怎样设置的?

上层调用sys属性文件function_store->android_enable_function添加android_usb_function

到android_dev:enable_list指向的linklist;

又是如何enableUSB function的那?

enable_store->android_enable(android_dev) ->

usb_add_config(cdev,&android_config_driver,android_bind_config);

把usb_configre加入到usb_composite_dev成员configure_listhead指向的list中,

调用函数android_bind_config绑定enabled的android_usb_function到usb_configure,

其中会调用具体android_usb_function相关的bind_config.

到此,usb_endpoint绑定到usb_interface.

/*调用函数usb_add_config,add了定义在android.c文件中的usb_configuration。又是如何创建usb_function的那?*/

/*usb_add_config调用了来自android.c的函数android_bind_config得到使用android_usb_function
 *描述的功能,调用定义在具体功能的函数如acm_bind_config(struct usb_configuration *c, u8 port_num)
 *最后调用函数int usb_add_function(struct usb_configuration *config,struct usb_function *function)
 *关联usb_function 到usb_configuration.
 *又是哪里关联usb_endpoint到usb_function的哪?
 **/

/*在函数usb_add_function中关联了usb_function和usb_endpoint;
 *调用了具体功能的bind函数如acm_bind
 **/

一个具体的过程:

usb_add_config(cdev,&android_config_driver,android_bind_config);

->android_bind_config

->android_bind_enabled_functions

->android_usb_function: bind_config(android_usb_function,usb_configuration);

->usb_add_function(struct usb_configuration *config,struct usb_function*function)

->usb_function:(*bind)(struct usb_configuration *,structusb_function *);

UDC (usb device controller) Framework - USB gadget driver framework相关推荐

  1. USB gadget driver framework

    USB gadget driver的框架可分为三部分:UDC-core, composite.c and android.c,其中 composite.c是核心,其他两部分都要bind 到 compo ...

  2. S3C2440 WINCE6将USB DEVICE改成USB HOST,实现两个USB HOST

    S3C2440一般默认的是一个USB DEVICE,一个USB HOST,即一个主口,一个从口,先来看看USB Device与USB Host相关知识. USB Host: 最底层就是USB Host ...

  3. 基于s3c6410 otg controller的gadget driver及usb枚举分 析

    一.简介      一个完整的USB系统由两部分构成,即usb主机(usb host)和usb设备(usb device).usb主机通常是指我们的pc机.具有host controller的嵌入式设 ...

  4. USB device USB controller USB passthrough

    近期往 openstack 里倒腾 USB passthrough[1],遂把 USB 知识做较为全面的整理,以供分享. USB device 什么是 USB device, 上图机智的小萌狗就是 U ...

  5. USB OTG(Host) 、 USB ADB(Device)、DWC3 Charge

    USB ADB: Corresponding to USB Device Mode USB OTG: Corresponding to USB Host Mode USB EAP: Correspon ...

  6. 把arm开发板做成USB网卡(RNDIS /Ethernet Gadget)

    /******************************************************* 原文地址: http://hi.baidu.com/deep_pro/item/ec4 ...

  7. USB查看器 USB Device Tree Viewer(UsbTreeView.exe)的使用(重启Intel Realsense摄像头)

    文章目录 简介 打开后界面 测试U盘弹出后是否能找回 测试挽回掉线的摄像头 简介 USB Device Tree Viewer是一个非常实用的USB设备查看器,它可以发现所有的usb接口的使用情况,并 ...

  8. 痞子衡嵌入式:可通过USB Device Path来唯一指定i.MXRT设备进行ROM/Flashloader通信

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是通过USB Device Path来唯一指定i.MXRT设备进行ROM/Flashloader通信. i.MXRT系列高性能微控制器从2 ...

  9. 【USB笔记】 USB设备请求USB Device Requests

    USB笔记 USB设备请求USB Device Requests 所有USB设备都会响应主机向设备默认控制管道(Control Pipe)上发送的请求(requests). 这些请求是使用控制传输(c ...

最新文章

  1. vc++ 动态加载位图
  2. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)
  3. 五种常见粗粮的最佳养生吃法
  4. 银杏谷资本合伙人郑雨林:我为什么围绕阿里云生态做投资?
  5. 土地利用现状图例颜色标准_土地利用现状分类图例
  6. Markdown设置自动生成目录及序号分级标准
  7. blast2go mysql_从 Blast2GO 本地化聊一聊 Linux 下 MySQL 的源码安装
  8. python中forward的参数_pytorch forward两个参数实例
  9. php 微信发红包 证书错误,微信支付,使用证书时出现58错误 - 微信公众平台
  10. Ubuntu20.04安装微信的方法
  11. win7 重装系统变 win10
  12. Android中运行免安装app,适用于免安装应用的 CTS
  13. 关于最近很火的Python圣诞树
  14. EM期望最大化算法实现二项混合分布与高斯混合分布
  15. 服务器显示不兼容这是什么问题,服务器server0处于不兼容的状态,怎么办?
  16. FileZilla Server 中文版
  17. 机器学习分类器模型评价指标
  18. .locked勒索病毒来势汹汹该怎么办?
  19. 什么是SHA256?比特币是如何应用SHA256算法的?
  20. Flask HTML模板引擎详解

热门文章

  1. 电表远程抄表用电数据的问题
  2. 红外额温枪的原理和红外线温度传感器的解析
  3. Win10系统可识别移动硬盘的插入,无法读取移动硬盘的内容,硬盘插入win10无法读取
  4. Masters of Doom
  5. 厦门小鱼论坛的成长历程
  6. 关于文字内容溢出用点点点(…)省略号表示
  7. w7服务器搭建网站教程,w7系统下的云服务器搭建教程
  8. mousedown、mousemove、mouseup实现一个可拖拽的div
  9. Linux下EasyPanel版本安装及升级
  10. 拿不到offer免费学,廖雪峰的“Web 全栈架构师”开班了