Android 4.0 USB挂载内核驱动层流程分析(3)

接上篇《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挂载没有问题了。

**可能有一些分析错的地方,如果有高手路过,还望指点一二!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/fb1aba3105ec1f84ff9e8b4ff051821d.html