Converting mass storage to the new function interface requires converting
the USB mass storage's function code and its users.
This patch converts the f_mass_storage.c to the new function interface.
The file is now compiled into a separate usb_f_mass_storage.ko module.
The old function interface is provided by means of a preprocessor conditional
directives. After all users are converted, the old interface can be removed.

Signed-off-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.p...@samsung.com>
---
 drivers/usb/gadget/Kconfig          |    3 +
 drivers/usb/gadget/Makefile         |    2 +
 drivers/usb/gadget/acm_ms.c         |    1 +
 drivers/usb/gadget/f_mass_storage.c |  136 +++++++++++++++++++++++++++++-----
 drivers/usb/gadget/mass_storage.c   |    1 +
 drivers/usb/gadget/multi.c          |    1 +
 6 files changed, 124 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 411d89f..bca3214 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -560,6 +560,9 @@ config USB_U_SERIAL
 config USB_U_MS
        tristate
 
+config USB_F_MASS_STORAGE
+       tristate
+
 choice
        tristate "USB Gadget Drivers"
        default USB_ETH
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 145c985..395acbd 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -83,4 +83,6 @@ usb_f_ss_lb-y                 := f_loopback.o f_sourcesink.o
 obj-$(CONFIG_USB_F_SS_LB)      += usb_f_ss_lb.o
 u_ms-y                         := storage_common.o
 obj-$(CONFIG_USB_U_MS)         += u_ms.o
+usb_f_mass_storage-y           := f_mass_storage.o
+obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
 obj-$(CONFIG_USB_U_SERIAL)     += u_serial.o
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
index 4b947bb..0af60f3 100644
--- a/drivers/usb/gadget/acm_ms.c
+++ b/drivers/usb/gadget/acm_ms.c
@@ -40,6 +40,7 @@
  * 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"
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/f_mass_storage.c 
b/drivers/usb/gadget/f_mass_storage.c
index c7c7414..7ab813d 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -213,6 +213,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/freezer.h>
+#include <linux/module.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -2527,6 +2528,9 @@ void fsg_common_put(struct fsg_common *common)
 {
        kref_put(&common->ref, fsg_common_release);
 }
+#ifndef USB_FMS_INCLUDED
+EXPORT_SYMBOL(fsg_common_put);
+#endif
 
 /* check if fsg_num_buffers is within a valid range */
 static inline int fsg_num_buffers_validate(void)
@@ -2744,6 +2748,9 @@ error_release:
        fsg_common_release(&common->ref);
        return ERR_PTR(rc);
 }
+#ifndef USB_FMS_INCLUDED
+EXPORT_SYMBOL(fsg_common_init_memset);
+#endif
 
 static void fsg_common_release(struct kref *ref)
 {
@@ -2793,24 +2800,6 @@ static void fsg_common_release(struct kref *ref)
 
 /*-------------------------------------------------------------------------*/
 
-static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
-{
-       struct fsg_dev          *fsg = fsg_from_func(f);
-       struct fsg_common       *common = fsg->common;
-
-       DBG(fsg, "unbind\n");
-       if (fsg->common->fsg == fsg) {
-               fsg->common->new_fsg = NULL;
-               raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
-               /* FIXME: make interruptible or killable somehow? */
-               wait_event(common->fsg_wait, common->fsg != fsg);
-       }
-
-       fsg_common_put(common);
-       usb_free_all_descriptors(&fsg->function);
-       kfree(fsg);
-}
-
 static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 {
        struct fsg_dev          *fsg = fsg_from_func(f);
@@ -2871,13 +2860,33 @@ autoconf_fail:
        return -ENOTSUPP;
 }
 
-/****************************** ADD FUNCTION ******************************/
+/****************************** ALLOCATE FUNCTION *************************/
 
 static struct usb_gadget_strings *fsg_strings_array[] = {
        &fsg_stringtab,
        NULL,
 };
 
+#ifdef USB_FMS_INCLUDED
+
+static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct fsg_dev          *fsg = fsg_from_func(f);
+       struct fsg_common       *common = fsg->common;
+
+       DBG(fsg, "unbind\n");
+       if (fsg->common->fsg == fsg) {
+               fsg->common->new_fsg = NULL;
+               raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+               /* FIXME: make interruptible or killable somehow? */
+               wait_event(common->fsg_wait, common->fsg != fsg);
+       }
+
+       fsg_common_put(common);
+       usb_free_all_descriptors(&fsg->function);
+       kfree(fsg);
+}
+
 static int fsg_bind_config(struct usb_composite_dev *cdev,
                           struct usb_configuration *c,
                           struct fsg_common *common)
@@ -2892,7 +2901,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
        fsg->function.name        = FSG_DRIVER_DESC;
        fsg->function.strings     = fsg_strings_array;
        fsg->function.bind        = fsg_bind;
-       fsg->function.unbind      = fsg_unbind;
+       fsg->function.unbind      = old_fsg_unbind;
        fsg->function.setup       = fsg_setup;
        fsg->function.set_alt     = fsg_set_alt;
        fsg->function.disable     = fsg_disable;
@@ -2914,6 +2923,90 @@ static int fsg_bind_config(struct usb_composite_dev 
*cdev,
        return rc;
 }
 
+#else
+
+static void fsg_free_inst(struct usb_function_instance *fi)
+{
+       struct fsg_common *common;
+
+       common = container_of(fi, struct fsg_common, func_inst);
+       kfree(common);
+}
+
+static struct usb_function_instance *fsg_alloc_inst(void)
+{
+       struct fsg_common *common;
+
+       common = kzalloc(sizeof(*common), GFP_KERNEL);
+       if (!common)
+               return ERR_PTR(-ENOMEM);
+       common->func_inst.free_func_inst = fsg_free_inst;
+
+       return &common->func_inst;
+}
+
+static void fsg_free(struct usb_function *f)
+{
+       struct fsg_dev *fsg;
+
+       fsg = container_of(f, struct fsg_dev, function);
+
+       kfree(fsg);
+}
+
+static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct fsg_dev          *fsg = fsg_from_func(f);
+       struct fsg_common       *common = fsg->common;
+
+       DBG(fsg, "unbind\n");
+       if (fsg->common->fsg == fsg) {
+               fsg->common->new_fsg = NULL;
+               raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+               /* FIXME: make interruptible or killable somehow? */
+               wait_event(common->fsg_wait, common->fsg != fsg);
+       }
+
+       fsg_common_put(common);
+       usb_free_all_descriptors(&fsg->function);
+}
+
+static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
+{
+       struct fsg_common *common = container_of(fi, struct fsg_common,
+                                                func_inst);
+       struct fsg_dev *fsg;
+
+       fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
+       if (unlikely(!fsg))
+               return NULL;
+
+       fsg->function.name        = FSG_DRIVER_DESC;
+       fsg->function.strings     = fsg_strings_array;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+       fsg->function.set_alt     = fsg_set_alt;
+       fsg->function.disable     = fsg_disable;
+       fsg->function.free_func   = fsg_free;
+
+       fsg->common               = common;
+       /*
+        * Our caller holds a reference to common structure so we
+        * don't have to be worry about it being freed until we return
+        * from this function.  So instead of incrementing counter now
+        * and decrement in error recovery we increment it only when
+        * call to usb_add_function() was successful.
+        */
+
+       return &fsg->function;
+}
+
+DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal Nazarewicz");
+
+#endif
 
 /************************* Module parameters *************************/
 
@@ -2948,4 +3041,7 @@ void fsg_config_from_params(struct fsg_config *cfg,
        /* Finalise */
        cfg->can_stall = params->stall;
 }
+#ifndef USB_FMS_INCLUDED
+EXPORT_SYMBOL(fsg_config_from_params);
+#endif
 
diff --git a/drivers/usb/gadget/mass_storage.c 
b/drivers/usb/gadget/mass_storage.c
index 99cc56f..1b668cc 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -55,6 +55,7 @@
  * 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"
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index a74ebef..b138a22 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -41,6 +41,7 @@ MODULE_LICENSE("GPL");
  * 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_ecm.c"
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to