fsg_common_init is a lengthy function. Factor portions of it out.
Signed-off-by: Andrzej Pietrasiewicz <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html