[PATCH 22/24] [Storage] fsg_common_init() may initialise object in place

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

 



fsg_common_init() takes now additional argument, pointer to
fsg_common structure.  If it is NULL function behaves as
previously -- allocates storage and initialises object.  If
it is non-NULL object is initialised in given location (handy
if msf_common were to be a field of another structure or
static variable).

Also, fsg_common_release() will free storage only if
free_storage_on_release is set -- it is initialised by
msf_common_init(): set if allocation was done, unset
otherwise (one may overwrite it of course).

fsg_common_from_params() also accepts this new argument.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@xxxxxxxxxxx>
---
 drivers/usb/gadget/f_mass_storage.c |   31 +++++++++++++++++++++----------
 drivers/usb/gadget/mass_storage.c   |    2 +-
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index db11bc2..33ff65b 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -280,6 +280,7 @@ struct fsg_common {
 	struct fsg_lun		*curlun;
 
 	unsigned int		can_stall:1;
+	unsigned int		free_storage_on_release:1;
 
 	/* Vendor (8 chars), product (16 chars), release (4
 	 * hexadecimal digits) and NUL byte */
@@ -2453,11 +2454,12 @@ static inline void fsg_common_put(struct fsg_common *common)
 }
 
 
-static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev,
+/* common may be NULL which means allocate */
+static 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_common *common;
 	struct fsg_buffhd *bh;
 	struct fsg_lun *curlun;
 	struct fsg_lun_config *lcfg;
@@ -2471,9 +2473,16 @@ static struct fsg_common *fsg_common_init(struct usb_composite_dev *cdev,
 		return ERR_PTR(-EINVAL);
 	}
 
-	common = kzalloc(sizeof *common, GFP_KERNEL);
-	if (!common)
-		return ERR_PTR(-ENOMEM);
+	/* Allocate? */
+	if (!common) {
+		common = kzalloc(sizeof *common, GFP_KERNEL);
+		if (!common)
+			return ERR_PTR(-ENOMEM);
+		common->free_storage_on_release = 1;
+	} else {
+		memset(common, 0, sizeof common);
+		common->free_storage_on_release = 0;
+	}
 	common->gadget = gadget;
 
 	/* Create the LUNs, open their backing files, and register the
@@ -2630,7 +2639,8 @@ static void fsg_common_release(struct kref *ref)
 	}
 
 	kfree(common->luns);
-	kfree(common);
+	if (common->free_storage_on_release)
+		kfree(common);
 }
 
 
@@ -2863,15 +2873,16 @@ fsg_config_from_params(struct fsg_config *cfg,
 }
 
 static inline struct fsg_common *
-fsg_common_from_params(struct usb_composite_dev *cdev,
+fsg_common_from_params(struct fsg_common *common,
+		       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,
+fsg_common_from_params(struct fsg_common *common,
+		       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);
+	return fsg_common_init(common, cdev, &cfg);
 }
-
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 20c689c..bd9c8a8 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -142,7 +142,7 @@ static int __init msg_do_config(struct usb_configuration *c)
 		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	}
 
-	common = fsg_common_from_params(c->cdev, &mod_data);
+	common = fsg_common_from_params(0, 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