Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- 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 0226eee..d79cc4b 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -860,6 +860,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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html