http://blog.csdn.net/airk000/article/details/7890182
接上篇《Android4.0 USB挂载内核驱动层流程分析(二)》
1.android_bind
- static int android_bind(struct usb_composite_dev *cdev)
- {
- struct android_dev *dev = _android_dev; //回头看Android4.0 USB挂载内核驱动层流程分析(一),static int __init init(void) 函数中_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); //这里的function们就是之前包括mass_storage_function在内的功能。下边分析
- 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); //通过读取设备ID来填充一下驱动参数
- 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 */
- strlcpy(manufacturer_string, "Android",
- sizeof(manufacturer_string) - 1); //填充一下默认的厂商和产品信息,根据说明意思是可以通过上层改变
- strlcpy(product_string, "Android", sizeof(product_string) - 1);
- #ifdef CONFIG_HUAWEI_KERNEL //分析的是华为的内核,所以有这样的宏定义
- if(0 != usb_para_data.usb_para.usb_serial[0])
- {
- /* use bluetooth address as usb serial number */
- strlcpy(serial_string, usb_para_data.usb_para.usb_serial, APP_USB_SERIAL_LEN); //华为的意思是使用蓝牙地址作为USB串口序列号
- }
- else
- {
- strlcpy(serial_string, USB_DEFAULT_SN, sizeof(serial_string) - 1); //如果蓝牙地址为0的话就使用默认序列号:012345789AB,下边就 bulabulabula...
- /* if the usb_serial is null and the nv value is google index, init.c will set
- * the ports to factory mode. so update the variable to keep consistent.
- */
- if(GOOGLE_INDEX == usb_para_data.usb_para.usb_pid_index) //Google模式,25!
- {
- USB_PR("%s usb serial number is null in google mode. so switch to original mode\n", __func__);
- usb_para_data.usb_para.usb_pid_index = ORI_INDEX;
- }
- }
- #else
- strlcpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1); //好吧,默认就是给0123456789ABCDEF序列号的
- #endif /* CONFIG_HUAWEI_KERNEL */
- id = usb_string_id(cdev);
- if (id < 0)
- return id;
- strings_dev[STRING_SERIAL_IDX].id = id;
- device_desc.iSerialNumber = id;
- /* backup the serial str id */
- #ifdef CONFIG_HUAWEI_KERNEL
- serial_str_id = id;
- #endif /* CONFIG_HUAWEI_KERNEL */
- gcnum = usb_gadget_controller_number(gadget); //识别一下控制芯片,返回一个BCD值
- 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); //如果前边没有遇到错误return的话,那么这里就可以正常供电了
- dev->cdev = cdev;
- return 0;
- }
2.android_init_function
- static int android_init_functions(struct android_usb_function **functions,
- struct usb_composite_dev *cdev)
- {
- struct android_dev *dev = _android_dev;
- struct android_usb_function *f;
- struct device_attribute **attrs;
- struct device_attribute *attr;
- int err = 0;
- int index = 0;
- for (; (f = *functions++); index++) {
- f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name); //拿mass_storage_function来说,dev_name就是f_mass_storage了
- f->dev = device_create(android_class, dev->dev,
- MKDEV(0, index), f, f->dev_name); //创建设备
- if (IS_ERR(f->dev)) {
- pr_err("%s: Failed to create dev %s", __func__,
- f->dev_name);
- err = PTR_ERR(f->dev);
- goto err_create;
- }
- if (f->init) { //f->init指向mass_storage_function_init,所以是在这个时候运行的。
- err = f->init(f, cdev);
- if (err) {
- pr_err("%s: Failed to init %s", __func__,
- f->name);
- goto err_out;
- }
- }
- attrs = f->attributes;
- if (attrs) {
- while ((attr = *attrs++) && !err)
- err = device_create_file(f->dev, attr);
- }
- if (err) {
- pr_err("%s: Failed to create function %s attributes",
- __func__, f->name);
- goto err_out;
- }
- }
- return 0;
- err_out:
- device_destroy(android_class, f->dev->devt);
- err_create:
- kfree(f->dev_name);
- return err;
- }
3.总结
由于对内核不是很熟悉,有些地方分析得不太好,但是作为驱动的使用者、适配者,就像大学老师说的,不用知道怎么来的,知道怎么用就好了。所以在分析完USB挂载相关内核驱动之后,显然最最重要的地方是mass_storage_function_init函数中的参数配置过程,定好有几个LUN,各自属性是什么样子的。然后就可以在内核结构中初始化完成了,剩下的工作就是跟VOLD相关的处理。
关于挂载,首先是由init.rc创建文件,由vold.fstab进行链接,然后只要提供给VOLD正确的参数(或默认),最终再在framework的overlay中将storage_list.xml配置好,就可以实现USB挂载没有问题了。
1楼 xiewen2010 2012-08-28 17:23发表
1)“事件流程”,eg :usb模式切换,
2)数据流程 eg:命令发送接收,数据发送接收。
不过我也不是太了解。
希望楼主可以继续深入看下去,华为usb这一块我在华为的时候曾今参与开发过(中途离开),希望能和博主一起深入学习
-
Re:
airk000 2012-08-30 15:46发表
- 回复xiewen2010:是没看那部分,最近一直再搞别的,也想抽时间再仔细往下看一看。