Removed references to mod_data from fsg_common_init() function (which was the last part of the f_mass_storage.c file that referenced this object) and instead created fsg_config structure which fsg_common_init() takes as an argument -- it stores all configuration options that were previously taken from mod_data. Moreover, it (the fsg_config structure) allows per-LUN configuration of removable and CD-ROM emulation. Module parameters are handled by defining an object of fsg_module_parameters structure and then declaring module parameters via FSG_MODULE_PARAMETERS() macro. It adds proper declarations to the code making specified object be populated from module parameters. To use values stored there one may use either fsg_config_from_params() which will will a fsg_config structure with values taken from fsg_module_parameters structure or fsg_common_from_params() which will initialise fsg_common structure directly. Signed-off-by: Michal Nazarewicz <m.nazarewicz@xxxxxxxxxxx> --- drivers/usb/gadget/f_mass_storage.c | 191 +++++++++++++++++++++++----------- drivers/usb/gadget/mass_storage.c | 7 +- 2 files changed, 135 insertions(+), 63 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index b9420a7..db11bc2 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -260,51 +260,6 @@ static const char fsg_string_interface[] = "Mass Storage"; /*-------------------------------------------------------------------------*/ -/* Encapsulate the module parameter settings */ - -static struct { - char *file[FSG_MAX_LUNS]; - int ro[FSG_MAX_LUNS]; - unsigned int num_filenames; - unsigned int num_ros; - unsigned int nluns; - - int removable; - int can_stall; - int cdrom; - - unsigned short release; -} mod_data = { // Default values - .removable = 0, - .can_stall = 1, - .cdrom = 0, - .release = 0xffff, - }; - - -module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, - S_IRUGO); -MODULE_PARM_DESC(file, "names of backing files or devices"); - -module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); -MODULE_PARM_DESC(ro, "true to force read-only"); - -module_param_named(luns, mod_data.nluns, uint, S_IRUGO); -MODULE_PARM_DESC(luns, "number of LUNs"); - -module_param_named(removable, mod_data.removable, bool, S_IRUGO); -MODULE_PARM_DESC(removable, "true to simulate removable media"); - -module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); -MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); - -module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); -MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); - - -/*-------------------------------------------------------------------------*/ - - /* Data shared by all the FSG instances. */ struct fsg_common { struct usb_gadget *gadget; @@ -334,6 +289,23 @@ struct fsg_common { }; +struct fsg_config { + unsigned nluns; + struct fsg_lun_config { + const char *filename; + char ro; + char removable; + char cdrom; + } luns[FSG_MAX_LUNS]; + + const char *vendor_name; /* 8 characters or less */ + const char *product_name; /* 16 characters or less */ + u16 release; + + char can_stall; +}; + + struct fsg_dev { struct usb_function function; struct usb_composite_dev*cdev; @@ -2481,19 +2453,19 @@ static inline void fsg_common_put(struct fsg_common *common) } -static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev) +static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev, + struct fsg_config *cfg) { struct usb_gadget *gadget = cdev->gadget; struct fsg_common *common; struct fsg_buffhd *bh; struct fsg_lun *curlun; + struct fsg_lun_config *lcfg; int nluns, i, rc; char *pathbuf; /* Find out how many LUNs there should be */ - nluns = mod_data.nluns; - if (nluns == 0) - nluns = max(mod_data.num_filenames, 1u); + nluns = cfg->nluns; if (nluns < 1 || nluns > FSG_MAX_LUNS) { dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns); return ERR_PTR(-EINVAL); @@ -2515,10 +2487,10 @@ static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev) init_rwsem(&common->filesem); - for (i = 0; i < nluns; ++i, ++curlun) { - curlun->cdrom = !!mod_data.cdrom; - curlun->ro = mod_data.cdrom || mod_data.ro[i]; - curlun->removable = mod_data.removable; + for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { + curlun->cdrom = !!lcfg->cdrom; + curlun->ro = lcfg->cdrom || lcfg->ro; + curlun->removable = lcfg->removable; curlun->dev.release = fsg_lun_release; curlun->dev.parent = &gadget->dev; /* curlun->dev.driver = &fsg_driver.driver; XXX */ @@ -2540,11 +2512,11 @@ static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev) if (rc) goto error_luns; - if (mod_data.file[i] && *mod_data.file[i]) { - rc = fsg_lun_open(curlun, mod_data.file[i]); + if (lcfg->filename) { + rc = fsg_lun_open(curlun, lcfg->filename); if (rc) goto error_luns; - } else if (!mod_data.removable) { + } else if (!curlun->removable) { ERROR(common, "no file given for LUN%d\n", i); rc = -EINVAL; goto error_luns; @@ -2565,9 +2537,9 @@ static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev) /* Prepare inquiryString */ - if (mod_data.release != 0xffff) { - i = mod_data.release; - } else if (mod_data.release == 0xffff) { + if (cfg->release != 0xffff) { + i = cfg->release; + } else { /* The sa1100 controller is not supported */ i = gadget_is_sa1100(gadget) ? -1 @@ -2580,18 +2552,23 @@ static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev) i = 0x0399; } } +#define OR(x, y) ((x) ? (x) : (y)) snprintf(common->inquiry_string, sizeof common->inquiry_string, - "Linux %-16s%04x", + "%-8s%-16s%04x", + OR(cfg->vendor_name, "Linux "), /* Assume product name dependent on the first LUN */ - common->luns->cdrom ? "File-Stor Gadget" : "File-CD Gadget ", + OR(cfg->product_name, common->luns->cdrom + ? "File-Stor Gadget" + : "File-CD Gadget "), i); +#undef OR /* Some peripheral controllers are known not to be able to * halt bulk endpoints correctly. If one of them is present, * disable stalls. */ - common->can_stall = mod_data.can_stall && + common->can_stall = cfg->can_stall && !(gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget)); @@ -2808,3 +2785,93 @@ static int fsg_add(struct usb_composite_dev *cdev, return rc; } + + + +/************************* Module parameters *************************/ + + +struct fsg_module_parameters { + char *file[FSG_MAX_LUNS]; + int ro[FSG_MAX_LUNS]; + int removable[FSG_MAX_LUNS]; + int cdrom[FSG_MAX_LUNS]; + + unsigned int file_count, ro_count, removable_count, cdrom_count; + unsigned int luns; /* nluns */ + int stall; /* can_stall */ +}; + + +#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ + module_param_array_named(prefix ## name, params.name, type, \ + &prefix ## params.name ## _count, \ + S_IRUGO); \ + MODULE_PARM_DESC(prefix ## name, desc) + +#define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \ + module_param_named(prefix ## name, params.name, type, \ + S_IRUGO); \ + MODULE_PARM_DESC(prefix ## name, desc) + +#define FSG_MODULE_PARAMETERS(prefix, params) \ + _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \ + "names of backing files or devices"); \ + _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \ + "true to force read-only"); \ + _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \ + "true to simulate removable media"); \ + _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \ + "true to simulate CD-ROM instead of disk"); \ + _FSG_MODULE_PARAM(prefix, params, luns, uint, \ + "number of LUNs"); \ + _FSG_MODULE_PARAM(prefix, params, stall, bool, \ + "false to prevent bulk stalls") + + +static void +fsg_config_from_params(struct fsg_config *cfg, + const struct fsg_module_parameters *params) +{ + struct fsg_lun_config *lun; + unsigned i, nluns; + + /* Configure LUNs */ + nluns = cfg->nluns = !params->luns + ? params->file_count ? params->file_count : 1 + : params->luns; + for (i = 0, lun = cfg->luns; + i < FSG_MAX_LUNS && i < nluns; + ++i, ++lun) { + lun->ro = !!params->ro[i]; + lun->cdrom = !!params->cdrom[i]; + lun->removable = + params->removable_count <= i || params->removable[i]; + lun->filename = + params->file_count > i && params->file[i][0] + ? params->file[i] + : 0; + } + + /* Let FSG use defaults */ + cfg->vendor_name = 0; + cfg->product_name = 0; + cfg->release = 0xffff; + + /* Finalise */ + cfg->can_stall = params->stall; +} + +static inline struct fsg_common * +fsg_common_from_params(struct usb_composite_dev *cdev, + const struct fsg_module_parameters *params) + __attribute__((unused)); +static inline struct fsg_common * +fsg_common_from_params(struct usb_composite_dev *cdev, + const struct fsg_module_parameters *params) +{ + struct fsg_config cfg; + fsg_config_from_params(&cfg, params); + return fsg_common_init(cdev, &cfg); +} + diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 832035b..20c689c 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -127,6 +127,11 @@ static struct usb_gadget_strings *dev_strings[] = { /****************************** Configurations ******************************/ +static struct fsg_module_parameters mod_data = { + .stall = 1 +}; +FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); + static int __init msg_do_config(struct usb_configuration *c) { struct fsg_common *common; @@ -137,7 +142,7 @@ static int __init msg_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - common = fsg_common_init(c->cdev); + common = fsg_common_from_params(c->cdev, &mod_data); if (IS_ERR(common)) return PTR_ERR(common); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html