summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/acm_ms.c13
-rw-r--r--drivers/usb/gadget/audio.c12
-rw-r--r--drivers/usb/gadget/cdc2.c16
-rw-r--r--drivers/usb/gadget/composite.c2
-rw-r--r--drivers/usb/gadget/ether.c17
-rw-r--r--drivers/usb/gadget/f_mass_storage.c15
-rw-r--r--drivers/usb/gadget/file_storage.c14
-rw-r--r--drivers/usb/gadget/gadget_chips.c94
-rw-r--r--drivers/usb/gadget/gadget_chips.h23
-rw-r--r--drivers/usb/gadget/gmidi.c16
-rw-r--r--drivers/usb/gadget/hid.c8
-rw-r--r--drivers/usb/gadget/multi.c11
-rw-r--r--drivers/usb/gadget/ncm.c17
-rw-r--r--drivers/usb/gadget/nokia.c14
-rw-r--r--drivers/usb/gadget/printer.c11
-rw-r--r--drivers/usb/gadget/serial.c22
-rw-r--r--drivers/usb/gadget/zero.c17
-rw-r--r--include/linux/usb/composite.h11
19 files changed, 24 insertions, 311 deletions
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 5c4a1330b498..307be5fa824c 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
 obj-$(CONFIG_USB_GADGET)	+= udc-core.o
 obj-$(CONFIG_USB_LIBCOMPOSITE)	+= libcomposite.o
 libcomposite-y			:= usbstring.o config.o epautoconf.o
-libcomposite-y			+= gadget_chips.o composite.o
+libcomposite-y			+= composite.o
 obj-$(CONFIG_USB_DUMMY_HCD)	+= dummy_hcd.o
 obj-$(CONFIG_USB_NET2272)	+= net2272.o
 obj-$(CONFIG_USB_NET2280)	+= net2280.o
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
index b0abc2518b38..5a7f289805ff 100644
--- a/drivers/usb/gadget/acm_ms.c
+++ b/drivers/usb/gadget/acm_ms.c
@@ -148,7 +148,6 @@ static struct usb_configuration acm_ms_config_driver = {
 
 static int __init acm_ms_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 	void			*retp;
@@ -165,18 +164,6 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
 		goto fail0;
 	}
 
-	/* set bcdDevice */
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0) {
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	} else {
-		WARNING(cdev, "controller '%s' not recognized; trying %s\n",
-				gadget->name,
-				acm_ms_config_driver.label);
-		device_desc.bcdDevice =
-			cpu_to_le16(0x0300 | 0x0099);
-	}
-
 	/*
 	 * Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index 1b9dee91d686..231b0efe8fdc 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -135,20 +135,8 @@ static struct usb_configuration audio_config_driver = {
 
 static int __init audio_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
 	int			status;
 
-	gcnum = usb_gadget_controller_number(cdev->gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	else {
-		ERROR(cdev, "controller '%s' not recognized; trying %s\n",
-			cdev->gadget->name,
-			audio_config_driver.label);
-		device_desc.bcdDevice =
-			__constant_cpu_to_le16(0x0300 | 0x0099);
-	}
-
 	status = usb_string_ids_tab(cdev, strings_dev);
 	if (status < 0)
 		goto fail;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index ba38d2a43723..1e4bb77f00bb 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -143,7 +143,6 @@ static struct usb_configuration cdc_config_driver = {
 
 static int __init cdc_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 
@@ -163,21 +162,6 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
 	if (status < 0)
 		goto fail0;
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	else {
-		/* We assume that can_support_ecm() tells the truth;
-		 * but if the controller isn't recognized at all then
-		 * that assumption is a bit more likely to be wrong.
-		 */
-		WARNING(cdev, "controller '%s' not recognized; trying %s\n",
-				gadget->name,
-				cdc_config_driver.label);
-		device_desc.bcdDevice =
-			cpu_to_le16(0x0300 | 0x0099);
-	}
-
 	/* Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
 	 */
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index cacb273ba708..957f973dd96a 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1389,6 +1389,8 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new,
 		new->idProduct = idProduct;
 	if (bcdDevice)
 		new->bcdDevice = bcdDevice;
+	else
+		new->bcdDevice = cpu_to_le16(get_default_bcdDevice());
 	if (iSerialNumber)
 		new->iSerialNumber = iSerialNumber;
 	if (iManufacturer)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index d7ec87e0bfcb..18c3f423706e 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -275,7 +275,6 @@ static struct usb_configuration eth_config_driver = {
 
 static int __init eth_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 
@@ -310,22 +309,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
 		device_desc.bNumConfigurations = 2;
 	}
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	else {
-		/* We assume that can_support_ecm() tells the truth;
-		 * but if the controller isn't recognized at all then
-		 * that assumption is a bit more likely to be wrong.
-		 */
-		dev_warn(&gadget->dev,
-				"controller '%s' not recognized; trying %s\n",
-				gadget->name,
-				eth_config_driver.label);
-		device_desc.bcdDevice =
-			cpu_to_le16(0x0300 | 0x0099);
-	}
-
 	/* Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
 	 */
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 11150960d88b..3a7668bde3ef 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -348,7 +348,6 @@ struct fsg_config {
 
 	const char *vendor_name;		/*  8 characters or less */
 	const char *product_name;		/* 16 characters or less */
-	u16 release;
 
 	char			can_stall;
 };
@@ -2772,18 +2771,7 @@ buffhds_first_it:
 	bh->next = common->buffhds;
 
 	/* Prepare inquiryString */
-	if (cfg->release != 0xffff) {
-		i = cfg->release;
-	} else {
-		i = usb_gadget_controller_number(gadget);
-		if (i >= 0) {
-			i = 0x0300 + i;
-		} else {
-			WARNING(common, "controller '%s' not recognized\n",
-				gadget->name);
-			i = 0x0399;
-		}
-	}
+	i = get_default_bcdDevice();
 	snprintf(common->inquiry_string, sizeof common->inquiry_string,
 		 "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
 		 /* Assume product name dependent on the first LUN */
@@ -3109,7 +3097,6 @@ fsg_config_from_params(struct fsg_config *cfg,
 	/* Let MSF use defaults */
 	cfg->vendor_name = 0;
 	cfg->product_name = 0;
-	cfg->release = 0xffff;
 
 	cfg->ops = NULL;
 	cfg->private_data = NULL;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ce362f7e39d3..3f7d640b6758 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -251,6 +251,7 @@
 #include <linux/freezer.h>
 #include <linux/utsname.h>
 
+#include <linux/usb/composite.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
@@ -3198,7 +3199,6 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
 static int __init check_parameters(struct fsg_dev *fsg)
 {
 	int	prot;
-	int	gcnum;
 
 	/* Store the default values */
 	mod_data.transport_type = USB_PR_BULK;
@@ -3213,16 +3213,8 @@ static int __init check_parameters(struct fsg_dev *fsg)
 	if (gadget_is_at91(fsg->gadget))
 		mod_data.can_stall = 0;
 
-	if (mod_data.release == 0xffff) {	// Parameter wasn't set
-		gcnum = usb_gadget_controller_number(fsg->gadget);
-		if (gcnum >= 0)
-			mod_data.release = 0x0300 + gcnum;
-		else {
-			WARNING(fsg, "controller '%s' not recognized\n",
-				fsg->gadget->name);
-			mod_data.release = 0x0399;
-		}
-	}
+	if (mod_data.release == 0xffff)
+		mod_data.release = get_default_bcdDevice();
 
 	prot = simple_strtol(mod_data.protocol_parm, NULL, 0);
 
diff --git a/drivers/usb/gadget/gadget_chips.c b/drivers/usb/gadget/gadget_chips.c
deleted file mode 100644
index 6387d43d3f8c..000000000000
--- a/drivers/usb/gadget/gadget_chips.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * USB device controllers have lots of quirks.  Use these macros in
- * gadget drivers or other code that needs to deal with them, and which
- * autoconfigures instead of using early binding to the hardware.
- *
- * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by
- * some config file that gets updated as new hardware is supported.
- * (And avoiding all runtime comparisons in typical one-choice configs!)
- *
- * NOTE:  some of these controller drivers may not be available yet.
- * Some are available on 2.4 kernels; several are available, but not
- * yet pushed in the 2.6 mainline tree.
- */
-
-#include <linux/usb/gadget.h>
-#include <linux/module.h>
-
-#include "gadget_chips.h"
-
-/**
- * usb_gadget_controller_number - support bcdDevice id convention
- * @gadget: the controller being driven
- *
- * Return a 2-digit BCD value associated with the peripheral controller,
- * suitable for use as part of a bcdDevice value, or a negative error code.
- *
- * NOTE:  this convention is purely optional, and has no meaning in terms of
- * any USB specification.  If you want to use a different convention in your
- * gadget driver firmware -- maybe a more formal revision ID -- feel free.
- *
- * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
- * to change their behavior accordingly.  For example it might help avoiding
- * some chip bug.
- */
-int usb_gadget_controller_number(struct usb_gadget *gadget)
-{
-	if (gadget_is_net2280(gadget))
-		return 0x01;
-	else if (gadget_is_dummy(gadget))
-		return 0x02;
-	else if (gadget_is_pxa(gadget))
-		return 0x03;
-	else if (gadget_is_goku(gadget))
-		return 0x06;
-	else if (gadget_is_omap(gadget))
-		return 0x08;
-	else if (gadget_is_pxa27x(gadget))
-		return 0x11;
-	else if (gadget_is_s3c2410(gadget))
-		return 0x12;
-	else if (gadget_is_at91(gadget))
-		return 0x13;
-	else if (gadget_is_imx(gadget))
-		return 0x14;
-	else if (gadget_is_musbhdrc(gadget))
-		return 0x16;
-	else if (gadget_is_atmel_usba(gadget))
-		return 0x18;
-	else if (gadget_is_fsl_usb2(gadget))
-		return 0x19;
-	else if (gadget_is_amd5536udc(gadget))
-		return 0x20;
-	else if (gadget_is_m66592(gadget))
-		return 0x21;
-	else if (gadget_is_fsl_qe(gadget))
-		return 0x22;
-	else if (gadget_is_ci13xxx_pci(gadget))
-		return 0x23;
-	else if (gadget_is_langwell(gadget))
-		return 0x24;
-	else if (gadget_is_r8a66597(gadget))
-		return 0x25;
-	else if (gadget_is_s3c_hsotg(gadget))
-		return 0x26;
-	else if (gadget_is_pch(gadget))
-		return 0x27;
-	else if (gadget_is_ci13xxx_msm(gadget))
-		return 0x28;
-	else if (gadget_is_renesas_usbhs(gadget))
-		return 0x29;
-	else if (gadget_is_s3c_hsudc(gadget))
-		return 0x30;
-	else if (gadget_is_net2272(gadget))
-		return 0x31;
-	else if (gadget_is_dwc3(gadget))
-		return 0x32;
-	else if (gadget_is_lpc32xx(gadget))
-		return 0x33;
-	else if (gadget_is_bcm63xx(gadget))
-		return 0x34;
-
-	return -ENOENT;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_controller_number);
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index c7055cd1e92e..bcd04bc66b98 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -27,35 +27,12 @@
  * If you have forgotten the alphabetical order let VIM/EMACS
  * do that for you.
  */
-#define gadget_is_amd5536udc(g)		(!strcmp("amd5536udc", (g)->name))
 #define gadget_is_at91(g)		(!strcmp("at91_udc", (g)->name))
-#define gadget_is_atmel_usba(g)		(!strcmp("atmel_usba_udc", (g)->name))
-#define gadget_is_bcm63xx(g)		(!strcmp("bcm63xx_udc", (g)->name))
-#define gadget_is_ci13xxx_msm(g)	(!strcmp("ci13xxx_msm", (g)->name))
-#define gadget_is_ci13xxx_pci(g)	(!strcmp("ci13xxx_pci", (g)->name))
-#define gadget_is_dummy(g)		(!strcmp("dummy_udc", (g)->name))
-#define gadget_is_dwc3(g)		(!strcmp("dwc3-gadget", (g)->name))
-#define gadget_is_fsl_qe(g)		(!strcmp("fsl_qe_udc", (g)->name))
-#define gadget_is_fsl_usb2(g)		(!strcmp("fsl-usb2-udc", (g)->name))
 #define gadget_is_goku(g)		(!strcmp("goku_udc", (g)->name))
-#define gadget_is_imx(g)		(!strcmp("imx_udc", (g)->name))
-#define gadget_is_langwell(g)		(!strcmp("langwell_udc", (g)->name))
-#define gadget_is_lpc32xx(g)		(!strcmp("lpc32xx_udc", (g)->name))
-#define gadget_is_m66592(g)		(!strcmp("m66592_udc", (g)->name))
 #define gadget_is_musbhdrc(g)		(!strcmp("musb-hdrc", (g)->name))
-#define gadget_is_net2272(g)		(!strcmp("net2272", (g)->name))
 #define gadget_is_net2280(g)		(!strcmp("net2280", (g)->name))
-#define gadget_is_omap(g)		(!strcmp("omap_udc", (g)->name))
-#define gadget_is_pch(g)		(!strcmp("pch_udc", (g)->name))
 #define gadget_is_pxa(g)		(!strcmp("pxa25x_udc", (g)->name))
 #define gadget_is_pxa27x(g)		(!strcmp("pxa27x_udc", (g)->name))
-#define gadget_is_r8a66597(g)		(!strcmp("r8a66597_udc", (g)->name))
-#define gadget_is_renesas_usbhs(g)	(!strcmp("renesas_usbhs_udc", (g)->name))
-#define gadget_is_s3c2410(g)		(!strcmp("s3c2410_udc", (g)->name))
-#define gadget_is_s3c_hsotg(g)		(!strcmp("s3c-hsotg", (g)->name))
-#define gadget_is_s3c_hsudc(g)		(!strcmp("s3c-hsudc", (g)->name))
-
-int usb_gadget_controller_number(struct usb_gadget *gadget);
 
 /**
  * gadget_supports_altsettings - return true if altsettings work
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 4181524d1c4b..881aab86ae99 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -137,8 +137,7 @@ static int __init midi_bind_config(struct usb_configuration *c)
 
 static int __init midi_bind(struct usb_composite_dev *cdev)
 {
-	struct usb_gadget *gadget = cdev->gadget;
-	int gcnum, status;
+	int status;
 
 	status = usb_string_ids_tab(cdev, strings_dev);
 	if (status < 0)
@@ -147,19 +146,6 @@ static int __init midi_bind(struct usb_composite_dev *cdev)
 	device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
 	midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id;
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum < 0) {
-		/* gmidi is so simple (no altsettings) that
-		 * it SHOULD NOT have problems with bulk-capable hardware.
-		 * so warn about unrecognized controllers, don't panic.
-		 */
-		pr_warning("%s: controller '%s' not recognized\n",
-			   __func__, gadget->name);
-		device_desc.bcdDevice = cpu_to_le16(0x9999);
-	} else {
-		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
-	}
-
 	status = usb_add_config(cdev, &midi_config, midi_bind_config);
 	if (status < 0)
 		return status;
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 5fa1bfa8c6c6..74130f6c12c0 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -143,7 +143,7 @@ static int __init hid_bind(struct usb_composite_dev *cdev)
 {
 	struct usb_gadget *gadget = cdev->gadget;
 	struct list_head *tmp;
-	int status, gcnum, funcs = 0;
+	int status, funcs = 0;
 
 	list_for_each(tmp, &hidg_func_list)
 		funcs++;
@@ -156,12 +156,6 @@ static int __init hid_bind(struct usb_composite_dev *cdev)
 	if (status < 0)
 		return status;
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	else
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
-
 	/* Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
 	 */
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 9d2e75c017dc..88472bf7dbb7 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -247,7 +247,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
 static int __ref multi_bind(struct usb_composite_dev *cdev)
 {
 	struct usb_gadget *gadget = cdev->gadget;
-	int status, gcnum;
+	int status;
 
 	if (!can_support_ecm(cdev->gadget)) {
 		dev_err(&gadget->dev, "controller '%s' not usable\n",
@@ -275,15 +275,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
 		}
 	}
 
-	/* set bcdDevice */
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0) {
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	} else {
-		WARNING(cdev, "controller '%s' not recognized\n", gadget->name);
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
-	}
-
 	/* allocate string IDs */
 	status = usb_string_ids_tab(cdev, strings_dev);
 	if (unlikely(status < 0))
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
index b21ec269b8f5..a22ad9af0565 100644
--- a/drivers/usb/gadget/ncm.c
+++ b/drivers/usb/gadget/ncm.c
@@ -139,7 +139,6 @@ static struct usb_configuration ncm_config_driver = {
 
 static int __init gncm_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 
@@ -148,22 +147,6 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
 	if (status < 0)
 		return status;
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
-	else {
-		/* We assume that can_support_ecm() tells the truth;
-		 * but if the controller isn't recognized at all then
-		 * that assumption is a bit more likely to be wrong.
-		 */
-		dev_warn(&gadget->dev,
-			 "controller '%s' not recognized; trying %s\n",
-			 gadget->name,
-			 ncm_config_driver.label);
-		device_desc.bcdDevice =
-			cpu_to_le16(0x0300 | 0x0099);
-	}
-
 	/* Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
 	 */
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index ad0cc3473073..661600abace8 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -84,6 +84,7 @@ static struct usb_device_descriptor device_desc = {
 	.bDeviceClass		= USB_CLASS_COMM,
 	.idVendor		= __constant_cpu_to_le16(NOKIA_VENDOR_ID),
 	.idProduct		= __constant_cpu_to_le16(NOKIA_PRODUCT_ID),
+	.bcdDevice		= cpu_to_le16(NOKIA_VERSION_NUM),
 	/* .iManufacturer = DYNAMIC */
 	/* .iProduct = DYNAMIC */
 	.bNumConfigurations =	1,
@@ -145,7 +146,6 @@ static struct usb_configuration nokia_config_100ma_driver = {
 
 static int __init nokia_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 
@@ -170,18 +170,8 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
 	nokia_config_500ma_driver.iConfiguration = status;
 	nokia_config_100ma_driver.iConfiguration = status;
 
-	/* set up other descriptors */
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
-	else {
-		/* this should only work with hw that supports altsettings
-		 * and several endpoints, anything else, panic.
-		 */
-		pr_err("nokia_bind: controller '%s' not recognized\n",
-			gadget->name);
+	if (!gadget_supports_altsettings(gadget))
 		goto err_usb;
-	}
 
 	/* finally register the configuration */
 	status = usb_add_config(cdev, &nokia_config_500ma_driver,
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index e394050afd02..e156e3f26727 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -1101,7 +1101,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
 	struct usb_gadget	*gadget = c->cdev->gadget;
 	struct printer_dev	*dev;
 	int			status = -ENOMEM;
-	int			gcnum;
 	size_t			len;
 	u32			i;
 	struct usb_request	*req;
@@ -1143,16 +1142,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
 		goto fail;
 	}
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0) {
-		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
-	} else {
-		dev_warn(&gadget->dev, "controller '%s' not recognized\n",
-			gadget->name);
-		/* unrecognized, but safe unless bulk is REALLY quirky */
-		device_desc.bcdDevice =
-			cpu_to_le16(0xFFFF);
-	}
 	if (iPNPstring)
 		strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2);
 
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index f17d4626af55..942067327d88 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -86,7 +86,7 @@ static struct usb_device_descriptor device_desc = {
 	/* .bMaxPacketSize0 = f(hardware) */
 	.idVendor =		cpu_to_le16(GS_VENDOR_ID),
 	/* .idProduct =	f(use_acm) */
-	/* .bcdDevice = f(hardware) */
+	.bcdDevice = cpu_to_le16(GS_VERSION_NUM << 16),
 	/* .iManufacturer = DYNAMIC */
 	/* .iProduct = DYNAMIC */
 	.bNumConfigurations =	1,
@@ -154,8 +154,6 @@ static struct usb_configuration serial_config_driver = {
 
 static int __init gs_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
-	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 
 	status = gserial_setup(cdev->gadget, n_ports);
@@ -174,24 +172,6 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
 	status = strings_dev[STRING_DESCRIPTION_IDX].id;
 	serial_config_driver.iConfiguration = status;
 
-	/* set up other descriptors */
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum);
-	else {
-		/* this is so simple (for now, no altsettings) that it
-		 * SHOULD NOT have problems with bulk-capable hardware.
-		 * so warn about unrcognized controllers -- don't panic.
-		 *
-		 * things like configuration and altsetting numbering
-		 * can need hardware-specific attention though.
-		 */
-		pr_warning("gs_bind: controller '%s' not recognized\n",
-			gadget->name);
-		device_desc.bcdDevice =
-			cpu_to_le16(GS_VERSION_NUM | 0x0099);
-	}
-
 	if (gadget_is_otg(cdev->gadget)) {
 		serial_config_driver.descriptors = otg_desc;
 		serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 0dabffa5f493..6bf4c0611365 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -253,8 +253,6 @@ static void zero_resume(struct usb_composite_dev *cdev)
 
 static int __init zero_bind(struct usb_composite_dev *cdev)
 {
-	int			gcnum;
-	struct usb_gadget	*gadget = cdev->gadget;
 	int			status;
 
 	/* Allocate string descriptor numbers ... note that string
@@ -281,21 +279,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
 		loopback_add(cdev, autoresume != 0);
 	}
 
-	gcnum = usb_gadget_controller_number(gadget);
-	if (gcnum >= 0)
-		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
-	else {
-		/* gadget zero is so simple (for now, no altsettings) that
-		 * it SHOULD NOT have problems with bulk-capable hardware.
-		 * so just warn about unrcognized controllers -- don't panic.
-		 *
-		 * things like configuration and altsetting numbering
-		 * can need hardware-specific attention though.
-		 */
-		pr_warning("%s: controller '%s' not recognized\n",
-			longname, gadget->name);
-		device_desc.bcdDevice = cpu_to_le16(0x9999);
-	}
 	usb_composite_overwrite_options(cdev, &coverwrite);
 
 	INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 65ae0a3feb5b..f8dda0621800 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -34,6 +34,8 @@
  * the composite model the host can use both functions at the same time.
  */
 
+#include <linux/bcd.h>
+#include <linux/version.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
@@ -418,6 +420,15 @@ struct usb_composite_overwrite {
 void usb_composite_overwrite_options(struct usb_composite_dev *cdev,
 		struct usb_composite_overwrite *covr);
 
+static inline u16 get_default_bcdDevice(void)
+{
+	u16 bcdDevice;
+
+	bcdDevice = bin2bcd((LINUX_VERSION_CODE >> 16 & 0xff)) << 8;
+	bcdDevice |= bin2bcd((LINUX_VERSION_CODE >> 8 & 0xff));
+	return bcdDevice;
+}
+
 /* messaging utils */
 #define DBG(d, fmt, args...) \
 	dev_dbg(&(d)->gadget->dev , fmt , ## args)