关于f_mass_storage.c的文章(转载)

来源:互联网 发布:世界建筑史网络 编辑:程序博客网 时间:2024/05/16 12:24

原文地址:http://blog.csdn.net/HellDevil/archive/2010/05/18/5604421.aspx

http://blog.csdn.net/HellDevil/archive/2010/05/06/5561918.aspx

http://blog.csdn.net/HellDevil/archive/2010/01/19/5213888.aspx

http://blog.csdn.net/HellDevil/archive/2010/05/15/5596196.aspx

Android usb驱动模块 g_android.ko rmmod issues


我最近在调试Android系统的gadget功能,通过make menuconfig发现gadget是编译成module模式的。里面有很多可选项,其中有个Android的选项,其实就是提供ADBStorage的功能的。

具体查看代码在/drivers/usb/gadget下,三个文件:android.c f_adb.c f_mass_storage.c

g_android.ko 是由这三个文件而来,其中android.c 依赖于f_adb.c f_mass_storage.c(这两个文件之间无依赖关系)

可以在android.c中的

view plaincopy to clipboardprint?

  1. static int __init android_bind_config(struct usb_configuration *c)  
  2. {  
  3.     struct android_dev *dev = _android_dev;  
  4.     int ret;  
  5.     printk(KERN_DEBUG "android_bind_config\n");  
  6.     ret = mass_storage_function_add(dev->cdev, c, dev->nluns);  
  7.     if (ret)  
  8.         return ret;  
  9.     return adb_function_add(dev->cdev, c);  
  10. }  


看到关系

============================================================

下面说说我的问题,

1.当我将Android编译成module模式,既g_android.ko时候,然后放入rootfs中手动加载,Okay, no problem!非常happy。但是,当我关闭adb进程,rmmod g_android的时候,出现死锁状态,打开代码进行查询,发现问题出现在

view plaincopy to clipboardprint?

  1. struct usb_request *req_get(struct adb_dev *dev, struct list_head *head, int DD)  
  2. {  
  3. unsigned long flags;  
  4. struct usb_request *req;  
  5. spin_lock_irqsave(&dev->lock, flags);//被锁了,郁闷  
  6. if (list_empty(head)) {  
  7. req = 0;  
  8. else {  
  9. req = list_first_entry(head, struct usb_request, list);  
  10. list_del(&req->list);  
  11. }  
  12. spin_unlock_irqrestore(&dev->lock, flags);  
  13. return req;  
  14. }  


一直死锁,通过打开kernel hacking中的spinlock debug发现是自己把自己锁了,找阿找阿。。。。

看了下rmmod时候函数调用过程当我rmmod的时候,首先会去执行__exit cleanup(void)中的usb_composite_unregister(&android_usb_driver)这句话中还调用 composite.c中的函数 (不细说),反正最后会调到f_adb.c中的

adb_function_unbind(struct usb_configuration *c, struct usb_function *f)

看看这个函数

view plaincopy to clipboardprint?

  1. static void  
  2. adb_function_unbind(struct usb_configuration *c, struct usb_function *f)  
  3. {  
  4.       
  5.     struct adb_dev  *dev = func_to_dev(f);  
  6.     struct usb_request *req;  
  7.    
  8.     spin_lock_irq(&dev->lock);//锁死你个req_get,谁叫我们共用一个dev->lock  
  9.       
  10.     while ((req=req_get(dev, &dev->rx_idle,0)))//被所到死  
  11.          {  
  12.         adb_request_free(req, dev->ep_out);  
  13.      }  
  14.     while ((req=req_get(dev, &dev->tx_idle,0)))  
  15.     {  
  16.          adb_request_free(req, dev->ep_in);  
  17.     }  
  18.     dev->online = 0;  
  19.     dev->error = 1;  
  20.     spin_unlock_irq(&dev->lock);  
  21.     
  22.     misc_deregister(&adb_device);  
  23.     kfree(_adb_dev);  
  24.       
  25.     _adb_dev = NULL;  
  26.       
  27. }  


所以感觉 req_get代码中的spinlock有问题,没办法,只能写了个req_get_free_lock(不加锁)替代while循环中的req_get函数

rebuild 内核,Okay 卸载g_android.ko 没问题哈哈。正当自己高兴的时候,发现乐极生悲了。。。

===========================================================

卸载完了g_android.ko 我再次insmod g_android.ko 挂了,不过不是kernel panic而是提示

"sysfs: duplicate filename 'usb_mass_storage' can not be created"

这次出在f_mass_storage.c这个文件中,根据信息提示应该是没因为上次没卸载完全。没办法,在几个与insmodrmmod的函数中加入打印信息。主要是mass_storage_function_add fsg_function_bindfsg_function_unbind三个函数,前两个是跟insmod有关,后者跟rmmod有关。

通过打印信息发现一个Android开发者的小纰漏 导致的问题,就是在

view plaincopy to clipboardprint?

  1. int __init mass_storage_function_add(struct usb_composite_dev *cdev,  
  2.     struct usb_configuration *c, int nluns)  
  3. {  
  4.     int     rc;  
  5.     struct fsg_dev  *fsg;  
  6.     printk(KERN_INFO "mass_storage_function_add\n");  
  7.     rc = fsg_alloc();  
  8.     if (rc)  
  9.         return rc;  
  10.     fsg = the_fsg;  
  11.     fsg->nluns = nluns;  
  12.      
  13.     spin_lock_init(&fsg->lock);  
  14.     init_rwsem(&fsg->filesem);  
  15.     kref_init(&fsg->ref);  
  16.     init_completion(&fsg->thread_notifier);  
  17.       
  18.     the_fsg->buf_size = BULK_BUFFER_SIZE;  
  19.     the_fsg->sdev.name = DRIVER_NAME;  
  20.     the_fsg->sdev.print_name = print_switch_name;  
  21.     the_fsg->sdev.print_state = print_switch_state;  
  22.       
  23.       
  24.     rc = switch_dev_register(&the_fsg->sdev);//卸载的时候没有swith_dev_unregister  
  25.       
  26.       
  27.     if (rc < 0)  
  28.         goto err_switch_dev_register;  
  29.     wake_lock_init(&the_fsg->wake_lock, WAKE_LOCK_SUSPEND,  
  30.                "usb_mass_storage");  
  31.       
  32.     fsg->cdev = cdev;  
  33.     fsg->function.name = shortname;  
  34.     fsg->function.descriptors = fs_function;  
  35.     fsg->function.bind = fsg_function_bind;  
  36.     fsg->function.unbind = fsg_function_unbind;  
  37.     fsg->function.setup = fsg_function_setup;  
  38.     fsg->function.set_alt = fsg_function_set_alt;  
  39.     fsg->function.disable = fsg_function_disable;  
  40.       
  41.     rc = usb_add_function(c, &fsg->function);  
  42.       
  43.     if (rc != 0)  
  44.         goto err_usb_add_function;  
  45.     return 0;  
  46. err_usb_add_function:  
  47.     switch_dev_unregister(&the_fsg->sdev);  
  48. err_switch_dev_register:  
  49.     kref_put(&the_fsg->ref, fsg_release);  
  50.       
  51.     return rc;  
  52. }  


在掉用过/drivers/switch/class_switch.c 中的 switch_dev_register后,除了出错处理再也没作擦屁股的动作(unregister)汗,这不是占着XX不拉什么吗?没办法,去 fsg_function_unbind函数中的

view plaincopy to clipboardprint?

  1. for (i = 0; i < fsg->nluns; ++i) {  
  2.         curlun = &fsg->luns[i];  
  3.         if (curlun->registered) {  
  4.             switch_dev_unregister(&the_fsg->sdev);//加入擦屁股的一句  
  5.             device_remove_file(&curlun->dev, &dev_attr_file);  
  6.             device_unregister(&curlun->dev);  
  7.             curlun->registered = 0;  
  8.         }  
  9.     }  


Okay 万事Okay 主阿!其实都不是什么大的问题拉。但是导致的现象确很恐怖。android developer太忙了,毕竟也是人阿。呵呵,以前都不敢改他们代码,总是推敲自己是不是哪边错了。

Android usb client mass-storage不能自动挂载到主机端的问题(1)

测试平台:Nvidia ARM架构

操作系统:Andorid(Nvidia修改)

       最近在搞Android usb client,发现当将client线分别接上Android系统机器的client端以及主机Host端的时候,AndroidUSB client两大功能中的ADB可以使用,而mass-storage无法使用,即装有Android系统的机器不能将自己的sdhc卡,以及自身的内存卡挂到host主机端,并且显示。

       输入 ls -l /dev/sd*

       发现终端显示了个叫/dev/sdb 的节点,尝试mount ,提示无法mount 未知的文件系统。

       Okay,查看Android系统端的init.rc发现挂载方式是vold.

       查看vold原代码,发现需要读取vold.conf,并且检测UMS

=======================================

       那么大致猜测下和问题有关的可能是Android系统的这么几个:

       1.rootfs  /etc/vold.conf配置可能有问题

       2.vold 的程序可能有问题

       3.linux driver  /driver/usb/gadget/f_mass_storage.c有问题

       4.UMS功能可能有问题

=======================================

大致猜测了问题的所在,那么下一 步就是一步一步确认了。

1.先看看/etc/vold.conf文件,代码在/out/target/product/XX/system/etc/vold.conf

      

view plaincopy to clipboardprint?

  1. volume_sdcard {  
  2.        media_path   /devices/platform/tegra-sdhci.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4  
  3.        media_type   mmc  
  4.        mount_point /sdcard  
  5. }  
  6. UMS的路径没有,个人经验:一般可以在/sys/devices/platform/  
  7. 下面找到一个叫包含"udc"字符的节点,进入它的子目录,会看到lun0的节点。  


进入/sys/devices/platform

这时候会有两种现象出现:1,就是有相应的节点;2,没有

1.如果有,则应该确定该节点是否和你的f_mass_storage驱动相对应,也就是说,这个节点是你的mass_storage驱动创建的,如果不是需要你去创建。

2.如果没有,那么需要在f_mass_storage.c里面去创建它。

我的情况是第一个,目录下有个叫shdc-udc.0/lun0的节点,但是并没有和我的g_android中的mass-storage驱动对应,所以我必须重新创建个。

nvidia提供给我门的/arch/arm/mach-XXX/nvodm_board.c中会有一系列的device_register的动作

创建/sys/devices/platform下的节点在这需要加入两句

view plaincopy to clipboardprint?

  1. static struct platform_device fsg_platform_device =  
  2. {  
  3.     .name = "usb_mass_storage",  
  4.     .id   = -1,  
  5. };  
  6. static void __init tegra_machine_init(void)  
  7. {  
  8. ....  
  9.  (void) platform_device_register(&fsg_platform_device);  
  10. ....  
  11. }  
  12. 加入这两句okay  


我们会发现/sys/devices/platform/usb_mass_storage/lun0这个目录产生了

这些动作是和你的linux drivermass-storage的驱动内容相对应的。

最后一步,就是需要将新创建的UMS(负责启动usb mass-storage功能) Path加入到你的vold.conf

view plaincopy to clipboardprint?

  1. volume_sdcard {  
  2.        media_path   /devices/platform/tegra-sdhci.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4  
  3.        media_type   mmc  
  4.        mount_point /sdcard  
  5.        ums_path    /devices/platform/usb_mass_storage/lun0  
  6. //加的代码就是这个  
  7. }  


===========================

打开机器,灌入系统,启动,发现还是不行,在ADB终端中输入sdutil ums enabel启动ums 实际上我机器已经在开机就启动了UMS功能

logcat显示UMS 挂掉了 一大堆的堆栈问题 stack 什么的。

估计和内存分配或者指针有关。

估计是vold的代码有问题。

进入android源代码目录/system/core/vold

打开该目录下所有代码,加入打印语句,进行跟踪。

发现当你ums enable时候

1.会进入cmd_dispatch.c执行do_set_ums_enable函数

view plaincopy to clipboardprint?

  1. static int do_set_ums_enable(char *cmd)  
  2. {  
  3.  ...  
  4.  if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS))  
  5.      return volmgr_enable_ums(true);  
  6.  return volmgr_enable_ums(false);  
  7. }  


它又调用了volmgr.c文件中的volmgr_enable_ums(bool enable)

view plaincopy to clipboardprint?

  1. int volmgr_enable_ums(bool enable)  
  2. {  
  3.  ...  
  4.   volume_t *v = vol_root //链表,链表中存储了每个存储设备的相关信息,如state. ums_path, mount_point这些来自于/etc/vold.conf  
  5.   while(v)  
  6.   {  
  7.       if(v->ums_path)  
  8.          if(enable){  
  9.             ...  
  10.             volmgr_shutdown_volume(v, _cb_volstopped_for_ums_enable_false);//程序执行到这句话 挂掉了  
  11.             ...  
  12.           }  
  13.   }  
  14.   


首先我们看看,程序是如何读取/etc/vold.conf配置信息并存储的

主要是这么几个函数volmgr_readconfig, volmgr_config_volume,等等,这里不详细讲,只是大概讲下,

首先 会建立一个大的链表,通过比配vold.confvolume_XX来确定有多少成员volum_sdcard1 volum_sdcard2

表示有两个成员

然后,会在每个成员里在建一个链表,用于存储ums_path mount_point这些

最后再将这些东西重新在组织成个链表v

=========================================

继续上面的代码说

跟踪volmgr_shutdown_volume()--->volmgr_stop_volume()--->_cb_volstopped_for_ums_enable()

view plaincopy to clipboardprint?

  1. staitc void _cb_volstopped_for_ums_enable(volume_t *v, void *arg)  
  2. {  
  3.       char* devdir_path  
  4.       ...  
  5.       devdir_path = blkdev_get_devpath(v->dev->disk);//挂了  
  6.       ...  
  7. }  


继续跟下去到blkdev.c

view plaincopy to clipboardprint?

  1. char *blkdev_get_devpath(blkdev_t *blk)  
  2. {  
  3.      ....  
  4.      char *dp = malloc(256);  
  5.      sprintf(dp, "%s/vold/%d:%d", blk->major, blk->minor);//挂掉  
  6. }  
  7. 经过调试 发现blk是空指针。  
  8. 在看调用它的函数 _cb_volstopped_for_ums_enable  
  9. 发现v->dev->disk空的指针  

char *blkdev_get_devpath(blkdev_t *blk) { .... char *dp = malloc(256); sprintf(dp, "%s/vold/%d:%d", blk->major, blk->minor);//挂掉 } 经过调试 发现blk是空指针。 在看调用它的函数 _cb_volstopped_for_ums_enable 发现v->dev->disk空的指针  

继续返回跟踪 ,发现v->dev->disk始终是空

怪不得,马的又没作异常处理,草了

在其他地方 发现v->devv->dev->disk是相同类型,有的地方用v->dev->major,有的地方用v->dev->disk->major

看了 下没见到v->dev->disk的初始化,悲剧阿。。。

于是尝试将v->dev作形参传入,而不是v->dev->disk

发现okay.汗查看/dev/vold/下面的设备号v->dev->major:v->dev->minor打出来的一致。

当机器启动时,插入usb client cable.主机端可以自动挂载mass-storage

Oh, yeah success! 

==========================================

不知道为什么v->dev->disk是空的。正在继续看。。估计这几天应该能搞清除。

写的不好,也不怎么详细,只是自己一点调试的看法和经验希望能帮助自己和大家,谢谢

Android usb client mass-storage挂载单个存储设备研究

上次,初步接触Android usb client 的挂载问题,所以写了第一篇研究的感受,许多地方还有点问题,有些现象还不够清晰,所以想继续写下去。

     首先,通过上次的验证,看到的现象,是可以挂载了,但是每一次只能挂载一个存储设备。

     其次,我上次所说的关于驱动的设备节点,也有问题,其实本身就有一个tegra-udc.c创建的/sys/devices/platform/tegra-udc.0/lun0这么个节点在,所以不需要在创建什么mass-storage节点。

 ===========================================================================   

()首先,我们看看第一个问题,怎么每次只挂了一个设备在上面呢?

    1.VOLD首先会去读取vold.conf的文件中配置内容(尾插入的链表方式)存储存储设备的必要信息(上次讲过,就是EMMCpartition 4

    接着,会去通过uevent读取动态插入的存储设备信息,以头插入链表的方式,并将第一个链表和这次的链表结合起来(auto_add_volume),使得动态存储设备在链表头几个,而静态存储设备在链表后面。这种顺序,在我的环境中是正确的,因为我的虽有的动态存储设备是挂载在 partition 4上面的。用过手机或者有一点挂载卸载经验的人都知道,如果想要顺利卸载partition 4需要卸载它的里面目录,否则partition 4一直显示busy而不能卸载。为什么要卸载了存储设备再挂呢,这是因为防止两边同时操作。

这里要说明下,就是如果想要动态存储设备通过ums_path路径的检测,需要在auto_add_volume函数里的ums_path下,明确指定目录,使得动态存储设备,能够被正确挂载。

    2.当在client卸载成功时,就需要挂载到host端了,我一路跟踪,发现这段voldvolmgr.c代码起了作用

    

view plaincopy to clipboardprint?

  1. static void _cb_volstopped_for_ums_enable(volume_t *v, void *arg)  
  2. {  
  3.     int rc;  
  4.     char *devdir_path;  
  5. #if DEBUG_VOLMGR  
  6.     LOG_VOL("_cb_volstopped_for_ums_enable(%s):", v->mount_point);  
  7. #endif  
  8.     //check dev->disk whether is NULL  
  9.     if (v->dev->disk)  
  10.        devdir_path = blkdev_get_devpath(v->dev->disk);  
  11.     else  
  12.        devdir_path = blkdev_get_devpath(v->dev);  
  13.          
  14.     if ((rc = ums_enable(devdir_path, v->ums_path)) < 0) {//重点  
  15.         free(devdir_path);  
  16.         LOGE("Error enabling ums (%d)", rc);  
  17.         return;  
  18.     }  
  19.     free(devdir_path);  
  20.     volume_setstate(v, volstate_ums);  
  21.     pthread_mutex_unlock(mutex);  
  22. }  


    最主要的是ums_enable(),是这句话让设备挂载到主机端,继续跟下去

    在同目录下的ums.c代码中

    

view plaincopy to clipboardprint?

  1. int ums_enable(char *dev_fspath, char *lun_syspath)  
  2. {  
  3.     LOG_VOL("ums_enable(%s, %s):", dev_fspath, lun_syspath);  
  4.     int fd;  
  5.     char filename[255];  
  6.     sprintf(filename, "/sys/%s/file", lun_syspath);  
  7.     if ((fd = open(filename, O_WRONLY)) < 0) {  
  8.         LOGE("Unable to open '%s' (%s)", filename, strerror(errno));  
  9.         return -errno;  
  10.     }  
  11.     if (write(fd, dev_fspath, strlen(dev_fspath)) < 0) {  
  12.         LOGE("Unable to write to ums lunfile (%s)", strerror(errno));  
  13.         close(fd);  
  14.         return -errno;  
  15.     }  
  16.       
  17.     close(fd);  
  18.     return 0;  
  19. }  


    open 一个"/sys/devices/platform/tegra-udc.0/lun0/file"文件

    然后向file文件写入一个 "/dev/block/vold/major:minor"path路径,而这个路径对应的是各个存储设备

    我尝试了写入不同的路径到file里(通过adb中写入 如:echo "/dev/block/vold/179:0">/sys/devices/platform/tegra-udc.0/lun0/file)。

    每写一个路径,就会挂载一个相应的存储设备到host端,但是当你挂载下个设备时候必须echo  "">file中,先从hostunmount前一个设备才能挂载当前设备。

    继续跟踪代码到kernenl,发现/driver/usb/gadget/f_mass_storage.c作了某些动作,挂载了设备

  

view plaincopy to clipboardprint?

  1. static ssize_t store_file(struct device *dev, struct device_attribute *attr,  
  2.         const char *buf, size_t count)  
  3. {  
  4.     struct lun  *curlun = dev_to_lun(dev);  
  5.     struct fsg_dev  *fsg = dev_get_drvdata(dev);  
  6.     int     rc = 0;  
  7.     DBG(fsg, "store_file: \"%s\"\n", buf);  
  8. #if 0  
  9.     /* disabled because we need to allow closing the backing file if the media was removed */  
  10.     if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {  
  11.         LDBG(curlun, "eject attempt prevented\n");  
  12.         return -EBUSY;              /* "Door is locked" */  
  13.     }  
  14. #endif  
  15.     /* Remove a trailing newline */  
  16.     if (count > 0 && buf[count-1] == '\n')  
  17.         ((char *) buf)[count-1] = 0;  
  18.     /* Eject current medium */  
  19.     down_write(&fsg->filesem);  
  20.     if (backing_file_is_open(curlun)) {  
  21.         close_backing_file(fsg, curlun);  
  22.         curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;  
  23.           
  24.     }  
  25.     /* Load new medium */  
  26.     if (count > 0 && buf[0]) {  
  27.         rc = open_backing_file(fsg, curlun, buf);  
  28.         if (rc == 0)  
  29.             curlun->unit_attention_data =  
  30.                     SS_NOT_READY_TO_READY_TRANSITION;  
  31.                   
  32.     }  
  33.     up_write(&fsg->filesem);  
  34.     return (rc < 0 ? rc : count);  
  35. }  


   知道sysfs的原理的人都知道static DEVICE_ATTR(file, 0444, show_file, store_file);是负责读(cat/read)或直写(echo/write)设备属性文件的宏,具体实现就是上面这句(写)。

   看来看去 主要就是open_backing_file()函数的作用。还没怎么研究透,只知道肯定是这句起了作用,它打开了vold目录下的设备节点,并且初始化了一些东西。看到的现象就是,host端只识别单设备不同分区的挂载,但是不识别多存储设备的同时挂载。

   我不知道,到底是什么问题,让所有设备只挂载到一个设备节点上去了(冲突),而不是以往的/dev/sdb sdc sde等。

   希望能够学习解决

======================================================================

()第二个问题其实也没什么,只是 先从UDC(usb device controller)的驱动走了下,当时没注意。

不知道Android手机是不是驱动有这种只挂载单一存储设备的限制,至少目前看是这样的。想想也正常,手机一般只有一个SD插槽,自己本身内存有限,挂一个SD的存储设备无可厚非。。。

希望是自己代码的问题,还在解决中,希望有研究的达人,一起研究分享下这方面的经验。谢谢,估计很快会写(三),还在尝试,希望写下一篇的时候,能解决这个问题。

Android usb client mass-storage 多存储设备挂载问题解决

这是写的第三篇文章,废话不多说,接着上次的问题--不能同一时间挂载多个存储设备,继续探讨。

昨天,和一位linux 达人,在交流,无意中提到了这个问题,然后让他看了看现象,他说我的/devices/platform/tegra-udc.0/gadget这个目录,可能有问题。

于是查了下LUN是什么(Logical units)逻辑单元,跟SCSI有关,仔细查了下f_mass_storage.c的代码,里面的代码是fsg什么的,继续查了下

========================================================================

The File-backed Storage Gadget (FSG) provides support for the USB Mass Storage class. It can appear to a host as a set of up to 8 SCSI disk drives (called Logical UNits orLUNs), although most of the time a single LUN is all you will need. The information stored for each LUN must be maintained by the gadget somewhere, either in a normal file or in a block device such as a disk partition or even a ramdisk. This file or block device is called the backing storage for the gadget, and you tell FSG where the backing storage is when you load the gadget driver:

来自:http://www.linux-usb.org/gadget/file_storage.html

翻译一下:文件备份存储装置提供usb mass storage类的支持。它在主机端显示一连串最多高达8个的SCSI驱动盘符(被称作逻辑单元或者LUN,不过大多数时间里你只需要用到一个LUN每个LUN的信息必须被保存在某个gadget中,信息不是存在一个普通文件,就是存在一个块设备中,例如一个盘分区,甚至是一个ramdisk。这个文件或者块设备对于gadget被称作“backing storage”,而当你试图加载gadget驱动的时候,你可以告诉FSG"backing storage"在哪里。(英文不行,翻译可能有问题,达人请指正)。

==========================================================================

okay 大概知道,怎么回事了,应该是存储设备对应lun的多少的问题。按照linux的那套,其实一个client对应一个lun是正确的,但是现在情况是需要让client去把自己作为host,处理挂载自己身上的N个存储设备,所以按照道理来说,一个设备应该有一lun,多个设备就多个lun

进行验证,尝试去利用现在已经有的唯一的一个lun/file,向里面写挂载存储设备的路径,并且追加,证明确实只支持一个设备的写入,不支持什么追加。

现在有两种解决方式:

1.在主机端,模拟个文件 系统,将client的所有设备都挂载到这个文件系统上(那位达人给我的建议),客观的说,这应该是最科学的,在不该原有设计思路的最好的方式。不过实在是能力有限,无从下手。。于是想了下面一个方法。

2.就是假设,模拟多个lun节点,根据代码/drivers/usb/gadget/f_mass_storage.c中的MAX_LUNS 8的定义,先模拟8lun设备看看情况

看代码:

view plaincopy to clipboardprint?

  1. tatic int __init  
  2. fsg_function_bind(struct usb_configuration *c, struct usb_function *f)  
  3. {  
  4.     ...  
  5.     /* Find out how many LUNs there should be */  
  6.     i = MAX_LUNS;//fsg->nluns;  hook modify the i = MAX_LUNS.  
  7.     if (i == 0)  
  8.         i = 1;  
  9.     if (i > MAX_LUNS) {  
  10.         ERROR(fsg, "invalid number of LUNs: %d\n", i);  
  11.         rc = -EINVAL;  
  12.         goto out;  
  13.     }  
  14.     /* Create the LUNs, open their backing files, and register the 
  15.      * LUN devices in sysfs. */  
  16.     fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL);  
  17.     if (!fsg->luns) {  
  18.         rc = -ENOMEM;  
  19.         goto out;  
  20.     }  
  21.     fsg->nluns = i;  
  22. ...  
  23. }  


原来的i = fsg->nluns给我改成了MAX_LUNS,这只是临时改的,应该按照道理来说需要判断有多少个存储设备被挂载,然后给i的值赋多少。不过后来想想这样该貌似有问题,于是继续跟踪,发现在/arch/arm/mach-xxx /xx-board.c文件中有

view plaincopy to clipboardprint?

  1. static struct android_usb_platform_data android_usb_plat =  
  2. {  
  3.     .vendor_id = 0x0955,  
  4.     .product_id = 0x7000,  
  5.     .adb_product_id = 0x7100,  
  6.     .product_name = "ADB Composite Device",  
  7.     .manufacturer_name = "NVIDIA Corporation",  
  8.     .serial_number = "0000000000000000",  
  9.     .nluns = 1,  
  10.     .bulk_size = 16384,  
  11. };  


nluns = 1;看来是这个问题阿。所以改动成3,

然后编译驱动,加载之,发现/sys/devices/platform/tegra-udc.0/gadget下会出现lun0-lun73个节点,

尝试把client端的每个存储设备的挂载信息写到对应的lun中的file下,如echo "/dev/block/vold/179:0">file

结果证明全能挂载了okay.

如果需要自动挂载这些存储设备,而不是手动,需要改vold代码中的volmgr.cauto_add_volume()函数里,当每往链表中添加设备信息时候,给ums_path的值添上相应的lun路径就行了。

==========================================================================

不过这种方法虽然可以作出来,但是并不是好的方法,只是投机取巧,会被人鄙视的,在这因为研究学习用,所以写了出来。现在还在继续研究模拟文件系统如何挂载的方式,希望能有所突破


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 常州c1驾驶证满了12分怎么办 预约科目三成功后没交钱怎么办 预约成功后驾校不提交档案怎么办 c2刚满一年的驾照扣12分怎么办 怀孕6个月咳嗽很厉害怎么办 家门口有电线杆影响我建楼房怎么办 卡丢了不知道卡号怎么办 驾考网上预约用户被锁定了怎么办 人才中心拿出来的户口掉了怎么办 父母是南京集体户孩子没户口怎么办 二建挂靠中介单位不给证怎么办 小包工头遇到工人在工地摔伤怎么办 外地人买了城中村的房子改造怎么办 深圳社保怀孕了产检异地怎么办 成都公租房租满6年怎么办 二建审核资料如果照片丢失怎么办 身份证被冒用在外地办社保怎么办 蔷薇的嫩叶都被太阳晒死了怎么办 乐视手机进水了屏幕失灵怎么办 乐视手机进水了屏幕不显示怎么办 美团商家单量出现下滑怎么办 想开个小超市没经营过怎么办 华为7c手机wifi信号差怎么办 贞子从电视里爬出来怎么办 2个月的婴儿吓到怎么办 排卵日同房了没避孕怕怀孕怎么办 妻子因为我欺骗她要跟我离婚怎么办 老婆用苹果手机共享我的位置怎么办 孕妇餐后2小时血糖偏高怎么办 孕妇血糖餐后2小时数值高怎么办 股市退市的话股民的钱怎么办 美股股票退市了手里的股票怎么办 坐高铁安检时怕把包包弄坏了怎么办 很贵的包包高铁安检怎么办 如果过高铁安检东西被扣留怎么办 邻居家小孩把我家东西弄坏了怎么办 邻居早上6点放音乐扰民怎么办 隔壁楼邻居天天放音乐很吵怎么办 发现老公在卧室安了摄像头怎么办 憋的尿又没有厕所的时候怎么办 一岁宝宝拉屎总是拉出血怎么办