http://blog.csdn.net/airk000/article/details/7887677
接《Android4.0 USB挂载内核驱动层流程分析(一)》
1.supported_functions
- static struct android_usb_function *supported_functions[] = {
- &rmnet_smd_function,
- &rmnet_sdio_function,
- &rmnet_smd_sdio_function,
- &rmnet_function,
- &diag_function,
- &serial_function,
- &adb_function,
- &ccid_function,
- // &acm_function,
- &mtp_function,
- &ptp_function,
- &rndis_function,
- &mass_storage_function,
- &accessory_function,
- NULL
- };
既然是分析USB挂载流程,那就不看别的功能函数,直接跳向mass_storage_function。
2.mass_storage_function
- static struct android_usb_function mass_storage_function = {
- .name = "mass_storage",
- .init = mass_storage_function_init,
- .cleanup = mass_storage_function_cleanup,
- .bind_config = mass_storage_function_bind_config,
- .attributes = mass_storage_function_attributes,
- };
包括功能名、初始化、清理、绑定配置、属性。
关于android_usb_function结构体:
- struct android_usb_function {
- char *name; //"mass_storage"
- void *config;
- struct device *dev;
- char *dev_name;
- struct device_attribute **attributes;
- /* for android_dev.enabled_functions */
- struct list_head enabled_list;
- /* Optional: initialization during gadget bind */ //当设备驱动绑定时的初始化(可选)
- int (*init)(struct android_usb_function *, struct usb_composite_dev *);
- /* Optional: cleanup during gadget unbind */ //当设备解绑的时候清理工作(可选)
- void (*cleanup)(struct android_usb_function *);
- int (*bind_config)(struct android_usb_function *, struct usb_configuration *); //绑定时的配置
- /* Optional: called when the configuration is removed */ //当配置被移除时(可选)
- void (*unbind_config)(struct android_usb_function *, struct usb_configuration *);
- /* Optional: handle ctrl requests before the device is configured */ //设备被配置前有什么请求的话会运行这个函数(可选)
- int (*ctrlrequest)(struct android_usb_function *,
- struct usb_composite_dev *,
- const struct usb_ctrlrequest *);
- };
init函数:mass_storage_function_init
在分析mass_storage_function_init函数之前,先要了解一个很重要的结构体:
- struct fsg_config {
- unsigned nluns;
- struct fsg_lun_config {
- const char *filename;
- char ro;
- char removable;
- char cdrom;
- char nofua;
- } luns[FSG_MAX_LUNS];
- const char *lun_name_format;
- const char *thread_name;
- /* Callback functions. */
- const struct fsg_operations *ops;
- /* Gadget's private data. */
- void *private_data;
- const char *vendor_name; /* 8 characters or less */
- const char *product_name; /* 16 characters or less */
- u16 release;
- char can_stall;
- };
nluns 最大支持的LUN数量(LUN:Logical units)
luns 每个LUN的参数,如下
-->filename 此LUN的名字,如果不是可移除的(removable)则不需要
-->ro FALSE(TRUE),设置read-only,如果是CD-ROM则不可能挂载成R/W
-->removable TRUE(FALSE),说明此LUN可移除
-->cdrom FALSE(TRUE),此LUN是否为CD-ROM
-->nofua FALSE(TRUE),此LUN是否可忽略
还有lun_name_format 建议为lun%d形式,如果不只是一个LUN,可以用%d来引导,必须是整型数字,如果不符合,可能将出现不可预知的错误。
thread_name 默认名字是"file_storage",是应该叫内核线程名字吧
了解了这个结构体后,看mass_storage_function_init函数:
- static int mass_storage_function_init(struct android_usb_function *f,
- struct usb_composite_dev *cdev)
- {
- struct mass_storage_function_config *config;
- struct fsg_common *common;
- int err;
- int i;
- config = kzalloc(sizeof(struct mass_storage_function_config),
- GFP_KERNEL);
- if (!config)
- return -ENOMEM;
- /* support multi luns and ro of ench lun is set to 0 to allow
- * opening "filename" in R/W mode. If the file is read-only,
- * the ro will be set to 1 automatically.
- */
- config->fsg.nluns = USB_MAX_LUNS; //USB_MAX_LUNS=3,说明支持三个存储设备。
- for (i = 0; i < USB_MAX_LUNS; i++) { //三个设备都可以移除,可以忽略,可以挂载为R/W,没有一个是CD-ROM
- config->fsg.luns[i].removable = 1;
- config->fsg.luns[i].nofua = 1;
- }
- common = fsg_common_init(NULL, cdev, &config->fsg); //交给fsg_common_init去根据配置创建设备,具体实现在f_mass_storage.c中
- if (IS_ERR(common)) {
- kfree(config);
- return PTR_ERR(common);
- }
- /* create a symlink for each lun */
- for (i = 0; i < USB_MAX_LUNS; i++)
- {
- err = sysfs_create_link(&f->dev->kobj,
- &common->luns[i].dev.kobj,
- dev_name(&common->luns[i].dev)); //创建设备链接
- if (err)
- {
- fsg_common_release(&common->ref);
- kfree(config);
- return err;
- }
- }
- config->common = common;
- f->config = config;
- return 0;
- }