接上篇《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; }
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; }
由于对内核不是很熟悉,有些地方分析得不太好,但是作为驱动的使用者、适配者,就像大学老师说的,不用知道怎么来的,知道怎么用就好了。所以在分析完USB挂载相关内核驱动之后,显然最最重要的地方是mass_storage_function_init函数中的参数配置过程,定好有几个LUN,各自属性是什么样子的。然后就可以在内核结构中初始化完成了,剩下的工作就是跟VOLD相关的处理。
关于挂载,首先是由init.rc创建文件,由vold.fstab进行链接,然后只要提供给VOLD正确的参数(或默认),最终再在framework的overlay中将storage_list.xml配置好,就可以实现USB挂载没有问题了。
**可能有一些分析错的地方,如果有高手路过,还望指点一二!