[PATCHv3 08/11] USB: gadget: g_multi: more configurable

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

 



Added Kconfig options for each function used by g_multi so that
one can customize the gadget to a greater extend.

Note that it will be wise to change vendor and product ID when
customising the gadget.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@xxxxxxxxxxx>
Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
 Documentation/usb/gadget_multi.txt |   27 +++---
 drivers/usb/gadget/Kconfig         |   67 +++++++++-----
 drivers/usb/gadget/multi.c         |  166 ++++++++++++++++--------------------
 3 files changed, 130 insertions(+), 130 deletions(-)

diff --git a/Documentation/usb/gadget_multi.txt b/Documentation/usb/gadget_multi.txt
index bd53a9f..65bccd8 100644
--- a/Documentation/usb/gadget_multi.txt
+++ b/Documentation/usb/gadget_multi.txt
@@ -2,20 +2,21 @@
 
 * Overview
 
-The Multifunction Composite Gadget (or g_multi) is a composite gadget
-that makes extensive use of the composite framework to provide
-a... multifunction gadget.
+The Multifunction Composite Gadget (or g_multi) is a customisable
+composite gadget that makes extensive use of the composite framework
+to provide a... multifunction gadget.
 
 In it's standard configuration it provides a single USB configuration
 with RNDIS[1] (that is Ethernet), USB CDC[2] ACM (that is serial) and
 USB Mass Storage functions.
 
-A CDC ECM (Ethernet) function may be turned on via a Kconfig option
-and RNDIS can be turned off.  If they are both enabled the gadget will
-have two configurations -- one with RNDIS and another with CDC ECM[3].
+Each function can be disabled via a Kconfig option.  There's also
+a CDC ECM (Ethernet) function which can be turned on.  If CDC ECM and
+RNDIS are enabled the gadget will have two configurations -- one with
+RNDIS and another with CDC ECM[3].
 
-Please not that if you use non-standard configuration (that is enable
-CDC ECM) you may need to change vendor and/or product ID.
+Please not that if you use non-standard configuration you may need to
+change vendor and/or product ID.
 
 * Host drivers
 
@@ -92,11 +93,11 @@ hesitate submitting it!
 
 **** Customising the gadget
 
-If you intend to hack the g_multi gadget be advised that rearranging
-functions will obviously change interface numbers for each of the
-functionality.  As an effect provided INFs won't work since they have
-interface numbers hard-coded in them (it's not hard to change those
-though).
+If you intend to customise (via Kconfig) or hack the g_multi gadget be
+advised that rearranging functions will obviously change interface
+numbers for each of the functionality.  As an effect provided INFs
+won't work since they have interface numbers hard-coded in them (it's
+not hard to change those though).
 
 This also means, that after experimenting with g_multi and changing
 provided functions one should change gadget's vendor and/or product ID
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index c97f021..8052643 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -861,43 +861,62 @@ config USB_G_NOKIA
 
 config USB_G_MULTI
 	tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
-	depends on BLOCK && NET
-	select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS
+	select USB_G_MULTI_ACM if !USB_G_MULTI_ANYTHING
 	help
-	  The Multifunction Composite Gadget provides Ethernet (RNDIS
-	  and/or CDC Ethernet), mass storage and ACM serial link
-	  interfaces.
-
-	  You will be asked to choose which of the two configurations is
-	  to be available in the gadget.  At least one configuration must
-	  be chosen to make the gadget usable.  Selecting more than one
-	  configuration will prevent Windows from automatically detecting
-	  the gadget as a composite gadget, so an INF file will be needed to
-	  use the gadget.
+	  The Multifunction Composite Gadget provides several different
+	  configurations and functions.  Which interfaces are provided can
+	  be configured at build time.  If you choose this gadget additional
+	  options will appear.
 
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_multi".
 
-config USB_G_MULTI_RNDIS
-	bool "RNDIS + CDC Serial + Storage configuration"
+config USB_G_MULTI_ANYTHING
+	bool
 	depends on USB_G_MULTI
+
+config USB_G_MULTI_RNDIS
+	bool "Include RNDIS function"
+	depends on USB_G_MULTI && NET
+	select USB_G_MULTI_ANYTHING
 	default y
 	help
-	  This option enables a configuration with RNDIS, CDC Serial and
-	  Mass Storage functions available in the Multifunction Composite
-	  Gadget.  This is the configuration dedicated for Windows since RNDIS
-	  is Microsoft's protocol.
+	  This option enables the RNDIS (Ethernet) function.  It is
+	  protocol dedicated for Windows since it's Microsoft's invention.
+
+	  If you select also CDC ECM function gadget will have two
+	  configurations one with RNDIS and another with CDC ECM.
+
+	  If unsure, say "y".
+
+config USB_G_MULTI_ECM
+	bool "Include CDC ECM function"
+	depends on USB_G_MULTI && NET
+	select USB_G_MULTI_ANYTHING
+	help
+	  This option enables the CDC ECM (Ethernet) function.
+
+	  If you select also RNDIS function gadget will have two
+	  configurations one with RNDIS and another with CDC ECM.
 
 	  If unsure, say "y".
 
-config USB_G_MULTI_CDC
-	bool "CDC Ethernet + CDC Serial + Storage configuration"
+config USB_G_MULTI_ACM
+	bool "Include CDC ACM function"
 	depends on USB_G_MULTI
-	default n
+	default y
+	help
+	  This option enables the CDC ACM (serial) function.
+
+	  If unsure, say "y".
+
+config USB_G_MULTI_MSF
+	bool "Include mass storage function"
+	depends on USB_G_MULTI && BLOCK
+	select USB_G_MULTI_ANYTHING
+	default y
 	help
-	  This option enables a configuration with CDC Ethernet (ECM), CDC
-	  Serial and Mass Storage functions available in the Multifunction
-	  Composite Gadget.
+	  This option enables the mass storage (or UMS) function.
 
 	  If unsure, say "y".
 
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index c7a5b58..6f6fd3e 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -57,19 +57,57 @@ MODULE_LICENSE("GPL");
 #include "config.c"
 #include "epautoconf.c"
 
-#include "f_mass_storage.c"
+/* Mass storage */
+#ifdef CONFIG_USB_G_MULTI_MSF
+#  include "f_mass_storage.c"
 
-#include "u_serial.c"
-#include "f_acm.c"
+static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
+FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+
+static struct fsg_common fsg_common;
+#else
+#  define fsg_common_from_params(common, cdev, data) NULL
+#  define fsg_bind_config(cdev, conf, common)        ((int)0)
+#  define fsg_common_put(common)            do { } while (0)
+#endif
 
-#include "f_ecm.c"
-#include "f_subset.c"
-#ifdef USB_ETH_RNDIS
+/* CDC ACM */
+#ifdef CONFIG_USB_G_MULTI_ACM
+#  include "u_serial.c"
+#  include "f_acm.c"
+#else
+#  define gserial_setup(conf, ports)        ((int)0)
+#  define gserial_cleanup()                 do { } while (0)
+#  define acm_bind_config(conf, ports)      ((int)0)
+#endif
+
+/* Ethernet */
+#ifdef CONFIG_USB_G_MULTI_ECM
+#  include "f_ecm.c"
+#  include "f_subset.c"
+#endif
+
+#ifdef CONFIG_USB_G_MULTI_RNDIS
 #  include "f_rndis.c"
 #  include "rndis.c"
 #endif
-#include "u_ether.c"
 
+#if defined CONFIG_USB_G_MULTI_ECM || defined CONFIG_USB_G_MULTI_RNDIS
+#  include "u_ether.c"
+static u8 hostaddr[ETH_ALEN];
+#else
+#  define gether_setup(cdev, hostaddr) ((int)0)
+#  define gether_cleanup()             do { } while (0)
+#endif
+
+#ifndef CONFIG_USB_G_MULTI_ECM
+#  define can_support_ecm(gadget)           true
+#  define ecm_bind_config(conf, ethaddr)    ((int)0)
+#endif
+
+#ifndef CONFIG_USB_G_MULTI_RNDIS
+#  define rndis_bind_config(conf, ethaddr)  ((int)0)
+#endif
 
 
 /***************************** Device Descriptor ****************************/
@@ -78,19 +116,6 @@ MODULE_LICENSE("GPL");
 #define MULTI_PRODUCT_NUM	0xa4ab	/* XXX */
 
 
-enum {
-	__MULTI_NO_CONFIG,
-#ifdef CONFIG_USB_G_MULTI_RNDIS
-	MULTI_RNDIS_CONFIG_NUM,
-#endif
-#ifdef CONFIG_USB_G_MULTI_CDC
-	MULTI_CDC_CONFIG_NUM,
-#endif
-	__MULTI_NUM_CONFIGS_HELPER,
-	MULTI_NUM_CONFIGS = __MULTI_NUM_CONFIGS_HELPER - 1
-};
-
-
 static struct usb_device_descriptor device_desc = {
 	.bLength =		sizeof device_desc,
 	.bDescriptorType =	USB_DT_DEVICE,
@@ -104,7 +129,11 @@ static struct usb_device_descriptor device_desc = {
 	/* Vendor and product id can be overridden by module parameters.  */
 	.idVendor =		cpu_to_le16(MULTI_VENDOR_NUM),
 	.idProduct =		cpu_to_le16(MULTI_PRODUCT_NUM),
-	.bNumConfigurations =	MULTI_NUM_CONFIGS,
+#if defined CONFIG_USB_G_MULTI_RNDIS && defined CONFIG_USB_G_MULTI_ECM
+	.bNumConfigurations =	2,
+#else
+	.bNumConfigurations =	1,
+#endif
 };
 
 
@@ -124,12 +153,6 @@ static const struct usb_descriptor_header *otg_desc[] = {
 enum {
 	MULTI_STRING_MANUFACTURER_IDX,
 	MULTI_STRING_PRODUCT_IDX,
-#ifdef CONFIG_USB_G_MULTI_RNDIS
-	MULTI_STRING_RNDIS_CONFIG_IDX,
-#endif
-#ifdef CONFIG_USB_G_MULTI_CDC
-	MULTI_STRING_CDC_CONFIG_IDX,
-#endif
 };
 
 static char manufacturer[50];
@@ -137,12 +160,6 @@ static char manufacturer[50];
 static struct usb_string strings_dev[] = {
 	[MULTI_STRING_MANUFACTURER_IDX].s = manufacturer,
 	[MULTI_STRING_PRODUCT_IDX].s      = DRIVER_DESC,
-#ifdef CONFIG_USB_G_MULTI_RNDIS
-	[MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS",
-#endif
-#ifdef CONFIG_USB_G_MULTI_CDC
-	[MULTI_STRING_CDC_CONFIG_IDX].s   = "Multifunction with CDC ECM",
-#endif
 	{  } /* end of list */
 };
 
@@ -159,19 +176,8 @@ static struct usb_gadget_strings *dev_strings[] = {
 
 /****************************** Configurations ******************************/
 
-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 u8 hostaddr[ETH_ALEN];
-
-
-/********** RNDIS **********/
-
-#ifdef USB_ETH_RNDIS
-
-static __ref int rndis_do_config(struct usb_configuration *c)
+static __ref int first_do_config(struct usb_configuration *c)
 {
 	int ret;
 
@@ -180,7 +186,11 @@ static __ref int rndis_do_config(struct usb_configuration *c)
 		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	}
 
+#ifdef CONFIG_USB_G_MULTI_RNDIS
 	ret = rndis_bind_config(c, hostaddr);
+#else
+	ret = ecm_bind_config(c, hostaddr);
+#endif
 	if (ret < 0)
 		return ret;
 
@@ -195,35 +205,17 @@ static __ref int rndis_do_config(struct usb_configuration *c)
 	return 0;
 }
 
-static int rndis_config_register(struct usb_composite_dev *cdev)
-{
-	static struct usb_configuration config = {
-		.bind			= rndis_do_config,
-		.bConfigurationValue	= MULTI_RNDIS_CONFIG_NUM,
-		.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
-	};
-
-	config.label          = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].s;
-	config.iConfiguration = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].id;
-
-	return usb_add_config(cdev, &config);
-}
-
-#else
-
-static int rndis_config_register(struct usb_composite_dev *cdev)
-{
-	return 0;
-}
-
-#endif
-
+static struct usb_configuration first_config_driver = {
+	.label			= "First Configuration",
+	.bind			= first_do_config,
+	.bConfigurationValue	= 1,
+	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
+};
 
-/********** CDC ECM **********/
 
-#ifdef CONFIG_USB_G_MULTI_CDC
+#if defined CONFIG_USB_G_MULTI_RNDIS && defined CONFIG_USB_G_MULTI_ECM
 
-static __ref int cdc_do_config(struct usb_configuration *c)
+static __ref int second_do_config(struct usb_configuration *c)
 {
 	int ret;
 
@@ -247,26 +239,12 @@ static __ref int cdc_do_config(struct usb_configuration *c)
 	return 0;
 }
 
-static int cdc_config_register(struct usb_composite_dev *cdev)
-{
-	static struct usb_configuration config = {
-		.bind			= cdc_do_config,
-		.bConfigurationValue	= MULTI_CDC_CONFIG_NUM,
-		.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
-	};
-
-	config.label          = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].s;
-	config.iConfiguration = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].id;
-
-	return usb_add_config(cdev, &config);
-}
-
-#else
-
-static int cdc_config_register(struct usb_composite_dev *cdev)
-{
-	return 0;
-}
+static struct usb_configuration second_config_driver = {
+	.label			= "Second Configuration",
+	.bind			= second_do_config,
+	.bConfigurationValue	= 2,
+	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
+};
 
 #endif
 
@@ -331,13 +309,15 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
 		strings_dev[MULTI_STRING_PRODUCT_IDX].id;
 
 	/* register configurations */
-	status = rndis_config_register(cdev);
+	status = usb_add_config(cdev, &first_config_driver);
 	if (unlikely(status < 0))
 		goto fail2;
 
-	status = cdc_config_register(cdev);
+#if defined CONFIG_USB_G_MULTI_RNDIS && defined CONFIG_USB_G_MULTI_ECM
+	status = usb_add_config(cdev, &second_config_driver);
 	if (unlikely(status < 0))
 		goto fail2;
+#endif
 
 	/* we're done */
 	dev_info(&gadget->dev, DRIVER_DESC "\n");
-- 
1.7.1

--
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