上一篇谈到了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)联系起来,然后调用udc core提供的函数:usb_gadget_probe_driver,并提供callback function: composite_bind给udc core.
先来看composite_bind
1576 static int composite_bind(struct usb_gadget *gadget)
1577 {
1578 struct usb_composite_dev *cdev;
1579 int status = -ENOMEM;
1580
1581 cdev = kzalloc(sizeof *cdev, GFP_KERNEL);
1582 if (!cdev)
1583 return status;
1584
1585 spin_lock_init(&cdev->lock);
1586 cdev->gadget = gadget;
1587 set_gadget_data(gadget, cdev);
1588 INIT_LIST_HEAD(&cdev->configs);
1589
1590 /* preallocate control response and buffer */
1591 cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
1592 if (!cdev->req)
1593 goto fail;
1594 cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
1595 if (!cdev->req->buf)
1596 goto fail;
1597 cdev->req->complete = composite_setup_complete;
1598 gadget->ep0->driver_data = cdev;
1599
1600 cdev->bufsiz = USB_BUFSIZ;
1601 cdev->driver = composite;
1602
1603 INIT_DELAYED_WORK(&cdev->request_reset, composite_request_reset);
1604 /*
1605 * As per USB compliance update, a device that is actively drawing
1606 * more than 100mA from USB must report itself as bus-powered in
1607 * the GetStatus(DEVICE) call.
1608 */
1609 if (CONFIG_USB_GADGET_VBUS_DRAW <= USB_SELF_POWER_VBUS_MAX_DRAW)
1610 usb_gadget_set_selfpowered(gadget);
1611
1612 /* interface and string IDs start at zero via kzalloc.
1613 * we force endpoints to start unassigned; few controller
1614 * drivers will zero ep->driver_data.
1615 */
1616 usb_ep_autoconfig_reset(cdev->gadget);
1617
1618 /* composite gadget needs to assign strings for whole device (like
1619 * serial number), register function drivers, potentially update
1620 * power state and consumption, etc
1621 */
1622 status = composite_gadget_bind(cdev);
1623 if (status < 0)
1624 goto fail;
1625
1626 cdev->desc = *composite->dev;
1627
1628 /* standardized runtime overrides for device ID data */
1629 if (idVendor)
1630 cdev->desc.idVendor = cpu_to_le16(idVendor);
1631 if (idProduct)
1632 cdev->desc.idProduct = cpu_to_le16(idProduct);
1633 if (bcdDevice)
1634 cdev->desc.bcdDevice = cpu_to_le16(bcdDevice);
1635
1636 /* string overrides */
1637 if (iManufacturer || !cdev->desc.iManufacturer) {
1638 if (!iManufacturer && !composite->iManufacturer &&
1639 !*composite_manufacturer)
1640 snprintf(composite_manufacturer,
1641 sizeof composite_manufacturer,
1642 "%s %s with %s",
1643 init_utsname()->sysname,
1644 init_utsname()->release,
1645 gadget->name);
1646
1647 cdev->manufacturer_override =
1648 override_id(cdev, &cdev->desc.iManufacturer);
1649 }
1650
1651 if (iProduct || (!cdev->desc.iProduct && composite->iProduct))
1652 cdev->product_override =
1653 override_id(cdev, &cdev->desc.iProduct);
1654
1655 if (iSerialNumber)
1656 cdev->serial_override =
1657 override_id(cdev, &cdev->desc.iSerialNumber);
1658
1659 /* has userspace failed to provide a serial number? */
1660 if (composite->needs_serial && !cdev->desc.iSerialNumber)
1661 WARNING(cdev, "userspace failed to provide iSerialNumber
");
1662
1663 /* finish up */
1664 status = device_create_file(&gadget->dev, &dev_attr_suspended);
1665 if (status)
1666 goto fail;
1667
1668 INFO(cdev, "%s ready
", composite->name);
1669 return 0;
1670
1671 fail:
1672 composite_unbind(gadget);
1673 return status;
1674 }
可以看出,composite_bind一开始就新建usb_composite_dev并建立usb_gadget与usb_composite_dev的关系。接下来,usb_ep_alloc_request(gadget->ep0) 分配ep0 usb request.
cdev->driver = composite, 这里指定usb_composite_dev的driver为usb_composite_probe注册进来的usb_composite_driver: android_usb_driver
status = composite_gadget_bind(cdev); 这里调用的是usb_composite_probe传进来的android_bind,android_bind会调用usb_add_config来添加config。具体的每一个function的添加会在调用usb_add_config时传进来的callback function中完成(这里是android_bind_config,这个函数会调用每一个需要添加的function的bind_config, 而bind_config调用的是usb_add_function)
接下来我们看 usb_gadget_probe_driver,这个函数主要调用usb_gadget_start
119 static inline int usb_gadget_start(struct usb_gadget *gadget,
120 struct usb_gadget_driver *driver,
121 int (*bind)(struct usb_gadget *))
122 {
123 return gadget->ops->start(driver, bind);
124
可以看出这个函数是udc core层实现的一个接口函数,具体实现在对应的usb device controller中
从参数可以看出,这个函数会将usb_gadget_driver和usb_gadget对应起来,并调用bind(这里为composite_bind,前面已经介绍过了他的作用)。
到这里,上图中的所有模块就已经介绍完了,对于整个gadget大体也有一个概念,不过疑问也来了,这里只涉及到了ep0,别的endpoind如何处理呢?
下面我们以adb为例做个简单的介绍
在composite_bind中有提到,他会调用到每一个需要添加的function的bind_config,adb算是其中一个function,那么我们从adb的bind_config看起。
629 static int adb_bind_config(struct usb_configuration *c)
630 {
631 struct adb_dev *dev = _adb_dev;
632
633 printk(KERN_INFO "adb_bind_config
");
634
635 dev->cdev = c->cdev;
636 dev->function.name = "adb";
637 dev->function.descriptors = fs_adb_descs;
638 dev->function.hs_descriptors = hs_adb_descs;
639 dev->function.bind = adb_function_bind;
640 dev->function.unbind = adb_function_unbind;
641 dev->function.set_alt = adb_function_set_alt;
642 dev->function.disable = adb_function_disable;
643
644 return usb_add_function(c, &dev->function);
645 }
可以看到正如我们前面所说,这里会调用usb_add_function,在usb_add_function中会调用function.bind,也就是adb_function_bind。
525 static int
526 adb_function_bind(struct usb_configuration *c, struct usb_function *f)
527 {
528 struct usb_composite_dev *cdev = c->cdev;
529 struct adb_dev *dev = func_to_adb(f);
530 int id;
531 int ret;
532
533 dev->cdev = cdev;
534 DBG(cdev, "adb_function_bind dev: %p
", dev);
535
536 /* allocate interface ID(s) */
537 id = usb_interface_id(c, f);
538 if (id < 0)
539 return id;
540 adb_interface_desc.bInterfaceNumber = id;
541
542 /* allocate endpoints */
543 ret = adb_create_bulk_endpoints(dev, &adb_fullspeed_in_desc,
544 &adb_fullspeed_out_desc);
545 if (ret)
546 return ret;
547
548 /* support high speed hardware */
549 if (gadget_is_dualspeed(c->cdev->gadget)) {
550 adb_highspeed_in_desc.bEndpointAddress =
551 adb_fullspeed_in_desc.bEndpointAddress;
552 adb_highspeed_out_desc.bEndpointAddress =
553 adb_fullspeed_out_desc.bEndpointAddress;
554 }
555
556 DBG(cdev, "%s speed %s: IN/%s, OUT/%s
",
557 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
558 f->name, dev->ep_in->name, dev->ep_out->name);
559 return 0;
560 }
可以看出主要的调用是 adb_create_bulk_endpoints
226 static int adb_create_bulk_endpoints(struct adb_dev *dev,
227 struct usb_endpoint_descriptor *in_desc,
228 struct usb_endpoint_descriptor *out_desc)
229 {
230 struct usb_composite_dev *cdev = dev->cdev;
231 struct usb_request *req;
232 struct usb_ep *ep;
233 int i;
234
235 DBG(cdev, "create_bulk_endpoints dev: %p
", dev);
236
237 ep = usb_ep_autoconfig(cdev->gadget, in_desc);
238 if (!ep) {
239 DBG(cdev, "usb_ep_autoconfig for ep_in failed
");
240 return -ENODEV;
241 }
242 DBG(cdev, "usb_ep_autoconfig for ep_in got %s
", ep->name);
243 ep->driver_data = dev; /* claim the endpoint */
244 dev->ep_in = ep;
245
246 ep = usb_ep_autoconfig(cdev->gadget, out_desc);
247 if (!ep) {
248 DBG(cdev, "usb_ep_autoconfig for ep_out failed
");
249 return -ENODEV;
250 }
251 DBG(cdev, "usb_ep_autoconfig for adb ep_out got %s
", ep->name);
252 ep->driver_data = dev; /* claim the endpoint */
253 dev->ep_out = ep;
254
255 /* now allocate requests for our endpoints */
256 req = adb_request_new(dev->ep_out, ADB_BULK_BUFFER_SIZE);
257 if (!req)
258 goto fail;
259 req->complete = adb_complete_out;
260 dev->rx_req = req;
261
262 for (i = 0; i < TX_REQ_MAX; i++) {
263 req = adb_request_new(dev->ep_in, ADB_BULK_BUFFER_SIZE);
264 if (!req)
265 goto fail;
266 req->complete = adb_complete_in;
267 adb_req_put(dev, &dev->tx_idle, req);
268 }
269
270 return 0;
271
272 fail:
273 printk(KERN_ERR "adb_bind() could not allocate requests
");
274 return -1;
275 }
从这个函数可以看出function如何与gadget建立关系
1. 通过usb_ep_autoconfig(cdev->gadget, in_desc)分配gadget初始化注册的endpoint
2. 通过adb_request_new(主要调用usb_ep_alloc_request)来分配对应的endpoint的request
3. req->complete = adb_complete_out 指定request的complete函数,这个函数会在usb device controller对应的endpoint收发中断完成之后被调用