Converting ecm subset to the new function interface requires converting
the USB subset's function code and its users.
This patch converts the f_subset.c to the new function interface.
The file is now compiled into a separate usb_f_subset.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/ether.c    |    1 +
 drivers/usb/gadget/f_subset.c |  110 +++++++++++++++++++++++++++++++++++------
 drivers/usb/gadget/g_ffs.c    |    1 +
 drivers/usb/gadget/u_gether.h |   27 ++++++++++
 6 files changed, 129 insertions(+), 15 deletions(-)
 create mode 100644 drivers/usb/gadget/u_gether.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 039de79..8e950e2 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -575,6 +575,9 @@ config USB_F_EEM
 config USB_F_ECM
        tristate
 
+config USB_F_SUBSET
+       tristate
+
 choice
        tristate "USB Gadget Drivers"
        default USB_ETH
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index dfaccf4..fc323c7 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -93,3 +93,5 @@ usb_f_eem-y                   := f_eem.o
 obj-$(CONFIG_USB_F_EEM)                += usb_f_eem.o
 usb_f_ecm-y                    := f_ecm.o
 obj-$(CONFIG_USB_F_ECM)                += usb_f_ecm.o
+usb_f_ecm_subset-y             := f_subset.o
+obj-$(CONFIG_USB_F_ECM)                += usb_f_ecm_subset.o
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 52106e5..f02c91b 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -104,6 +104,7 @@ static inline bool has_rndis(void)
  * 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_FSUBSET_INCLUDED
 #include "f_subset.c"
 #ifdef USB_ETH_RNDIS
 #include "f_rndis.c"
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 185d6f5..f7b01c4 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -12,11 +12,12 @@
 
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
 
 #include "u_ether.h"
-
+#include "u_gether.h"
 
 /*
  * This function packages a simple "CDC Subset" Ethernet port with no real
@@ -298,6 +299,22 @@ geth_bind(struct usb_configuration *c, struct usb_function 
*f)
        int                     status;
        struct usb_ep           *ep;
 
+#ifndef USB_FSUBSET_INCLUDED
+       struct f_gether_opts    *gether_opts;
+
+       gether_opts = container_of(f->fi, struct f_gether_opts, func_inst);
+       if (!gether_opts->ethaddr)
+               return -EINVAL;
+#endif
+       /* maybe allocate device-global string IDs */
+       if (geth_string_defs[0].id == 0) {
+               status = usb_string_ids_tab(c->cdev, geth_string_defs);
+               if (status < 0)
+                       return status;
+               subset_data_intf.iInterface = geth_string_defs[0].id;
+               ether_desc.iMACAddress = geth_string_defs[1].id;
+       }
+
        /* allocate instance-specific interface IDs */
        status = usb_interface_id(c, f);
        if (status < 0)
@@ -360,8 +377,10 @@ fail:
        return status;
 }
 
+#ifdef USB_FSUBSET_INCLUDED
+
 static void
-geth_unbind(struct usb_configuration *c, struct usb_function *f)
+geth_old_unbind(struct usb_configuration *c, struct usb_function *f)
 {
        geth_string_defs[0].id = 0;
        usb_free_all_descriptors(f);
@@ -386,18 +405,6 @@ int geth_bind_config(struct usb_configuration *c, u8 
ethaddr[ETH_ALEN],
        struct f_gether *geth;
        int             status;
 
-       if (!ethaddr)
-               return -EINVAL;
-
-       /* maybe allocate device-global string IDs */
-       if (geth_string_defs[0].id == 0) {
-               status = usb_string_ids_tab(c->cdev, geth_string_defs);
-               if (status < 0)
-                       return status;
-               subset_data_intf.iInterface = geth_string_defs[0].id;
-               ether_desc.iMACAddress = geth_string_defs[1].id;
-       }
-
        /* allocate and initialize one new instance */
        geth = kzalloc(sizeof *geth, GFP_KERNEL);
        if (!geth)
@@ -413,7 +420,7 @@ int geth_bind_config(struct usb_configuration *c, u8 
ethaddr[ETH_ALEN],
        geth->port.func.name = "cdc_subset";
        geth->port.func.strings = geth_strings;
        geth->port.func.bind = geth_bind;
-       geth->port.func.unbind = geth_unbind;
+       geth->port.func.unbind = geth_old_unbind;
        geth->port.func.set_alt = geth_set_alt;
        geth->port.func.disable = geth_disable;
 
@@ -422,3 +429,76 @@ int geth_bind_config(struct usb_configuration *c, u8 
ethaddr[ETH_ALEN],
                kfree(geth);
        return status;
 }
+
+#else
+
+static void geth_free_inst(struct usb_function_instance *f)
+{
+       struct f_gether_opts *opts;
+
+       opts = container_of(f, struct f_gether_opts, func_inst);
+       kfree(opts);
+}
+
+static struct usb_function_instance *geth_alloc_inst(void)
+{
+       struct f_gether_opts *opts;
+
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+
+       opts->func_inst.free_func_inst = geth_free_inst;
+
+       return &opts->func_inst;
+}
+
+static void geth_free(struct usb_function *f)
+{
+       struct f_gether *eth;
+
+       eth = func_to_geth(f);
+       kfree(eth);
+}
+
+static void geth_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       geth_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+}
+
+struct usb_function *geth_alloc(struct usb_function_instance *fi)
+{
+       struct f_gether *geth;
+       struct f_gether_opts *opts;
+
+       /* allocate and initialize one new instance */
+       geth = kzalloc(sizeof(*geth), GFP_KERNEL);
+       if (!geth)
+               return ERR_PTR(-ENOMEM);
+
+       opts = container_of(fi, struct f_gether_opts, func_inst);
+
+       /* export host's Ethernet address in CDC format */
+       snprintf(geth->ethaddr, sizeof(geth->ethaddr), "%pm", opts->ethaddr);
+       geth_string_defs[1].s = geth->ethaddr;
+
+       geth->port.ioport = opts->dev;
+       geth->port.cdc_filter = DEFAULT_FILTER;
+
+       geth->port.func.name = "cdc_subset";
+       geth->port.func.strings = geth_strings;
+       geth->port.func.bind = geth_bind;
+       geth->port.func.unbind = geth_unbind;
+       geth->port.func.set_alt = geth_set_alt;
+       geth->port.func.disable = geth_disable;
+       geth->port.func.free_func = geth_free;
+
+       return &geth->port.func;
+}
+
+DECLARE_USB_FUNCTION_INIT(geth, geth_alloc_inst, geth_alloc);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Brownell");
+
+#endif
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 65a34f3..be6f2dd 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -29,6 +29,7 @@
 #  endif
 
 #  include "u_ecm.h"
+#define USB_FSUBSET_INCLUDED
 #  include "f_subset.c"
 #  ifdef USB_ETH_RNDIS
 #    include "f_rndis.c"
diff --git a/drivers/usb/gadget/u_gether.h b/drivers/usb/gadget/u_gether.h
new file mode 100644
index 0000000..06dd54e
--- /dev/null
+++ b/drivers/usb/gadget/u_gether.h
@@ -0,0 +1,27 @@
+/*
+ * u_gether.h
+ *
+ * Utility definitions for the subset function
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Author: Andrzej Pietrasiewicz <andrze...@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef U_GETHER_H
+#define U_GETHER_H
+
+#include <linux/usb/composite.h>
+
+struct f_gether_opts {
+       struct usb_function_instance    func_inst;
+       u8                              *ethaddr;
+       struct eth_dev                  *dev;
+};
+
+#endif /* U_GETHER_H */
-- 
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