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