上一篇谈到了usb host以及usb core,这一篇来介绍下usb gadget,usb gadget较usb host出现较晚,随着linux越来越用作嵌入式设备而出现,是一套独立的架构,独立于usb core。
由上图可以看出gadget架构有两个核心抽象层,composite framework和udc core。
composite framework: 由写一个gadget driver需要处理的一些common部分抽象而成,如:ep0 common部分处理(与硬件无关的部分),get descriptor,set configuration等。
由于要处理set configuration,所以composite framework需要知道usb的config以及添加进来的function(usb interface)。
核心函数如下:
usb_compostie_probe: 提供给上层的接口,用来注册一个usb composite driver,上图中的android, serial, usb massstorage都是composite driver
usb_add_config: 添加一个config
usb_add_function: 添加一个function(interface), 如adb,mass storage,serial,rndis。
composite_setup: 处理ep0的setup请求
udc core: 由每一个usd device controller需要提供给composite framework的接口抽象而成,这样usb devcie controller部分就只需要focus在与硬件相关的部分
下面我们以android为例来追一下具体的调用流程
android的init模块会调用 usb_composite_probe(&android_usb_driver, android_bind);
1772 int usb_composite_probe(struct usb_composite_driver *driver,
1773 int (*bind)(struct usb_composite_dev *cdev))
1774 {
1775 int rc;
1776 if (!driver || !driver->dev || !bind || composite)
1777 return -EINVAL;
1778
1779 if (!driver->name)
1780 driver->name = "composite";
1781 if (!driver->iProduct)
1782 driver->iProduct = driver->name;
1783 composite_driver.function = (char *) driver->name;
1784 composite_driver.driver.name = driver->name;
1785 composite_driver.max_speed =
1786 min_t(u8, composite_driver.max_speed, driver->max_speed);
1787 composite = driver;
1788 composite_gadget_bind = bind;
1789 rc = switch_dev_register(&compositesdev);
1790 INIT_WORK(&cdusbcmdwork, ctusbcmd_do_work);
1791 if (rc < 0)
1792 pr_err("%s: switch_dev_register fail", __func__);
1793
1794 return usb_gadget_probe_driver(&composite_driver, composite_bind);
1795 }
从代码中可以看出,usb_composite_probe主要是将注册进来的usb_composite_driver(这里是android_usb_driver)与usb_gadget_driver(这里是composite_driver)联系起来,然后调