Signed-off-by: Andrzej Pietrasiewicz <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/Kconfig | 1 +
drivers/usb/gadget/acm_ms.c | 78 ++++++++++++++++++++++++-------------------
2 files changed, 45 insertions(+), 34 deletions(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index bca3214..6d4ec9d 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -906,6 +906,7 @@ config USB_G_ACM_MS
select USB_U_SERIAL
select USB_F_ACM
select USB_U_MS
+ select USB_F_MASS_STORAGE
help
This driver provides two functions in one configuration:
a mass storage, and a CDC ACM (serial port) link.
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
index 0af60f3..2fc559c 100644
--- a/drivers/usb/gadget/acm_ms.c
+++ b/drivers/usb/gadget/acm_ms.c
@@ -33,15 +33,7 @@
/*-------------------------------------------------------------------------*/
-/*
- * Kbuild is not very cooperative with respect to linking separately
- * compiled library objects into one module. So for now we won't use
- * separate compilation ... ensuring init/exit sections work to shrink
- * the runtime footprint, and giving us at least some parts of what
- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
- */
-#define USB_FMS_INCLUDED
-#include "f_mass_storage.c"
+#include "f_mass_storage.h"
/*-------------------------------------------------------------------------*/
USB_GADGET_COMPOSITE_OPTIONS();
@@ -107,16 +99,20 @@ static struct usb_gadget_strings *dev_strings[] = {
static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
-static struct fsg_common fsg_common;
-
/*-------------------------------------------------------------------------*/
static struct usb_function *f_acm;
static struct usb_function_instance *f_acm_inst;
+
+static struct usb_function *f_fsg;
+static struct usb_function_instance *f_fsg_inst;
+
/*
* We _always_ have both ACM and mass storage functions.
*/
static int __init acm_ms_do_config(struct usb_configuration *c)
{
+ struct fsg_config config;
+ struct fsg_common *common;
int status;
if (gadget_is_otg(c->cdev->gadget)) {
@@ -131,23 +127,49 @@ static int __init acm_ms_do_config(struct
usb_configuration *c)
f_acm = usb_get_function(f_acm_inst);
if (IS_ERR(f_acm)) {
status = PTR_ERR(f_acm);
- goto err_func;
+ goto err_acm_func;
}
status = usb_add_function(c, f_acm);
if (status < 0)
- goto err_conf;
+ goto err_acm_conf;
+
+ f_fsg_inst = usb_get_function_instance("mass_storage");
+ if (IS_ERR(f_fsg_inst)) {
+ status = PTR_ERR(f_fsg_inst);
+ goto err_acm;
+ }
+
+ common = container_of(f_fsg_inst, struct fsg_common, func_inst);
+ fsg_config_from_params(&config, &fsg_mod_data);
+ common = fsg_common_init_memset(common, c->cdev, &config, false);
+ if (IS_ERR(common)) {
+ status = PTR_ERR(common);
+ goto err_fsg_func;
+ }
+
+ f_fsg = usb_get_function(f_fsg_inst);
+ if (IS_ERR(f_fsg)) {
+ status = PTR_ERR(f_fsg);
+ goto err_fsg_func;
+ }
- status = fsg_bind_config(c->cdev, c, &fsg_common);
+ status = usb_add_function(c, f_fsg);
if (status < 0)
- goto err_fsg;
+ goto err_fsg_conf;
return 0;
-err_fsg:
+
+err_fsg_conf:
+ usb_put_function(f_fsg);
+err_fsg_func:
+ fsg_common_put(common);
+ usb_put_function_instance(f_fsg_inst);
+err_acm:
usb_remove_function(c, f_acm);
-err_conf:
+err_acm_conf:
usb_put_function(f_acm);
-err_func:
+err_acm_func:
usb_put_function_instance(f_acm_inst);
return status;
}
@@ -165,14 +187,6 @@ static int __init acm_ms_bind(struct usb_composite_dev
*cdev)
{
struct usb_gadget *gadget = cdev->gadget;
int status;
- void *retp;
-
- /* set up mass storage function */
- retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
- if (IS_ERR(retp)) {
- status = PTR_ERR(retp);
- return PTR_ERR(retp);
- }
/*
* Allocate string descriptor numbers ... note that string
@@ -180,30 +194,26 @@ static int __init acm_ms_bind(struct usb_composite_dev
*cdev)
*/
status = usb_string_ids_tab(cdev, strings_dev);
if (status < 0)
- goto fail1;
+ return status;
device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
/* register our configuration */
status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config);
if (status < 0)
- goto fail1;
+ return status;
usb_composite_overwrite_options(cdev, &coverwrite);
dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
DRIVER_DESC);
- fsg_common_put(&fsg_common);
return 0;
-
- /* error recovery */
-fail1:
- fsg_common_put(&fsg_common);
- return status;
}
static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
{
usb_put_function(f_acm);
+ usb_put_function(f_fsg);
+ usb_put_function_instance(f_fsg_inst);
usb_put_function_instance(f_acm_inst);
return 0;
}
--
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