Android4.0 USB挂载内核驱动层流程分析(三)

http://blog.csdn.net/airk000/article/details/7890182

接上篇《Android4.0 USB挂载内核驱动层流程分析(二)》
1.android_bind

  1. static int android_bind(struct usb_composite_dev *cdev)  
  2. {  
  3.     struct android_dev *dev = _android_dev;    //回头看Android4.0 USB挂载内核驱动层流程分析(一),static int __init init(void) 函数中_android_dev = dev; _android_dev是一个静态结构体  
  4.     struct usb_gadget   *gadget = cdev->gadget;  
  5.     int         gcnum, id, ret;  
  6.   
  7.   
  8.     usb_gadget_disconnect(gadget);    //初始化前确保是断开的  
  9.   
  10.   
  11.     ret = android_init_functions(dev->functions, cdev);    //这里的function们就是之前包括mass_storage_function在内的功能。下边分析  
  12.     if (ret)  
  13.         return ret;  
  14.   
  15.   
  16.     /* Allocate string descriptor numbers ... note that string 
  17.      * contents can be overridden by the composite_dev glue. 
  18.      */  
  19.     id = usb_string_id(cdev);    //通过读取设备ID来填充一下驱动参数  
  20.     if (id < 0)  
  21.         return id;  
  22.     strings_dev[STRING_MANUFACTURER_IDX].id = id;  
  23.     device_desc.iManufacturer = id;  
  24.   
  25.   
  26.     id = usb_string_id(cdev);  
  27.     if (id < 0)  
  28.         return id;  
  29.     strings_dev[STRING_PRODUCT_IDX].id = id;  
  30.     device_desc.iProduct = id;  
  31.   
  32.   
  33.     /* Default strings - should be updated by userspace */  
  34.     strlcpy(manufacturer_string, "Android",  
  35.         sizeof(manufacturer_string) - 1);    //填充一下默认的厂商和产品信息,根据说明意思是可以通过上层改变  
  36.     strlcpy(product_string, "Android"sizeof(product_string) - 1);  
  37. #ifdef CONFIG_HUAWEI_KERNEL    //分析的是华为的内核,所以有这样的宏定义  
  38.     if(0 != usb_para_data.usb_para.usb_serial[0])      
  39.     {  
  40.         /* use bluetooth address as usb serial number */  
  41.         strlcpy(serial_string, usb_para_data.usb_para.usb_serial, APP_USB_SERIAL_LEN);    //华为的意思是使用蓝牙地址作为USB串口序列号  
  42.     }  
  43.     else  
  44.     {  
  45.         strlcpy(serial_string, USB_DEFAULT_SN, sizeof(serial_string) - 1);    //如果蓝牙地址为0的话就使用默认序列号:012345789AB,下边就 bulabulabula...  
  46.         /* if the usb_serial is null and the nv value is google index, init.c will set 
  47.          * the ports to factory mode. so update the variable to keep consistent. 
  48.          */  
  49.         if(GOOGLE_INDEX == usb_para_data.usb_para.usb_pid_index)    //Google模式,25!  
  50.         {              
  51.             USB_PR("%s usb serial number is null in google mode. so switch to original mode\n", __func__);  
  52.             usb_para_data.usb_para.usb_pid_index = ORI_INDEX;  
  53.         }  
  54.     }  
  55. #else  
  56.     strlcpy(serial_string, "0123456789ABCDEF"sizeof(serial_string) - 1);  //好吧,默认就是给0123456789ABCDEF序列号的  
  57. #endif  /* CONFIG_HUAWEI_KERNEL */  
  58.   
  59.   
  60.     id = usb_string_id(cdev);  
  61.     if (id < 0)  
  62.         return id;  
  63.     strings_dev[STRING_SERIAL_IDX].id = id;  
  64.     device_desc.iSerialNumber = id;  
  65.     /* backup the serial str id */  
  66. #ifdef CONFIG_HUAWEI_KERNEL  
  67.     serial_str_id = id;  
  68. #endif  /* CONFIG_HUAWEI_KERNEL */  
  69.   
  70.   
  71.     gcnum = usb_gadget_controller_number(gadget);    //识别一下控制芯片,返回一个BCD值  
  72.     if (gcnum >= 0)  
  73.         device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);  
  74.     else {  
  75.         /* gadget zero is so simple (for now, no altsettings) that 
  76.          * it SHOULD NOT have problems with bulk-capable hardware. 
  77.          * so just warn about unrcognized controllers -- don't panic. 
  78.          * 
  79.          * things like configuration and altsetting numbering 
  80.          * can need hardware-specific attention though. 
  81.          */  
  82.         pr_warning("%s: controller '%s' not recognized\n",  
  83.             longname, gadget->name);  
  84.         device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);  
  85.     }  
  86.   
  87.   
  88.     usb_gadget_set_selfpowered(gadget);    //如果前边没有遇到错误return的话,那么这里就可以正常供电了  
  89.     dev->cdev = cdev;  
  90.   
  91.   
  92.     return 0;  
  93. }  

2.android_init_function

  1. static int android_init_functions(struct android_usb_function **functions,  
  2.                   struct usb_composite_dev *cdev)  
  3. {  
  4.     struct android_dev *dev = _android_dev;  
  5.     struct android_usb_function *f;  
  6.     struct device_attribute **attrs;  
  7.     struct device_attribute *attr;  
  8.     int err = 0;  
  9.     int index = 0;  
  10.   
  11.   
  12.     for (; (f = *functions++); index++) {  
  13.         f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);  //拿mass_storage_function来说,dev_name就是f_mass_storage了  
  14.         f->dev = device_create(android_class, dev->dev,  
  15.                 MKDEV(0, index), f, f->dev_name);    //创建设备  
  16.         if (IS_ERR(f->dev)) {  
  17.             pr_err("%s: Failed to create dev %s", __func__,  
  18.                             f->dev_name);  
  19.             err = PTR_ERR(f->dev);  
  20.             goto err_create;  
  21.         }  
  22.   
  23.   
  24.         if (f->init) {    //f->init指向mass_storage_function_init,所以是在这个时候运行的。  
  25.             err = f->init(f, cdev);  
  26.             if (err) {  
  27.                 pr_err("%s: Failed to init %s", __func__,  
  28.                                 f->name);  
  29.                 goto err_out;  
  30.             }  
  31.         }  
  32.   
  33.   
  34.         attrs = f->attributes;  
  35.         if (attrs) {  
  36.             while ((attr = *attrs++) && !err)  
  37.                 err = device_create_file(f->dev, attr);  
  38.         }  
  39.         if (err) {  
  40.             pr_err("%s: Failed to create function %s attributes",  
  41.                     __func__, f->name);  
  42.             goto err_out;  
  43.         }  
  44.     }  
  45.     return 0;  
  46.   
  47.   
  48. err_out:  
  49.     device_destroy(android_class, f->dev->devt);  
  50. err_create:  
  51.     kfree(f->dev_name);  
  52.     return err;  
  53. }  

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:是没看那部分,最近一直再搞别的,也想抽时间再仔细往下看一看。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值