基于android4.0的usb gadget分析专题(1)
分析前还是先扯几句吧:今天有心情看点代码,就做一点笔记吧,不过android的usb gadget代码不多,但是层次复杂,再加上没人写这方便的文章,所以也没有什么可以参考的,只能自己悟啦,再看之前建议你把设备驱动模型搞懂,要不跟代 码会跟的你吐血的,设备驱动模型网上有很多啦,你花上几个小时跟下代码就基本知道什么意思啦,我记得有个博客是http://blog.csdn.net/king_208讲的相当棒,好啦,不懂驱动模型的就去看吧!下面分析几个大的函数吧!
点击(此处)折叠或打开
- struct android_dev {
- struct android_usb_function **functions;
- struct list_head enabled_functions;
- struct usb_composite_dev *cdev;
- struct device *dev;
- bool enabled;
- struct mutex mutex;
- bool connected;
- bool sw_connected;
- struct work_struct work;
- };
上面的这个结构相当重要,几乎贯穿了整个usb gadget驱动,相当于一个全局的纽带。
- static int __init init(void)
- {
- struct android_dev *dev;
- int err;
- /*下面创建一个class,创建这个class的目的是支持用户空间的udev,自动创建设备节点*/
- 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;// 初始化该结构体的functions成员
- /*该结构体的定义如下*/
- static struct android_usb_function *supported_functions[] = {
&adb_function,//支持的adb功能
&acm_function,
&mtp_function,
&ptp_function,
&rndis_function,
&mass_storage_function,//支持的大容量存储功能
&accessory_function,
NULL
}; - INIT_LIST_HEAD(&dev->enabled_functions);//初始化dev的enabled_functions成员链表头
- INIT_WORK(&dev->work, android_work);//初始化dev的work成员,支持的工作队列
- mutex_init(&dev->mutex);//初始化dev的成员mutex互斥锁
- err = android_create_device(dev);//在该函数中继续初始化android_dev中的成员dev,其中用到上面的android_class类,支持动态创建设备节点,并为该设备创建属性。
- if (err) {
- class_destroy(android_class);
- kfree(dev);
- return err;
- }
- /*把初始化好的android_dev变量dev,存到一个全局变量中,供后面访问*/
- _android_dev = dev;
- /* 对composite driver中的setup和disconnect函数重新赋值 */
- composite_driver.setup = android_setup;
- composite_driver.disconnect = android_disconnect;
- /*下面这个函数才是函数的开始,到里面牵涉的东西会越来越多,后面先把他的两个参数给贴出了*/
- return usb_composite_probe(&android_usb_driver, android_bind);
- }
composite_driver的定义如下
- 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,
- },
- };
这是上面的函数的第一个参数
- static struct usb_composite_driver android_usb_driver = {
- .name = "android_usb",//该复合设备驱动的名称
- .dev = &device_desc,//设备描述符
- .strings = dev_strings,
- .unbind = android_usb_unbind,
- };
这是上面的函数的第二个参数
- static int android_bind(struct usb_composite_dev *cdev)
- {
- struct android_dev *dev = _android_dev;
- struct usb_gadget *gadget = cdev->gadget;
- int gcnum, id, ret;
- usb_gadget_disconnect(gadget);
- ret = android_init_functions(dev->functions, cdev);
- if (ret)
- return ret;
- /* Allocate string descriptor numbers ... note that string
- * contents can be overridden by the composite_dev glue.
- */
- id = usb_string_id(cdev);
- if (id < 0)
- return id;
- strings_dev[STRING_MANUFACTURER_IDX].id = id;
- device_desc.iManufacturer = id;
- id = usb_string_id(cdev);
- if (id < 0)
- return id;
- strings_dev[STRING_PRODUCT_IDX].id = id;
- device_desc.iProduct = id;
- /* Default strings - should be updated by userspace */
- strncpy(manufacturer_string, "Android", sizeof(manufacturer_string) - 1);
- strncpy(product_string, "Android", sizeof(product_string) - 1);
- strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
- id = usb_string_id(cdev);
- if (id < 0)
- return id;
- strings_dev[STRING_SERIAL_IDX].id = id;
- device_desc.iSerialNumber = id;
- gcnum = usb_gadget_controller_number(gadget);
- if (gcnum >= 0)
- device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
- else {
- /* gadget zero is so simple (for now, no altsettings) that
- * it SHOULD NOT have problems with bulk-capable hardware.
- * so just warn about unrcognized controllers -- don't panic.
- *
- * things like configuration and altsetting numbering
- * can need hardware-specific attention though.
- */
- pr_warning("%s: controller '%s' not recognized\n",
- longname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
- }
- usb_gadget_set_selfpowered(gadget);
- dev->cdev = cdev;
- return 0;
- }
好啦,今天就到此结束吧,最后了解下一个概念,复合设备,什么是复合设备呢?
Example: a device with a single configuration supporting both network
link and mass storage functions is a composite device. Those functions
might alternatively be packaged in individual configurations, but in
the composite model the host can use both functions at the same time.
英语就不用我解释了吧,相信大家都能看懂,真要是不懂的话,找google大神。今天已经很晚啦,有空继续分析。
浙公网安备 33010602011771号