继Linux Gadget的一点研究后陆续续关注了很久Android USB Gadget,一直想写点什么记录一些认识,可是Linux USB实在是太复杂,让人有点无从下笔的感觉。它的复杂并不是说不可以被人理解,而且涉及的面很广。USB Host的驱动关注比较少,就对USB device驱动的认识来说,需从两大方面去对它进行认识和了解,一方面是USB协议本身,如果连USB端点、设备描述符、接口、复合设备等概念都不清楚的话,那是无法理解Linux USB device驱动的;另外方面就是USB Gadget架构。而本文就是基于对USB Gadget架构的一点认识而记录的。
static int __init init(void)
{
struct android_dev *dev;
int err;
android_class = class_create(THIS_MODULE, "android_usb");
if (IS_ERR(android_class))
return PTR_ERR(android_class);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->functions = supported_functions;
INIT_LIST_HEAD(&dev->enabled_functions);
INIT_WORK(&dev->work, android_work);
mutex_init(&dev->mutex);
err = android_create_device(dev);
if (err) {
class_destroy(android_class);
kfree(dev);
return err;
}
_android_dev = dev;
/* Override composite driver functions */
composite_driver.setup = android_setup;
composite_driver.disconnect = android_disconnect;
return usb_composite_probe(&android_usb_driver, android_bind);
}
composite_driver是定义在driver/usb/gadget/composite.c中,
static struct usb_gadget_driver composite_driver = {
.speed = USB_SPEED_HIGH,
.unbind = composite_unbind,
.setup = composite_setup,
.disconnect = composite_disconnect,
.suspend = composite_suspend,
.resume = composite_resume,
.driver = {
.owner = THIS_MODULE,
},
};
可见它是一个全局的结构体,android.c中重新实现了它的setup和disconnect方法。然后调用函数usb_gadget_probe_driver(&android_usb_driver,android_bind);向USB设备层进行探测和注册。
extern int usb_composite_probe(struct usb_composite_driver *driver,
int (*bind)(struct usb_composite_dev *cdev))
{
if (!driver || !driver->dev || !bind || composite)
return -EINVAL;
if (!driver->iProduct)
driver->iProduct = driver->name;
if (!driver->name)
driver->name = "composite";
composite_driver.function = (char *) driver->name;
composite_driver.driver.name = driver->name;
composite = driver;
composite_gadget_bind = bind;
return usb_gadget_probe_driver(&composite_driver, composite_bind);
}
函数usb_gadget_probe_driver调用usb_gadget_probe_driver相关USB设备控制器驱动层进行注册。