接《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 };
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; };上边这个结构体在f_mass_storage.c中,在C文件开头就对这个结构体有详细的介绍:
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; }至此基本的结构也就初始化完成了。配置很重要,一定不能错。明天再分析android_bind。