[PATCH v5 08/15] usb/gadget: f_mass_storage: create lun creation helpers for use in fsg_common_init

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux