[PATCH 21/24] [Storage] fsg_config structure added & module parameters handlig changed

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

 



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

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

  Powered by Linux