[PATCH v4 27/46] usb/gadget: f_subset: convert to new function interface with backward compatibility

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <andrzej.p@xxxxxxxxxxx>
Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
 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 <andrzej.p@xxxxxxxxxxx>
+ *
+ * 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux