fsg_common_init is a lengthy function. Factor portions of it out. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/usb/gadget/f_mass_storage.c | 260 ++++++++++++++++++++++------------- drivers/usb/gadget/f_mass_storage.h | 6 + 2 files changed, 169 insertions(+), 97 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 61952b6..441bde5 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2829,18 +2829,172 @@ int fsg_common_set_cdev(struct fsg_common *common, return 0; } +static inline int fsg_common_add_sysfs(struct fsg_common *common, + struct fsg_lun *lun) +{ + int rc; + + rc = device_register(&lun->dev); + if (rc) { + put_device(&lun->dev); + return rc; + } + + rc = device_create_file(&lun->dev, + lun->cdrom + ? &dev_attr_ro_cdrom + : &dev_attr_ro); + if (rc) + goto error_cdrom; + rc = device_create_file(&lun->dev, + lun->removable + ? &dev_attr_file + : &dev_attr_file_nonremovable); + if (rc) + goto error_removable; + rc = device_create_file(&lun->dev, &dev_attr_nofua); + if (rc) + goto error_nofua; + + return 0; + +error_nofua: + device_remove_file(&lun->dev, + lun->removable + ? &dev_attr_file + : &dev_attr_file_nonremovable); +error_removable: + device_remove_file(&lun->dev, + lun->cdrom + ? &dev_attr_ro_cdrom + : &dev_attr_ro); +error_cdrom: + device_unregister(&lun->dev); + return rc; +} + #define MAX_LUN_NAME_LEN 80 +int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, + unsigned int id, const char *name, + const char **name_pfx) +{ + struct fsg_lun *lun; + char *pathbuf; + int rc = -ENOMEM; + int name_len; + + if (!common->nluns || !common->luns) + return -ENODEV; + + if (common->luns[id]) + return -EBUSY; + + name_len = strlen(name) + 1; + if (name_len > MAX_LUN_NAME_LEN) + return -ENAMETOOLONG; + + lun = kzalloc(sizeof(*lun), GFP_KERNEL); + if (!lun) + return -ENOMEM; + + lun->name = kstrndup(name, name_len, GFP_KERNEL); + if (!lun->name) + goto error_name; + lun->name_pfx = name_pfx; + + lun->cdrom = !!cfg->cdrom; + lun->ro = cfg->cdrom || cfg->ro; + lun->initially_ro = lun->ro; + lun->removable = !!cfg->removable; + + common->luns[id] = lun; + + if (common->sysfs) { + lun->dev.release = fsg_lun_release; + lun->dev.parent = &common->gadget->dev; + dev_set_drvdata(&lun->dev, &common->filesem); + dev_set_name(&lun->dev, name); + + rc = fsg_common_add_sysfs(common, lun); + if (rc) { + pr_info("failed to register LUN%d: %d\n", id, rc); + goto error_sysfs; + } + } + + if (cfg->filename) { + rc = fsg_lun_open(lun, cfg->filename); + if (rc) + goto error_lun; + } else if (!lun->removable) { + pr_err("no file given for LUN%d\n", id); + rc = -EINVAL; + goto error_lun; + } + + pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); + { + char *p = "(no medium)"; + if (fsg_lun_is_open(lun)) { + p = "(error)"; + if (pathbuf) { + p = d_path(&lun->filp->f_path, + pathbuf, PATH_MAX); + if (IS_ERR(p)) + p = "(error)"; + } + } + pr_info("LUN: %s%s%sfile: %s\n", + lun->removable ? "removable " : "", + lun->ro ? "read only " : "", + lun->cdrom ? "CD-ROM " : "", + p); + } + kfree(pathbuf); + + return 0; + +error_lun: + if (common->sysfs) { + fsg_common_remove_sysfs(lun); + device_unregister(&lun->dev); + } + fsg_lun_close(lun); +error_sysfs: + common->luns[id] = NULL; + kfree(lun->name); +error_name: + kfree(lun); + return rc; +} + +int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg) +{ + char buf[40]; /* enough for 2^128 decimal */ + int i, rc; + + for (i = 0; i < common->nluns; ++i) { + snprintf(buf, sizeof(buf), "lun%d", i); + rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL); + if (rc) + goto fail; + } + + pr_info("Number of LUNs=%d\n", common->nluns); + + return 0; + +fail: + _fsg_common_remove_luns(common, i); + return rc; +} + struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_composite_dev *cdev, struct fsg_config *cfg) { - struct usb_gadget *gadget = cdev->gadget; - struct fsg_lun **curlun_it; - struct fsg_lun_config *lcfg; - int nluns, i, rc; - char *pathbuf; - + int i, rc; common = fsg_common_setup(common, !!common); if (IS_ERR(common)) @@ -2865,72 +3019,10 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, rc = fsg_common_set_nluns(common, cfg->nluns); if (rc) goto error_release; - curlun_it = common->luns; - nluns = cfg->nluns; - for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) { - struct fsg_lun *curlun; - - curlun = kzalloc(sizeof(*curlun), GFP_KERNEL); - if (!curlun) { - rc = -ENOMEM; - common->nluns = i; - goto error_release; - } - *curlun_it = curlun; - - curlun->name = kzalloc(MAX_LUN_NAME_LEN, GFP_KERNEL); - if (!curlun->name) { - rc = -ENOMEM; - common->nluns = i; - goto error_release; - } - curlun->cdrom = !!lcfg->cdrom; - curlun->ro = lcfg->cdrom || lcfg->ro; - curlun->initially_ro = curlun->ro; - curlun->removable = lcfg->removable; - curlun->dev.release = fsg_lun_release; - curlun->dev.parent = &gadget->dev; - /* curlun->dev.driver = &fsg_driver.driver; XXX */ - dev_set_drvdata(&curlun->dev, &common->filesem); - dev_set_name(&curlun->dev, "lun%d", i); - strlcpy(curlun->name, dev_name(&curlun->dev), MAX_LUN_NAME_LEN); - - rc = device_register(&curlun->dev); - if (rc) { - INFO(common, "failed to register LUN%d: %d\n", i, rc); - common->nluns = i; - put_device(&curlun->dev); - kfree(curlun); - goto error_release; - } - - rc = device_create_file(&curlun->dev, - curlun->cdrom - ? &dev_attr_ro_cdrom - : &dev_attr_ro); - if (rc) - goto error_luns; - rc = device_create_file(&curlun->dev, - curlun->removable - ? &dev_attr_file - : &dev_attr_file_nonremovable); - if (rc) - goto error_luns; - rc = device_create_file(&curlun->dev, &dev_attr_nofua); - if (rc) - goto error_luns; - - if (lcfg->filename) { - rc = fsg_lun_open(curlun, lcfg->filename); - if (rc) - goto error_luns; - } else if (!curlun->removable) { - ERROR(common, "no file given for LUN%d\n", i); - rc = -EINVAL; - goto error_luns; - } - } + rc = fsg_common_create_luns(common, cfg); + if (rc) + goto error_release; /* Prepare inquiryString */ i = get_default_bcdDevice(); @@ -2942,7 +3034,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, : "File-Stor Gadget"), i); - /* Tell the thread to start working */ common->thread_task = kthread_create(fsg_main_thread, common, "file-storage"); @@ -2955,37 +3046,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); INFO(common, "Number of LUNs=%d\n", common->nluns); - pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); - for (i = 0, nluns = common->nluns, curlun_it = common->luns; - i < nluns; - ++curlun_it, ++i) { - struct fsg_lun *curlun = *curlun_it; - char *p = "(no medium)"; - if (fsg_lun_is_open(curlun)) { - p = "(error)"; - if (pathbuf) { - p = d_path(&curlun->filp->f_path, - pathbuf, PATH_MAX); - if (IS_ERR(p)) - p = "(error)"; - } - } - LINFO(curlun, "LUN: %s%s%sfile: %s\n", - curlun->removable ? "removable " : "", - curlun->ro ? "read only " : "", - curlun->cdrom ? "CD-ROM " : "", - p); - } - kfree(pathbuf); - DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); wake_up_process(common->thread_task); return common; -error_luns: - common->nluns = i + 1; error_release: common->state = FSG_STATE_TERMINATED; /* The thread is dead */ /* Call fsg_common_release() directly, ref might be not initialised. */ diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h index 547a5c6..08243c3 100644 --- a/drivers/usb/gadget/f_mass_storage.h +++ b/drivers/usb/gadget/f_mass_storage.h @@ -122,6 +122,12 @@ void fsg_common_free_luns(struct fsg_common *common); int fsg_common_set_nluns(struct fsg_common *common, int nluns); +int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, + unsigned int id, const char *name, + const char **name_pfx); + +int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg); + void fsg_config_from_params(struct fsg_config *cfg, const struct fsg_module_parameters *params, unsigned int fsg_num_buffers); -- 1.7.0.4 -- 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