aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-09-01 15:29:57 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-01 15:29:57 -0700
commita673f25b4013b7b6484ef935ce5a63dc5a248a7e (patch)
tree332efe03a21e9549032f20f3defae9211865f843
parent9c19ffe7b6129ad4babb0762c3b342d02679b9ce (diff)
downloadpatches-a673f25b4013b7b6484ef935ce5a63dc5a248a7e.tar.gz
more patches
-rw-r--r--series17
-rw-r--r--tty/serial-core-restore-termios-settings-when-resume-console-ports.patch61
-rw-r--r--tty/serial-core-skip-call-set_termios-console_start-when-no_console_suspend.patch39
-rw-r--r--tty/vt-use-pit_tick_rate-in-vt-beep-ioctl.patch78
-rw-r--r--usb/init.h-add-some-more-documentation-to-__ref-tags.patch53
-rw-r--r--usb/usb-gadget-composite-better-string-override-handling.patch234
-rw-r--r--usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_composite_driver.patch323
-rw-r--r--usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_configuration.patch409
-rw-r--r--usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch1062
-rw-r--r--usb/usb-gadget-functionfs-code-cleanup.patch208
-rw-r--r--usb/usb-gadget-g_ffs-fixed-vendor-and-product-id.patch35
-rw-r--r--usb/usb-gadget-g_multi-fixed-vendor-and-product-id.patch35
-rw-r--r--usb/usb-gadget-g_multi-moved-strings-handling-code-to-composite.patch78
-rw-r--r--usb/usb-gadget-mass_storage-moved-strings-handling-code.patch152
-rw-r--r--usb/usb-gadget-mass_storage-optional-scsi-write-fua-bit.patch104
-rw-r--r--usb/usb-gadget-storage-remove-nofua-file-when-unbinding.patch31
-rw-r--r--usb/usb-revert-usb-gadget-section-mismatch-warning-fixed.patch258
17 files changed, 3097 insertions, 80 deletions
diff --git a/series b/series
index f619bcd43ba292..17a77655851ce2 100644
--- a/series
+++ b/series
@@ -75,7 +75,6 @@ tty/serport-place-serport-serio-device-correctly-in-the-device-tree.patch
tty/serial-mfd-snprintf-returns-largish-values.patch
tty/serial-add-console_poll-support-for-uartlite.patch
tty/tty-remove-__gfp_nofail-from-tty_add_file.patch
-tty/vt-use-pit_tick_rate-in-vt-beep-ioctl.patch
tty/ioctl-use-asm-generic-ioctls-h-on-arm
tty/ioctl-use-asm-generic-ioctls-h-on-avr32
tty/ioctl-use-asm-generic-ioctls-h-on-cris
@@ -86,6 +85,8 @@ tty/ioctl-use-asm-generic-ioctls-h-on-m32r
tty/ioctl-use-asm-generic-ioctls-h-on-m68k
tty/ioctl-use-asm-generic-ioctls-h-on-mn10300
tty/ioctl-use-asm-generic-ioctls-h-on-s390
+tty/serial-core-skip-call-set_termios-console_start-when-no_console_suspend.patch
+tty/serial-core-restore-termios-settings-when-resume-console-ports.patch
###################################
@@ -101,8 +102,20 @@ usb/usb-gadget-dbgp-cleanup-remove-unneeded-check.patch
usb/usb-sam-ba-add-driver-for-atmel-sam-boot-assistant-sam-ba.patch
usb/usb-gadget-verify-vbus-current-before-setting-the-device-self-powered-bit.patch
usb/usb-core-update-comment-to-match-current-function-name.patch
+usb/usb-gadget-g_multi-fixed-vendor-and-product-id.patch
+usb/usb-gadget-g_ffs-fixed-vendor-and-product-id.patch
+usb/usb-gadget-storage-remove-nofua-file-when-unbinding.patch
+usb/usb-gadget-mass_storage-optional-scsi-write-fua-bit.patch
+usb/usb-gadget-functionfs-code-cleanup.patch
+usb/usb-gadget-composite-better-string-override-handling.patch
+usb/usb-gadget-mass_storage-moved-strings-handling-code.patch
+usb/usb-gadget-g_multi-moved-strings-handling-code-to-composite.patch
+usb/usb-revert-usb-gadget-section-mismatch-warning-fixed.patch
+usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch
+usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_composite_driver.patch
+usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_configuration.patch
+usb/init.h-add-some-more-documentation-to-__ref-tags.patch
# staging stuff for next is now in the staging-next tree on git.kernel.org
-
diff --git a/tty/serial-core-restore-termios-settings-when-resume-console-ports.patch b/tty/serial-core-restore-termios-settings-when-resume-console-ports.patch
new file mode 100644
index 00000000000000..97651f1ee022f0
--- /dev/null
+++ b/tty/serial-core-restore-termios-settings-when-resume-console-ports.patch
@@ -0,0 +1,61 @@
+From jason77.wang@gmail.com Wed Sep 1 14:08:21 2010
+From: Jason Wang <jason77.wang@gmail.com>
+To: gregkh@suse.de, alan@linux.intel.com, arnd@arndb.de,
+ sbrabec@suse.cz
+Cc: linux-serial@vger.kernel.org
+Subject: serial-core: restore termios settings when resume console ports
+Date: Sat, 21 Aug 2010 15:14:42 +0800
+Message-Id: <1282374882-6651-3-git-send-email-jason77.wang@gmail.com>
+
+The commit 4547be7 rewrites suspend and resume functions. According
+to this rewrite, when a serial port is a printk console device and
+can suspend(without set no_console_suspend flag), it will definitely
+call set_termios function during its resume, but parameter termios
+isn't initialized, this will pass an unpredictable config to the
+serial port. If this serial port is not a userspace opened tty device
+, a suspend and resume action will make this serial port unusable.
+I.E. ttyS0 is a printk console device, ttyS1 or keyboard+display is
+userspace tty device, a suspend/resume action will make ttyS0
+unusable.
+
+If a serial port is both a printk console device and an opened tty
+device, this issue can be overcome because it will call set_termios
+again with the correct parameter in the uart_change_speed function.
+
+Refer to the deleted content of commit 4547be7, revert parts relate
+to restore settings into parameter termios. It is safe because if
+a serial port is a printk console only device, the only meaningful
+field in termios is c_cflag and its old config is saved in
+uport->cons->cflag, if this port is also an opened tty device,
+it will clear uport->cons->cflag in the uart_open and the old config
+is saved in tty->termios.
+
+Signed-off-by: Jason Wang <jason77.wang@gmail.com>
+Acked-by: Stanislav Brabec <sbrabec@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/serial/serial_core.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/serial/serial_core.c
++++ b/drivers/serial/serial_core.c
+@@ -2066,6 +2066,18 @@ int uart_resume_port(struct uart_driver
+ * Re-enable the console device after suspending.
+ */
+ if (console_suspend_enabled && uart_console(uport)) {
++ /*
++ * First try to use the console cflag setting.
++ */
++ memset(&termios, 0, sizeof(struct ktermios));
++ termios.c_cflag = uport->cons->cflag;
++
++ /*
++ * If that's unset, use the tty termios setting.
++ */
++ if (port->tty && port->tty->termios && termios.c_cflag == 0)
++ termios = *(port->tty->termios);
++
+ uart_change_pm(state, 0);
+ uport->ops->set_termios(uport, &termios, NULL);
+ console_start(uport->cons);
diff --git a/tty/serial-core-skip-call-set_termios-console_start-when-no_console_suspend.patch b/tty/serial-core-skip-call-set_termios-console_start-when-no_console_suspend.patch
new file mode 100644
index 00000000000000..ea045ea027cb33
--- /dev/null
+++ b/tty/serial-core-skip-call-set_termios-console_start-when-no_console_suspend.patch
@@ -0,0 +1,39 @@
+From jason77.wang@gmail.com Wed Sep 1 14:08:06 2010
+From: Jason Wang <jason77.wang@gmail.com>
+To: gregkh@suse.de, alan@linux.intel.com, arnd@arndb.de,
+ sbrabec@suse.cz
+Cc: linux-serial@vger.kernel.org
+Subject: serial-core: skip call set_termios/console_start when no_console_suspend
+Date: Sat, 21 Aug 2010 15:14:41 +0800
+Message-Id: <1282374882-6651-2-git-send-email-jason77.wang@gmail.com>
+
+The commit 4547be7 rewrites suspend and resume functions, this
+introduces a problem on the OMAP3EVM platoform. when the kernel boots
+with no_console_suspend and we suspend the kernel, then resume it,
+the serial console will be not usable. This problem should be common
+for all platforms.
+The cause for this problem is that when enter suspend, if we choose
+no_console_suspend, the console_stop will be skiped. But in resume
+function, the console port will be set to uninitialized state by
+calling set_termios function and the console_start is called without
+checking whether the no_console_suspend is set, Now fix it.
+
+Signed-off-by: Jason Wang <jason77.wang@gmail.com>
+Acked-by: Stanislav Brabec <sbrabec@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/serial/serial_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/serial/serial_core.c
++++ b/drivers/serial/serial_core.c
+@@ -2065,7 +2065,7 @@ int uart_resume_port(struct uart_driver
+ /*
+ * Re-enable the console device after suspending.
+ */
+- if (uart_console(uport)) {
++ if (console_suspend_enabled && uart_console(uport)) {
+ uart_change_pm(state, 0);
+ uport->ops->set_termios(uport, &termios, NULL);
+ console_start(uport->cons);
diff --git a/tty/vt-use-pit_tick_rate-in-vt-beep-ioctl.patch b/tty/vt-use-pit_tick_rate-in-vt-beep-ioctl.patch
deleted file mode 100644
index 3aa34c8da9fd86..00000000000000
--- a/tty/vt-use-pit_tick_rate-in-vt-beep-ioctl.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From arnd@arndb.de Wed Sep 1 13:04:58 2010
-From: Arnd Bergmann <arnd@arndb.de>
-To: linux-kernel@vger.kernel.org,
- Greg KH <greg@kroah.com>,
- linux-input@vger.kernel.org,
- Alan Cox <alan@lxorguk.ukuu.org.uk>,
- Dmitry Torokhov <dmitry.torokhov@gmail.com>
-Subject: vt: use PIT_TICK_RATE in vt beep ioctl
-Date: Tue, 24 Aug 2010 15:53:11 +0200
-Cc: linux-arm-kernel@lists.infradead.org,
- David Yang <david.yangshuai@gmail.com>,
- Eric Miao <eric.y.miao@gmail.com>,
- Emmanuel Colbus <emmanuel.colbus@ensimag.imag.fr>,
- Andrew Morton <akpm@osdl.org>
-Message-Id: <201008241553.11219.arnd@arndb.de>
-
-The KIOCSOUND and KDMKTONE ioctls are based on the
-CLOCK_TICK_RATE, which is architecture and sometimes
-configuration specific.
-
-In practice, most user applications assume that it
-is actually defined as the i8253 PIT base clock of
-1193182 Hz, which is true on some architectures
-but not on others.
-
-This patch makes the vt code use the PIT frequency
-on all architectures, which is much more well-defined.
-It will change the behavior of user applications
-sending the beep ioctl on all architectures that
-define CLOCK_TICK_RATE different from PIT_TICK_RATE.
-
-The original breakage was introduced in commit bcc8ca099
-"Adapt drivers/char/vt_ioctl.c to non-x86".
-Hopefully, reverting this change will make the frequency
-correct in more cases than it will make it incorrect.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/char/vt_ioctl.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/drivers/char/vt_ioctl.c
-+++ b/drivers/char/vt_ioctl.c
-@@ -533,11 +533,14 @@ int vt_ioctl(struct tty_struct *tty, str
- case KIOCSOUND:
- if (!perm)
- goto eperm;
-- /* FIXME: This is an old broken API but we need to keep it
-- supported and somehow separate the historic advertised
-- tick rate from any real one */
-+ /*
-+ * The use of PIT_TICK_RATE is historic, it used to be
-+ * the platform-dependent CLOCK_TICK_RATE between 2.6.12
-+ * and 2.6.36, which was a minor but unfortunate ABI
-+ * change.
-+ */
- if (arg)
-- arg = CLOCK_TICK_RATE / arg;
-+ arg = PIT_TICK_RATE / arg;
- kd_mksound(arg, 0);
- break;
-
-@@ -553,11 +556,8 @@ int vt_ioctl(struct tty_struct *tty, str
- */
- ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
- count = ticks ? (arg & 0xffff) : 0;
-- /* FIXME: This is an old broken API but we need to keep it
-- supported and somehow separate the historic advertised
-- tick rate from any real one */
- if (count)
-- count = CLOCK_TICK_RATE / count;
-+ count = PIT_TICK_RATE / count;
- kd_mksound(count, ticks);
- break;
- }
diff --git a/usb/init.h-add-some-more-documentation-to-__ref-tags.patch b/usb/init.h-add-some-more-documentation-to-__ref-tags.patch
new file mode 100644
index 00000000000000..131c9eb5d7a400
--- /dev/null
+++ b/usb/init.h-add-some-more-documentation-to-__ref-tags.patch
@@ -0,0 +1,53 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:16:36 2010
+Date: Thu, 12 Aug 2010 17:43:56 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: init.h: add some more documentation to __ref* tags
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org,
+ =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>,
+ Sam Ravnborg <sam@ravnborg.org>
+Message-id: <596c51e49e129c14531a6367ea7b321ee541bdb5.1281625724.git.m.nazarewicz@samsung.com>
+
+The __ref* tags may have been confusing for new kernel
+developers (I was confused by them for sure) so adding a few
+more sentences to comment to clear things up for people who
+see those for the first time.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/init.h | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/include/linux/init.h
++++ b/include/linux/init.h
+@@ -46,16 +46,23 @@
+ #define __exitdata __section(.exit.data)
+ #define __exit_call __used __section(.exitcall.exit)
+
+-/* modpost check for section mismatches during the kernel build.
++/*
++ * modpost check for section mismatches during the kernel build.
+ * A section mismatch happens when there are references from a
+ * code or data section to an init section (both code or data).
+ * The init sections are (for most archs) discarded by the kernel
+ * when early init has completed so all such references are potential bugs.
+ * For exit sections the same issue exists.
++ *
+ * The following markers are used for the cases where the reference to
+ * the *init / *exit section (code or data) is valid and will teach
+- * modpost not to issue a warning.
+- * The markers follow same syntax rules as __init / __initdata. */
++ * modpost not to issue a warning. Intended semantics is that a code or
++ * data tagged __ref* can reference code or data from init section without
++ * producing a warning (of course, no warning does not mean code is
++ * correct, so optimally document why the __ref is needed and why it's OK).
++ *
++ * The markers follow same syntax rules as __init / __initdata.
++ */
+ #define __ref __section(.ref.text) noinline
+ #define __refdata __section(.ref.data)
+ #define __refconst __section(.ref.rodata)
diff --git a/usb/usb-gadget-composite-better-string-override-handling.patch b/usb/usb-gadget-composite-better-string-override-handling.patch
new file mode 100644
index 00000000000000..34788c65066e0d
--- /dev/null
+++ b/usb/usb-gadget-composite-better-string-override-handling.patch
@@ -0,0 +1,234 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 14:09:23 2010
+Date: Thu, 12 Aug 2010 17:43:46 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: gadget: composite: Better string override handling
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <48e2d6507f004252a012cf25bc0a06e5cb69808f.1281625724.git.m.nazarewicz@samsung.com>
+
+The iManufatcurer, iProduct and iSerialNumber composite module
+parameters were only used when the gadget driver registers
+strings for manufacturer, product and serial number. If the
+gadget never bothered to set corresponding fields in USB device
+descriptors those module parameters are ignored.
+
+This commit makes the parameters work even if the strings ID
+have not been assigned. It also changes the way IDs are
+overridden -- what IDs are overridden is now saved in
+usb_composite_dev structure -- which makes it unnecessary to
+modify the string tables the way previous code did.
+
+The commit also adds a iProduct and iManufatcurer fields to the
+usb_composite_device structure. If they are set, appropriate
+strings are reserved and added to device descriptor. This makes
+it unnecessary for gadget drivers to maintain code for setting
+those. If iProduct is not set it defaults to
+usb_composite_device::name; if iManufatcurer is not set
+a default "<system> <release> with <gadget-name>" is used.
+
+The last thing is that if needs_serial field of
+usb_composite_device is set and user failed to provided
+iSerialNumber parameter a warning is issued.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/composite.c | 96 +++++++++++++++++++++++++++--------------
+ include/linux/usb/composite.h | 13 +++++
+ 2 files changed, 77 insertions(+), 32 deletions(-)
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -24,6 +24,7 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/device.h>
++#include <linux/utsname.h>
+
+ #include <linux/usb/composite.h>
+
+@@ -69,6 +70,8 @@ static char *iSerialNumber;
+ module_param(iSerialNumber, charp, 0);
+ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
+
++static char composite_manufacturer[50];
++
+ /*-------------------------------------------------------------------------*/
+
+ /**
+@@ -599,6 +602,7 @@ static int get_string(struct usb_composi
+ struct usb_configuration *c;
+ struct usb_function *f;
+ int len;
++ const char *str;
+
+ /* Yes, not only is USB's I18N support probably more than most
+ * folk will ever care about ... also, it's all supported here.
+@@ -638,9 +642,29 @@ static int get_string(struct usb_composi
+ return s->bLength;
+ }
+
+- /* Otherwise, look up and return a specified string. String IDs
+- * are device-scoped, so we look up each string table we're told
+- * about. These lookups are infrequent; simpler-is-better here.
++ /* Otherwise, look up and return a specified string. First
++ * check if the string has not been overridden.
++ */
++ if (cdev->manufacturer_override == id)
++ str = iManufacturer ?: composite->iManufacturer ?:
++ composite_manufacturer;
++ else if (cdev->product_override == id)
++ str = iProduct ?: composite->iProduct;
++ else if (cdev->serial_override == id)
++ str = iSerialNumber;
++ else
++ str = NULL;
++ if (str) {
++ struct usb_gadget_strings strings = {
++ .language = language,
++ .strings = &(struct usb_string) { 0xff, str }
++ };
++ return usb_gadget_get_string(&strings, 0xff, buf);
++ }
++
++ /* String IDs are device-scoped, so we look up each string
++ * table we're told about. These lookups are infrequent;
++ * simpler-is-better here.
+ */
+ if (composite->strings) {
+ len = lookup_string(composite->strings, buf, language, id);
+@@ -1025,26 +1049,17 @@ composite_unbind(struct usb_gadget *gadg
+ composite = NULL;
+ }
+
+-static void
+-string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
++static u8 override_id(struct usb_composite_dev *cdev, u8 *desc)
+ {
+- struct usb_string *str = tab->strings;
+-
+- for (str = tab->strings; str->s; str++) {
+- if (str->id == id) {
+- str->s = s;
+- return;
+- }
++ if (!*desc) {
++ int ret = usb_string_id(cdev);
++ if (unlikely(ret < 0))
++ WARNING(cdev, "failed to override string ID\n");
++ else
++ *desc = ret;
+ }
+-}
+
+-static void
+-string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
+-{
+- while (*tab) {
+- string_override_one(*tab, id, s);
+- tab++;
+- }
++ return *desc;
+ }
+
+ static int composite_bind(struct usb_gadget *gadget)
+@@ -1107,19 +1122,34 @@ static int composite_bind(struct usb_gad
+ cdev->desc = *composite->dev;
+ cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+
+- /* strings can't be assigned before bind() allocates the
+- * releavnt identifiers
+- */
+- if (cdev->desc.iManufacturer && iManufacturer)
+- string_override(composite->strings,
+- cdev->desc.iManufacturer, iManufacturer);
+- if (cdev->desc.iProduct && iProduct)
+- string_override(composite->strings,
+- cdev->desc.iProduct, iProduct);
+- if (cdev->desc.iSerialNumber && iSerialNumber)
+- string_override(composite->strings,
+- cdev->desc.iSerialNumber, iSerialNumber);
++ /* stirng overrides */
++ if (iManufacturer || !cdev->desc.iManufacturer) {
++ if (!iManufacturer && !composite->iManufacturer &&
++ !*composite_manufacturer)
++ snprintf(composite_manufacturer,
++ sizeof composite_manufacturer,
++ "%s %s with %s",
++ init_utsname()->sysname,
++ init_utsname()->release,
++ gadget->name);
++
++ cdev->manufacturer_override =
++ override_id(cdev, &cdev->desc.iManufacturer);
++ }
++
++ if (iProduct || (!cdev->desc.iProduct && composite->iProduct))
++ cdev->product_override =
++ override_id(cdev, &cdev->desc.iProduct);
++
++ if (iSerialNumber)
++ cdev->serial_override =
++ override_id(cdev, &cdev->desc.iSerialNumber);
++
++ /* has userspace failed to provide a serial number? */
++ if (composite->needs_serial && !cdev->desc.iSerialNumber)
++ WARNING(cdev, "userspace failed to provide iSerialNumber\n");
+
++ /* finish up */
+ status = device_create_file(&gadget->dev, &dev_attr_suspended);
+ if (status)
+ goto fail;
+@@ -1217,6 +1247,8 @@ int usb_composite_register(struct usb_co
+ if (!driver || !driver->dev || !driver->bind || composite)
+ return -EINVAL;
+
++ if (!driver->iProduct)
++ driver->iProduct = driver->name;
+ if (!driver->name)
+ driver->name = "composite";
+ composite_driver.function = (char *) driver->name;
+--- a/include/linux/usb/composite.h
++++ b/include/linux/usb/composite.h
+@@ -237,10 +237,17 @@ int usb_add_config(struct usb_composite_
+ /**
+ * struct usb_composite_driver - groups configurations into a gadget
+ * @name: For diagnostics, identifies the driver.
++ * @iProduct: Used as iProduct override if @dev->iProduct is not set.
++ * If NULL value of @name is taken.
++ * @iManufacturer: Used as iManufacturer override if @dev->iManufacturer is
++ * not set. If NULL a default "<system> <release> with <udc>" value
++ * will be used.
+ * @dev: Template descriptor for the device, including default device
+ * identifiers.
+ * @strings: tables of strings, keyed by identifiers assigned during bind()
+ * and language IDs provided in control requests
++ * @needs_serial: set to 1 if the gadget needs userspace to provide
++ * a serial number. If one is not provided, warning will be printed.
+ * @bind: (REQUIRED) Used to allocate resources that are shared across the
+ * whole device, such as string IDs, and add its configurations using
+ * @usb_add_config(). This may fail by returning a negative errno
+@@ -266,8 +273,11 @@ int usb_add_config(struct usb_composite_
+ */
+ struct usb_composite_driver {
+ const char *name;
++ const char *iProduct;
++ const char *iManufacturer;
+ const struct usb_device_descriptor *dev;
+ struct usb_gadget_strings **strings;
++ unsigned needs_serial:1;
+
+ /* REVISIT: bind() functions can be marked __init, which
+ * makes trouble for section mismatch analysis. See if
+@@ -334,6 +344,9 @@ struct usb_composite_dev {
+ struct list_head configs;
+ struct usb_composite_driver *driver;
+ u8 next_string_id;
++ u8 manufacturer_override;
++ u8 product_override;
++ u8 serial_override;
+
+ /* the gadget driver won't enable the data pullup
+ * while the deactivation count is nonzero.
diff --git a/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_composite_driver.patch b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_composite_driver.patch
new file mode 100644
index 00000000000000..779a690b66869c
--- /dev/null
+++ b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_composite_driver.patch
@@ -0,0 +1,323 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:15:37 2010
+Date: Thu, 12 Aug 2010 17:43:54 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: usb gadget: don't save bind callback in struct usb_composite_driver
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org,
+ =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Message-id: <cfb1102e8bd59822b76475d58f5e4f1ceadade50.1281625724.git.m.nazarewicz@samsung.com>
+
+The bind function is most of the time only called at init time so there
+is no need to save a pointer to it in the composite driver structure.
+
+This fixes many section mismatches reported by modpost.
+
+Signed-off-by: Michał Nazarewicz <m.nazarewicz@samsung.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/audio.c | 3 +--
+ drivers/usb/gadget/cdc2.c | 3 +--
+ drivers/usb/gadget/composite.c | 15 +++++++++++----
+ drivers/usb/gadget/ether.c | 3 +--
+ drivers/usb/gadget/g_ffs.c | 3 +--
+ drivers/usb/gadget/hid.c | 3 +--
+ drivers/usb/gadget/mass_storage.c | 3 +--
+ drivers/usb/gadget/multi.c | 3 +--
+ drivers/usb/gadget/serial.c | 3 +--
+ drivers/usb/gadget/webcam.c | 3 +--
+ drivers/usb/gadget/zero.c | 3 +--
+ include/linux/usb/composite.h | 19 +++++--------------
+ 12 files changed, 26 insertions(+), 38 deletions(-)
+
+--- a/drivers/usb/gadget/audio.c
++++ b/drivers/usb/gadget/audio.c
+@@ -166,13 +166,12 @@ static struct usb_composite_driver audio
+ .name = "g_audio",
+ .dev = &device_desc,
+ .strings = audio_strings,
+- .bind = audio_bind,
+ .unbind = __exit_p(audio_unbind),
+ };
+
+ static int __init init(void)
+ {
+- return usb_composite_register(&audio_driver);
++ return usb_composite_probe(&audio_driver, audio_bind);
+ }
+ module_init(init);
+
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -245,7 +245,6 @@ static struct usb_composite_driver cdc_d
+ .name = "g_cdc",
+ .dev = &device_desc,
+ .strings = dev_strings,
+- .bind = cdc_bind,
+ .unbind = __exit_p(cdc_unbind),
+ };
+
+@@ -255,7 +254,7 @@ MODULE_LICENSE("GPL");
+
+ static int __init init(void)
+ {
+- return usb_composite_register(&cdc_driver);
++ return usb_composite_probe(&cdc_driver, cdc_bind);
+ }
+ module_init(init);
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -40,6 +40,7 @@
+ #define USB_BUFSIZ 1024
+
+ static struct usb_composite_driver *composite;
++static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);
+
+ /* Some systems will need runtime overrides for the product identifers
+ * published in the device descriptor, either numbers or strings or both.
+@@ -1115,7 +1116,7 @@ static int composite_bind(struct usb_gad
+ * serial number), register function drivers, potentially update
+ * power state and consumption, etc
+ */
+- status = composite->bind(cdev);
++ status = composite_gadget_bind(cdev);
+ if (status < 0)
+ goto fail;
+
+@@ -1227,8 +1228,12 @@ static struct usb_gadget_driver composit
+ };
+
+ /**
+- * usb_composite_register() - register a composite driver
++ * usb_composite_probe() - register a composite driver
+ * @driver: the driver to register
++ * @bind: the callback used to allocate resources that are shared across the
++ * whole device, such as string IDs, and add its configurations using
++ * @usb_add_config(). This may fail by returning a negative errno
++ * value; it should return zero on successful initialization.
+ * Context: single threaded during gadget setup
+ *
+ * This function is used to register drivers using the composite driver
+@@ -1241,9 +1246,10 @@ static struct usb_gadget_driver composit
+ * while it was binding. That would usually be done in order to wait for
+ * some userspace participation.
+ */
+-int usb_composite_register(struct usb_composite_driver *driver)
++extern int usb_composite_probe(struct usb_composite_driver *driver,
++ int (*bind)(struct usb_composite_dev *cdev))
+ {
+- if (!driver || !driver->dev || !driver->bind || composite)
++ if (!driver || !driver->dev || !bind || composite)
+ return -EINVAL;
+
+ if (!driver->iProduct)
+@@ -1253,6 +1259,7 @@ int usb_composite_register(struct usb_co
+ composite_driver.function = (char *) driver->name;
+ composite_driver.driver.name = driver->name;
+ composite = driver;
++ composite_gadget_bind = bind;
+
+ return usb_gadget_probe_driver(&composite_driver, composite_bind);
+ }
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -402,7 +402,6 @@ static struct usb_composite_driver eth_d
+ .name = "g_ether",
+ .dev = &device_desc,
+ .strings = dev_strings,
+- .bind = eth_bind,
+ .unbind = __exit_p(eth_unbind),
+ };
+
+@@ -412,7 +411,7 @@ MODULE_LICENSE("GPL");
+
+ static int __init init(void)
+ {
+- return usb_composite_register(&eth_driver);
++ return usb_composite_probe(&eth_driver, eth_bind);
+ }
+ module_init(init);
+
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -147,7 +147,6 @@ static struct usb_composite_driver gfs_d
+ .name = DRIVER_NAME,
+ .dev = &gfs_dev_desc,
+ .strings = gfs_dev_strings,
+- .bind = gfs_bind,
+ .unbind = gfs_unbind,
+ .iProduct = DRIVER_DESC,
+ };
+@@ -187,7 +186,7 @@ static int functionfs_ready_callback(str
+ return -EBUSY;
+
+ gfs_ffs_data = ffs;
+- ret = usb_composite_register(&gfs_driver);
++ ret = usb_composite_probe(&gfs_driver, gfs_bind);
+ if (unlikely(ret < 0))
+ clear_bit(0, &gfs_registered);
+ return ret;
+--- a/drivers/usb/gadget/hid.c
++++ b/drivers/usb/gadget/hid.c
+@@ -256,7 +256,6 @@ static struct usb_composite_driver hidg_
+ .name = "g_hid",
+ .dev = &device_desc,
+ .strings = dev_strings,
+- .bind = hid_bind,
+ .unbind = __exit_p(hid_unbind),
+ };
+
+@@ -282,7 +281,7 @@ static int __init hidg_init(void)
+ if (status < 0)
+ return status;
+
+- status = usb_composite_register(&hidg_driver);
++ status = usb_composite_probe(&hidg_driver, hid_bind);
+ if (status < 0)
+ platform_driver_unregister(&hidg_plat_driver);
+
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -169,7 +169,6 @@ static int __init msg_bind(struct usb_co
+ static struct usb_composite_driver msg_driver = {
+ .name = "g_mass_storage",
+ .dev = &msg_device_desc,
+- .bind = msg_bind,
+ .iProduct = DRIVER_DESC,
+ .needs_serial = 1,
+ };
+@@ -180,7 +179,7 @@ MODULE_LICENSE("GPL");
+
+ static int __init msg_init(void)
+ {
+- return usb_composite_register(&msg_driver);
++ return usb_composite_probe(&msg_driver, msg_bind);
+ }
+ module_init(msg_init);
+
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -353,7 +353,6 @@ static struct usb_composite_driver multi
+ .name = "g_multi",
+ .dev = &device_desc,
+ .strings = dev_strings,
+- .bind = multi_bind,
+ .unbind = __exit_p(multi_unbind),
+ .iProduct = DRIVER_DESC,
+ .needs_serial = 1,
+@@ -362,7 +361,7 @@ static struct usb_composite_driver multi
+
+ static int __init multi_init(void)
+ {
+- return usb_composite_register(&multi_driver);
++ return usb_composite_probe(&multi_driver, multi_bind);
+ }
+ module_init(multi_init);
+
+--- a/drivers/usb/gadget/serial.c
++++ b/drivers/usb/gadget/serial.c
+@@ -242,7 +242,6 @@ static struct usb_composite_driver gseri
+ .name = "g_serial",
+ .dev = &device_desc,
+ .strings = dev_strings,
+- .bind = gs_bind,
+ };
+
+ static int __init init(void)
+@@ -271,7 +270,7 @@ static int __init init(void)
+ }
+ strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
+
+- return usb_composite_register(&gserial_driver);
++ return usb_composite_probe(&gserial_driver, gs_bind);
+ }
+ module_init(init);
+
+--- a/drivers/usb/gadget/webcam.c
++++ b/drivers/usb/gadget/webcam.c
+@@ -373,14 +373,13 @@ static struct usb_composite_driver webca
+ .name = "g_webcam",
+ .dev = &webcam_device_descriptor,
+ .strings = webcam_device_strings,
+- .bind = webcam_bind,
+ .unbind = webcam_unbind,
+ };
+
+ static int __init
+ webcam_init(void)
+ {
+- return usb_composite_register(&webcam_driver);
++ return usb_composite_probe(&webcam_driver, webcam_bind);
+ }
+
+ static void __exit
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -340,7 +340,6 @@ static struct usb_composite_driver zero_
+ .name = "zero",
+ .dev = &device_desc,
+ .strings = dev_strings,
+- .bind = zero_bind,
+ .unbind = zero_unbind,
+ .suspend = zero_suspend,
+ .resume = zero_resume,
+@@ -351,7 +350,7 @@ MODULE_LICENSE("GPL");
+
+ static int __init init(void)
+ {
+- return usb_composite_register(&zero_driver);
++ return usb_composite_probe(&zero_driver, zero_bind);
+ }
+ module_init(init);
+
+--- a/include/linux/usb/composite.h
++++ b/include/linux/usb/composite.h
+@@ -248,11 +248,7 @@ int usb_add_config(struct usb_composite_
+ * and language IDs provided in control requests
+ * @needs_serial: set to 1 if the gadget needs userspace to provide
+ * a serial number. If one is not provided, warning will be printed.
+- * @bind: (REQUIRED) Used to allocate resources that are shared across the
+- * whole device, such as string IDs, and add its configurations using
+- * @usb_add_config(). This may fail by returning a negative errno
+- * value; it should return zero on successful initialization.
+- * @unbind: Reverses @bind(); called as a side effect of unregistering
++ * @unbind: Reverses bind; called as a side effect of unregistering
+ * this driver.
+ * @disconnect: optional driver disconnect method
+ * @suspend: Notifies when the host stops sending USB traffic,
+@@ -263,7 +259,7 @@ int usb_add_config(struct usb_composite_
+ * Devices default to reporting self powered operation. Devices which rely
+ * on bus powered operation should report this in their @bind() method.
+ *
+- * Before returning from @bind, various fields in the template descriptor
++ * Before returning from bind, various fields in the template descriptor
+ * may be overridden. These include the idVendor/idProduct/bcdDevice values
+ * normally to bind the appropriate host side driver, and the three strings
+ * (iManufacturer, iProduct, iSerialNumber) normally used to provide user
+@@ -279,12 +275,6 @@ struct usb_composite_driver {
+ struct usb_gadget_strings **strings;
+ unsigned needs_serial:1;
+
+- /* REVISIT: bind() functions can be marked __init, which
+- * makes trouble for section mismatch analysis. See if
+- * we can't restructure things to avoid mismatching...
+- */
+-
+- int (*bind)(struct usb_composite_dev *);
+ int (*unbind)(struct usb_composite_dev *);
+
+ void (*disconnect)(struct usb_composite_dev *);
+@@ -294,8 +284,9 @@ struct usb_composite_driver {
+ void (*resume)(struct usb_composite_dev *);
+ };
+
+-extern int usb_composite_register(struct usb_composite_driver *);
+-extern void usb_composite_unregister(struct usb_composite_driver *);
++extern int usb_composite_probe(struct usb_composite_driver *driver,
++ int (*bind)(struct usb_composite_dev *cdev));
++extern void usb_composite_unregister(struct usb_composite_driver *driver);
+
+
+ /**
diff --git a/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_configuration.patch b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_configuration.patch
new file mode 100644
index 00000000000000..115ae2d361a7ea
--- /dev/null
+++ b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_configuration.patch
@@ -0,0 +1,409 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:16:05 2010
+Date: Thu, 12 Aug 2010 17:43:55 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: usb gadget: don't save bind callback in struct usb_configuration
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org,
+ =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Message-id: <c4e57f3ae9153e524e7422527ef5e7351c1cf10c.1281625724.git.m.nazarewicz@samsung.com>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+The bind function is most of the time only called at init time so there
+is no need to save a pointer to it in the configuration structure.
+
+This fixes many section mismatches reported by modpost.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+[m.nazarewicz@samsung.com: updated for -next]
+Signed-off-by: Michał Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/audio.c | 3 +--
+ drivers/usb/gadget/cdc2.c | 3 +--
+ drivers/usb/gadget/composite.c | 14 ++++++++------
+ drivers/usb/gadget/ether.c | 7 +++----
+ drivers/usb/gadget/f_loopback.c | 3 +--
+ drivers/usb/gadget/f_sourcesink.c | 3 +--
+ drivers/usb/gadget/g_ffs.c | 3 +--
+ drivers/usb/gadget/hid.c | 3 +--
+ drivers/usb/gadget/mass_storage.c | 3 +--
+ drivers/usb/gadget/multi.c | 10 ++++------
+ drivers/usb/gadget/nokia.c | 8 ++++----
+ drivers/usb/gadget/serial.c | 4 ++--
+ drivers/usb/gadget/webcam.c | 4 ++--
+ include/linux/usb/composite.h | 8 +++-----
+ 14 files changed, 33 insertions(+), 43 deletions(-)
+
+--- a/drivers/usb/gadget/audio.c
++++ b/drivers/usb/gadget/audio.c
+@@ -105,7 +105,6 @@ static int __init audio_do_config(struct
+
+ static struct usb_configuration audio_config_driver = {
+ .label = DRIVER_DESC,
+- .bind = audio_do_config,
+ .bConfigurationValue = 1,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -145,7 +144,7 @@ static int __init audio_bind(struct usb_
+ strings_dev[STRING_PRODUCT_IDX].id = status;
+ device_desc.iProduct = status;
+
+- status = usb_add_config(cdev, &audio_config_driver);
++ status = usb_add_config(cdev, &audio_config_driver, audio_do_config);
+ if (status < 0)
+ goto fail;
+
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -151,7 +151,6 @@ static int __init cdc_do_config(struct u
+
+ static struct usb_configuration cdc_config_driver = {
+ .label = "CDC Composite (ECM + ACM)",
+- .bind = cdc_do_config,
+ .bConfigurationValue = 1,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -218,7 +217,7 @@ static int __init cdc_bind(struct usb_co
+ device_desc.iProduct = status;
+
+ /* register our configuration */
+- status = usb_add_config(cdev, &cdc_config_driver);
++ status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config);
+ if (status < 0)
+ goto fail1;
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -474,18 +474,20 @@ done:
+ * usb_add_config() - add a configuration to a device.
+ * @cdev: wraps the USB gadget
+ * @config: the configuration, with bConfigurationValue assigned
++ * @bind: the configuration's bind function
+ * Context: single threaded during gadget setup
+ *
+- * One of the main tasks of a composite driver's bind() routine is to
++ * One of the main tasks of a composite @bind() routine is to
+ * add each of the configurations it supports, using this routine.
+ *
+- * This function returns the value of the configuration's bind(), which
++ * This function returns the value of the configuration's @bind(), which
+ * is zero for success else a negative errno value. Binding configurations
+ * assigns global resources including string IDs, and per-configuration
+ * resources such as interface IDs and endpoints.
+ */
+ int usb_add_config(struct usb_composite_dev *cdev,
+- struct usb_configuration *config)
++ struct usb_configuration *config,
++ int (*bind)(struct usb_configuration *))
+ {
+ int status = -EINVAL;
+ struct usb_configuration *c;
+@@ -494,7 +496,7 @@ int usb_add_config(struct usb_composite_
+ config->bConfigurationValue,
+ config->label, config);
+
+- if (!config->bConfigurationValue || !config->bind)
++ if (!config->bConfigurationValue || !bind)
+ goto done;
+
+ /* Prevent duplicate configuration identifiers */
+@@ -511,7 +513,7 @@ int usb_add_config(struct usb_composite_
+ INIT_LIST_HEAD(&config->functions);
+ config->next_interface_id = 0;
+
+- status = config->bind(config);
++ status = bind(config);
+ if (status < 0) {
+ list_del(&config->list);
+ config->cdev = NULL;
+@@ -537,7 +539,7 @@ int usb_add_config(struct usb_composite_
+ }
+ }
+
+- /* set_alt(), or next config->bind(), sets up
++ /* set_alt(), or next bind(), sets up
+ * ep->driver_data as needed.
+ */
+ usb_ep_autoconfig_reset(cdev->gadget);
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -251,7 +251,6 @@ static int __init rndis_do_config(struct
+
+ static struct usb_configuration rndis_config_driver = {
+ .label = "RNDIS",
+- .bind = rndis_do_config,
+ .bConfigurationValue = 2,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -289,7 +288,6 @@ static int __init eth_do_config(struct u
+
+ static struct usb_configuration eth_config_driver = {
+ /* .label = f(hardware) */
+- .bind = eth_do_config,
+ .bConfigurationValue = 1,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -373,12 +371,13 @@ static int __init eth_bind(struct usb_co
+
+ /* register our configuration(s); RNDIS first, if it's used */
+ if (has_rndis()) {
+- status = usb_add_config(cdev, &rndis_config_driver);
++ status = usb_add_config(cdev, &rndis_config_driver,
++ rndis_do_config);
+ if (status < 0)
+ goto fail;
+ }
+
+- status = usb_add_config(cdev, &eth_config_driver);
++ status = usb_add_config(cdev, &eth_config_driver, eth_do_config);
+ if (status < 0)
+ goto fail;
+
+--- a/drivers/usb/gadget/f_loopback.c
++++ b/drivers/usb/gadget/f_loopback.c
+@@ -349,7 +349,6 @@ static int __init loopback_bind_config(s
+ static struct usb_configuration loopback_driver = {
+ .label = "loopback",
+ .strings = loopback_strings,
+- .bind = loopback_bind_config,
+ .bConfigurationValue = 2,
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+ /* .iConfiguration = DYNAMIC */
+@@ -382,5 +381,5 @@ int __init loopback_add(struct usb_compo
+ loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ }
+
+- return usb_add_config(cdev, &loopback_driver);
++ return usb_add_config(cdev, &loopback_driver, loopback_bind_config);
+ }
+--- a/drivers/usb/gadget/f_sourcesink.c
++++ b/drivers/usb/gadget/f_sourcesink.c
+@@ -498,7 +498,6 @@ unknown:
+ static struct usb_configuration sourcesink_driver = {
+ .label = "source/sink",
+ .strings = sourcesink_strings,
+- .bind = sourcesink_bind_config,
+ .setup = sourcesink_setup,
+ .bConfigurationValue = 3,
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -532,5 +531,5 @@ int __init sourcesink_add(struct usb_com
+ sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ }
+
+- return usb_add_config(cdev, &sourcesink_driver);
++ return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config);
+ }
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -234,11 +234,10 @@ static int gfs_bind(struct usb_composite
+
+ c->c.label = gfs_strings[i].s;
+ c->c.iConfiguration = gfs_strings[i].id;
+- c->c.bind = gfs_do_config;
+ c->c.bConfigurationValue = 1 + i;
+ c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER;
+
+- ret = usb_add_config(cdev, &c->c);
++ ret = usb_add_config(cdev, &c->c, gfs_do_config);
+ if (unlikely(ret < 0))
+ goto error_unbind;
+ }
+--- a/drivers/usb/gadget/hid.c
++++ b/drivers/usb/gadget/hid.c
+@@ -148,7 +148,6 @@ static int __init do_config(struct usb_c
+
+ static struct usb_configuration config_driver = {
+ .label = "HID Gadget",
+- .bind = do_config,
+ .bConfigurationValue = 1,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -201,7 +200,7 @@ static int __init hid_bind(struct usb_co
+ device_desc.iProduct = status;
+
+ /* register our configuration */
+- status = usb_add_config(cdev, &config_driver);
++ status = usb_add_config(cdev, &config_driver, do_config);
+ if (status < 0)
+ return status;
+
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -141,7 +141,6 @@ static int __init msg_do_config(struct u
+
+ static struct usb_configuration msg_config_driver = {
+ .label = "Linux File-Backed Storage",
+- .bind = msg_do_config,
+ .bConfigurationValue = 1,
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+ };
+@@ -153,7 +152,7 @@ static int __init msg_bind(struct usb_co
+ {
+ int status;
+
+- status = usb_add_config(cdev, &msg_config_driver);
++ status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
+ if (status < 0)
+ return status;
+
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -164,7 +164,7 @@ static u8 hostaddr[ETH_ALEN];
+
+ #ifdef USB_ETH_RNDIS
+
+-static __ref int rndis_do_config(struct usb_configuration *c)
++static __init int rndis_do_config(struct usb_configuration *c)
+ {
+ int ret;
+
+@@ -191,7 +191,6 @@ static __ref int rndis_do_config(struct
+ 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,
+ };
+@@ -199,7 +198,7 @@ static int rndis_config_register(struct
+ 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);
++ return usb_add_config(cdev, &config, rndis_do_config);
+ }
+
+ #else
+@@ -216,7 +215,7 @@ static int rndis_config_register(struct
+
+ #ifdef CONFIG_USB_G_MULTI_CDC
+
+-static __ref int cdc_do_config(struct usb_configuration *c)
++static __init int cdc_do_config(struct usb_configuration *c)
+ {
+ int ret;
+
+@@ -243,7 +242,6 @@ static __ref int cdc_do_config(struct us
+ 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,
+ };
+@@ -251,7 +249,7 @@ static int cdc_config_register(struct us
+ 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);
++ return usb_add_config(cdev, &config, cdc_do_config);
+ }
+
+ #else
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -135,7 +135,6 @@ static int __init nokia_bind_config(stru
+
+ static struct usb_configuration nokia_config_500ma_driver = {
+ .label = "Bus Powered",
+- .bind = nokia_bind_config,
+ .bConfigurationValue = 1,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_ONE,
+@@ -144,7 +143,6 @@ static struct usb_configuration nokia_co
+
+ static struct usb_configuration nokia_config_100ma_driver = {
+ .label = "Self Powered",
+- .bind = nokia_bind_config,
+ .bConfigurationValue = 2,
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+@@ -206,11 +204,13 @@ static int __init nokia_bind(struct usb_
+ }
+
+ /* finaly register the configuration */
+- status = usb_add_config(cdev, &nokia_config_500ma_driver);
++ status = usb_add_config(cdev, &nokia_config_500ma_driver,
++ nokia_bind_config);
+ if (status < 0)
+ goto err_usb;
+
+- status = usb_add_config(cdev, &nokia_config_100ma_driver);
++ status = usb_add_config(cdev, &nokia_config_100ma_driver,
++ nokia_bind_config);
+ if (status < 0)
+ goto err_usb;
+
+--- a/drivers/usb/gadget/serial.c
++++ b/drivers/usb/gadget/serial.c
+@@ -155,7 +155,6 @@ static int __init serial_bind_config(str
+
+ static struct usb_configuration serial_config_driver = {
+ /* .label = f(use_acm) */
+- .bind = serial_bind_config,
+ /* .bConfigurationValue = f(use_acm) */
+ /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -225,7 +224,8 @@ static int __init gs_bind(struct usb_com
+ }
+
+ /* register our configuration */
+- status = usb_add_config(cdev, &serial_config_driver);
++ status = usb_add_config(cdev, &serial_config_driver,
++ serial_bind_config);
+ if (status < 0)
+ goto fail;
+
+--- a/drivers/usb/gadget/webcam.c
++++ b/drivers/usb/gadget/webcam.c
+@@ -317,7 +317,6 @@ webcam_config_bind(struct usb_configurat
+
+ static struct usb_configuration webcam_config_driver = {
+ .label = webcam_config_label,
+- .bind = webcam_config_bind,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0, /* dynamic */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+@@ -354,7 +353,8 @@ webcam_bind(struct usb_composite_dev *cd
+ webcam_config_driver.iConfiguration = ret;
+
+ /* Register our configuration. */
+- if ((ret = usb_add_config(cdev, &webcam_config_driver)) < 0)
++ if ((ret = usb_add_config(cdev, &webcam_config_driver,
++ webcam_config_bind)) < 0)
+ goto error;
+
+ INFO(cdev, "Webcam Video Gadget\n");
+--- a/include/linux/usb/composite.h
++++ b/include/linux/usb/composite.h
+@@ -161,8 +161,6 @@ ep_choose(struct usb_gadget *g, struct u
+ * and by language IDs provided in control requests.
+ * @descriptors: Table of descriptors preceding all function descriptors.
+ * Examples include OTG and vendor-specific descriptors.
+- * @bind: Called from @usb_add_config() to allocate resources unique to this
+- * configuration and to call @usb_add_function() for each function used.
+ * @unbind: Reverses @bind; called as a side effect of unregistering the
+ * driver which added this configuration.
+ * @setup: Used to delegate control requests that aren't handled by standard
+@@ -207,8 +205,7 @@ struct usb_configuration {
+ * we can't restructure things to avoid mismatching...
+ */
+
+- /* configuration management: bind/unbind */
+- int (*bind)(struct usb_configuration *);
++ /* configuration management: unbind/setup */
+ void (*unbind)(struct usb_configuration *);
+ int (*setup)(struct usb_configuration *,
+ const struct usb_ctrlrequest *);
+@@ -232,7 +229,8 @@ struct usb_configuration {
+ };
+
+ int usb_add_config(struct usb_composite_dev *,
+- struct usb_configuration *);
++ struct usb_configuration *,
++ int (*)(struct usb_configuration *));
+
+ /**
+ * struct usb_composite_driver - groups configurations into a gadget
diff --git a/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch
new file mode 100644
index 00000000000000..96fc71f65726e1
--- /dev/null
+++ b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch
@@ -0,0 +1,1062 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:15:02 2010
+Date: Thu, 12 Aug 2010 17:43:53 +0200
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Subject: usb gadget: don't save bind callback in struct usb_gadget_driver
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org,
+ =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Message-id: <340f780f91de1b3ca17d0c29d87963205d172f4e.1281625724.git.m.nazarewicz@samsung.com>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+To accomplish this the function to register a gadget driver takes the bind
+function as a second argument. To make things clearer rename the function
+to resemble platform_driver_probe.
+
+This fixes many section mismatches like
+
+ WARNING: drivers/usb/gadget/g_printer.o(.data+0xc): Section mismatch in
+ reference from the variable printer_driver to the function
+ .init.text:printer_bind()
+ The variable printer_driver references
+ the function __init printer_bind()
+
+All callers are fixed.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+[m.nazarewicz@samsung.com: added dbgp]
+Signed-off-by: Michał Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/amd5536udc.c | 9 +++++----
+ drivers/usb/gadget/at91_udc.c | 11 ++++++-----
+ drivers/usb/gadget/atmel_usba_udc.c | 7 ++++---
+ drivers/usb/gadget/ci13xxx_udc.c | 18 ++++++++++--------
+ drivers/usb/gadget/composite.c | 3 +--
+ drivers/usb/gadget/dbgp.c | 3 +--
+ drivers/usb/gadget/dummy_hcd.c | 10 +++++-----
+ drivers/usb/gadget/file_storage.c | 3 +--
+ drivers/usb/gadget/fsl_qe_udc.c | 12 ++++++------
+ drivers/usb/gadget/fsl_udc_core.c | 10 +++++-----
+ drivers/usb/gadget/gmidi.c | 3 +--
+ drivers/usb/gadget/goku_udc.c | 9 +++++----
+ drivers/usb/gadget/imx_udc.c | 9 +++++----
+ drivers/usb/gadget/inode.c | 6 ++----
+ drivers/usb/gadget/langwell_udc.c | 9 +++++----
+ drivers/usb/gadget/lh7a40x_udc.c | 10 +++++-----
+ drivers/usb/gadget/m66592-udc.c | 9 +++++----
+ drivers/usb/gadget/net2280.c | 10 +++++-----
+ drivers/usb/gadget/omap_udc.c | 10 +++++-----
+ drivers/usb/gadget/printer.c | 5 ++---
+ drivers/usb/gadget/pxa25x_udc.c | 9 +++++----
+ drivers/usb/gadget/pxa27x_udc.c | 12 +++++++-----
+ drivers/usb/gadget/r8a66597-udc.c | 9 +++++----
+ drivers/usb/gadget/s3c-hsotg.c | 9 +++++----
+ drivers/usb/gadget/s3c2410_udc.c | 17 ++++++++---------
+ drivers/usb/musb/musb_gadget.c | 9 +++++----
+ include/linux/usb/gadget.h | 20 ++++++++------------
+ 27 files changed, 127 insertions(+), 124 deletions(-)
+
+--- a/drivers/usb/gadget/amd5536udc.c
++++ b/drivers/usb/gadget/amd5536udc.c
+@@ -1954,13 +1954,14 @@ static int setup_ep0(struct udc *dev)
+ }
+
+ /* Called by gadget driver to register itself */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct udc *dev = udc;
+ int retval;
+ u32 tmp;
+
+- if (!driver || !driver->bind || !driver->setup
++ if (!driver || !bind || !driver->setup
+ || driver->speed != USB_SPEED_HIGH)
+ return -EINVAL;
+ if (!dev)
+@@ -1972,7 +1973,7 @@ int usb_gadget_register_driver(struct us
+ dev->driver = driver;
+ dev->gadget.dev.driver = &driver->driver;
+
+- retval = driver->bind(&dev->gadget);
++ retval = bind(&dev->gadget);
+
+ /* Some gadget drivers use both ep0 directions.
+ * NOTE: to gadget driver, ep0 is just one endpoint...
+@@ -2000,7 +2001,7 @@ int usb_gadget_register_driver(struct us
+
+ return 0;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ /* shutdown requests and disconnect from gadget */
+ static void
+--- a/drivers/usb/gadget/at91_udc.c
++++ b/drivers/usb/gadget/at91_udc.c
+@@ -1628,7 +1628,8 @@ static void at91_vbus_timer(unsigned lon
+ schedule_work(&udc->vbus_timer_work);
+ }
+
+-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct at91_udc *udc = &controller;
+ int retval;
+@@ -1636,7 +1637,7 @@ int usb_gadget_register_driver (struct u
+
+ if (!driver
+ || driver->speed < USB_SPEED_FULL
+- || !driver->bind
++ || !bind
+ || !driver->setup) {
+ DBG("bad parameter.\n");
+ return -EINVAL;
+@@ -1653,9 +1654,9 @@ int usb_gadget_register_driver (struct u
+ udc->enabled = 1;
+ udc->selfpowered = 1;
+
+- retval = driver->bind(&udc->gadget);
++ retval = bind(&udc->gadget);
+ if (retval) {
+- DBG("driver->bind() returned %d\n", retval);
++ DBG("bind() returned %d\n", retval);
+ udc->driver = NULL;
+ udc->gadget.dev.driver = NULL;
+ dev_set_drvdata(&udc->gadget.dev, NULL);
+@@ -1671,7 +1672,7 @@ int usb_gadget_register_driver (struct u
+ DBG("bound to %s\n", driver->driver.name);
+ return 0;
+ }
+-EXPORT_SYMBOL (usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/atmel_usba_udc.c
++++ b/drivers/usb/gadget/atmel_usba_udc.c
+@@ -1789,7 +1789,8 @@ out:
+ return IRQ_HANDLED;
+ }
+
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct usba_udc *udc = &the_udc;
+ unsigned long flags;
+@@ -1812,7 +1813,7 @@ int usb_gadget_register_driver(struct us
+ clk_enable(udc->pclk);
+ clk_enable(udc->hclk);
+
+- ret = driver->bind(&udc->gadget);
++ ret = bind(&udc->gadget);
+ if (ret) {
+ DBG(DBG_ERR, "Could not bind to driver %s: error %d\n",
+ driver->driver.name, ret);
+@@ -1841,7 +1842,7 @@ err_driver_bind:
+ udc->gadget.dev.driver = NULL;
+ return ret;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/ci13xxx_udc.c
++++ b/drivers/usb/gadget/ci13xxx_udc.c
+@@ -2340,12 +2340,15 @@ static const struct usb_ep_ops usb_ep_op
+ static const struct usb_gadget_ops usb_gadget_ops;
+
+ /**
+- * usb_gadget_register_driver: register a gadget driver
++ * usb_gadget_probe_driver: register a gadget driver
++ * @driver: the driver being registered
++ * @bind: the driver's bind callback
+ *
+- * Check usb_gadget_register_driver() at "usb_gadget.h" for details
+- * Interrupts are enabled here
++ * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
++ * Interrupts are enabled here.
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct ci13xxx *udc = _udc;
+ unsigned long i, k, flags;
+@@ -2354,7 +2357,7 @@ int usb_gadget_register_driver(struct us
+ trace("%p", driver);
+
+ if (driver == NULL ||
+- driver->bind == NULL ||
++ bind == NULL ||
+ driver->unbind == NULL ||
+ driver->setup == NULL ||
+ driver->disconnect == NULL ||
+@@ -2430,7 +2433,7 @@ int usb_gadget_register_driver(struct us
+ udc->gadget.dev.driver = &driver->driver;
+
+ spin_unlock_irqrestore(udc->lock, flags);
+- retval = driver->bind(&udc->gadget); /* MAY SLEEP */
++ retval = bind(&udc->gadget); /* MAY SLEEP */
+ spin_lock_irqsave(udc->lock, flags);
+
+ if (retval) {
+@@ -2447,7 +2450,7 @@ int usb_gadget_register_driver(struct us
+ usb_gadget_unregister_driver(driver);
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ /**
+ * usb_gadget_unregister_driver: unregister a gadget driver
+@@ -2462,7 +2465,6 @@ int usb_gadget_unregister_driver(struct
+ trace("%p", driver);
+
+ if (driver == NULL ||
+- driver->bind == NULL ||
+ driver->unbind == NULL ||
+ driver->setup == NULL ||
+ driver->disconnect == NULL ||
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -1213,7 +1213,6 @@ composite_resume(struct usb_gadget *gadg
+ static struct usb_gadget_driver composite_driver = {
+ .speed = USB_SPEED_HIGH,
+
+- .bind = composite_bind,
+ .unbind = composite_unbind,
+
+ .setup = composite_setup,
+@@ -1255,7 +1254,7 @@ int usb_composite_register(struct usb_co
+ composite_driver.driver.name = driver->name;
+ composite = driver;
+
+- return usb_gadget_register_driver(&composite_driver);
++ return usb_gadget_probe_driver(&composite_driver, composite_bind);
+ }
+
+ /**
+--- a/drivers/usb/gadget/dbgp.c
++++ b/drivers/usb/gadget/dbgp.c
+@@ -403,7 +403,6 @@ fail:
+ static struct usb_gadget_driver dbgp_driver = {
+ .function = "dbgp",
+ .speed = USB_SPEED_HIGH,
+- .bind = dbgp_bind,
+ .unbind = dbgp_unbind,
+ .setup = dbgp_setup,
+ .disconnect = dbgp_disconnect,
+@@ -415,7 +414,7 @@ static struct usb_gadget_driver dbgp_dri
+
+ static int __init dbgp_init(void)
+ {
+- return usb_gadget_register_driver(&dbgp_driver);
++ return usb_gadget_probe_driver(&dbgp_driver, dbgp_bind);
+ }
+
+ static void __exit dbgp_exit(void)
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -748,7 +748,8 @@ static DEVICE_ATTR (function, S_IRUGO, s
+ */
+
+ int
+-usb_gadget_register_driver (struct usb_gadget_driver *driver)
++usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct dummy *dum = the_controller;
+ int retval, i;
+@@ -757,8 +758,7 @@ usb_gadget_register_driver (struct usb_g
+ return -EINVAL;
+ if (dum->driver)
+ return -EBUSY;
+- if (!driver->bind || !driver->setup
+- || driver->speed == USB_SPEED_UNKNOWN)
++ if (!bind || !driver->setup || driver->speed == USB_SPEED_UNKNOWN)
+ return -EINVAL;
+
+ /*
+@@ -796,7 +796,7 @@ usb_gadget_register_driver (struct usb_g
+ dum->gadget.dev.driver = &driver->driver;
+ dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
+ driver->driver.name);
+- retval = driver->bind(&dum->gadget);
++ retval = bind(&dum->gadget);
+ if (retval) {
+ dum->driver = NULL;
+ dum->gadget.dev.driver = NULL;
+@@ -812,7 +812,7 @@ usb_gadget_register_driver (struct usb_g
+ usb_hcd_poll_rh_status (dummy_to_hcd (dum));
+ return 0;
+ }
+-EXPORT_SYMBOL (usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int
+ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -3608,7 +3608,6 @@ static struct usb_gadget_driver fsg_dri
+ .speed = USB_SPEED_FULL,
+ #endif
+ .function = (char *) fsg_string_product,
+- .bind = fsg_bind,
+ .unbind = fsg_unbind,
+ .disconnect = fsg_disconnect,
+ .setup = fsg_setup,
+@@ -3650,7 +3649,7 @@ static int __init fsg_init(void)
+ if ((rc = fsg_alloc()) != 0)
+ return rc;
+ fsg = the_fsg;
+- if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
++ if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0)
+ kref_put(&fsg->ref, fsg_release);
+ return rc;
+ }
+--- a/drivers/usb/gadget/fsl_qe_udc.c
++++ b/drivers/usb/gadget/fsl_qe_udc.c
+@@ -2302,9 +2302,10 @@ static irqreturn_t qe_udc_irq(int irq, v
+ }
+
+ /*-------------------------------------------------------------------------
+- Gadget driver register and unregister.
++ Gadget driver probe and unregister.
+ --------------------------------------------------------------------------*/
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ int retval;
+ unsigned long flags = 0;
+@@ -2315,8 +2316,7 @@ int usb_gadget_register_driver(struct us
+
+ if (!driver || (driver->speed != USB_SPEED_FULL
+ && driver->speed != USB_SPEED_HIGH)
+- || !driver->bind || !driver->disconnect
+- || !driver->setup)
++ || !bind || !driver->disconnect || !driver->setup)
+ return -EINVAL;
+
+ if (udc_controller->driver)
+@@ -2332,7 +2332,7 @@ int usb_gadget_register_driver(struct us
+ udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed);
+ spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+- retval = driver->bind(&udc_controller->gadget);
++ retval = bind(&udc_controller->gadget);
+ if (retval) {
+ dev_err(udc_controller->dev, "bind to %s --> %d",
+ driver->driver.name, retval);
+@@ -2353,7 +2353,7 @@ int usb_gadget_register_driver(struct us
+ udc_controller->gadget.name, driver->driver.name);
+ return 0;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/fsl_udc_core.c
++++ b/drivers/usb/gadget/fsl_udc_core.c
+@@ -1765,7 +1765,8 @@ static irqreturn_t fsl_udc_irq(int irq,
+ * Hook to gadget drivers
+ * Called by initialization code of gadget drivers
+ *----------------------------------------------------------------*/
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ int retval = -ENODEV;
+ unsigned long flags = 0;
+@@ -1775,8 +1776,7 @@ int usb_gadget_register_driver(struct us
+
+ if (!driver || (driver->speed != USB_SPEED_FULL
+ && driver->speed != USB_SPEED_HIGH)
+- || !driver->bind || !driver->disconnect
+- || !driver->setup)
++ || !bind || !driver->disconnect || !driver->setup)
+ return -EINVAL;
+
+ if (udc_controller->driver)
+@@ -1792,7 +1792,7 @@ int usb_gadget_register_driver(struct us
+ spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+ /* bind udc driver to gadget driver */
+- retval = driver->bind(&udc_controller->gadget);
++ retval = bind(&udc_controller->gadget);
+ if (retval) {
+ VDBG("bind to %s --> %d", driver->driver.name, retval);
+ udc_controller->gadget.dev.driver = NULL;
+@@ -1814,7 +1814,7 @@ out:
+ retval);
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ /* Disconnect from gadget driver */
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+--- a/drivers/usb/gadget/gmidi.c
++++ b/drivers/usb/gadget/gmidi.c
+@@ -1292,7 +1292,6 @@ static void gmidi_resume(struct usb_gadg
+ static struct usb_gadget_driver gmidi_driver = {
+ .speed = USB_SPEED_FULL,
+ .function = (char *)longname,
+- .bind = gmidi_bind,
+ .unbind = gmidi_unbind,
+
+ .setup = gmidi_setup,
+@@ -1309,7 +1308,7 @@ static struct usb_gadget_driver gmidi_dr
+
+ static int __init gmidi_init(void)
+ {
+- return usb_gadget_register_driver(&gmidi_driver);
++ return usb_gadget_probe_driver(&gmidi_driver, gmidi_bind);
+ }
+ module_init(gmidi_init);
+
+--- a/drivers/usb/gadget/goku_udc.c
++++ b/drivers/usb/gadget/goku_udc.c
+@@ -1343,14 +1343,15 @@ static struct goku_udc *the_controller;
+ * disconnect is reported. then a host may connect again, or
+ * the driver might get unbound.
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct goku_udc *dev = the_controller;
+ int retval;
+
+ if (!driver
+ || driver->speed < USB_SPEED_FULL
+- || !driver->bind
++ || !bind
+ || !driver->disconnect
+ || !driver->setup)
+ return -EINVAL;
+@@ -1363,7 +1364,7 @@ int usb_gadget_register_driver(struct us
+ driver->driver.bus = NULL;
+ dev->driver = driver;
+ dev->gadget.dev.driver = &driver->driver;
+- retval = driver->bind(&dev->gadget);
++ retval = bind(&dev->gadget);
+ if (retval) {
+ DBG(dev, "bind to driver %s --> error %d\n",
+ driver->driver.name, retval);
+@@ -1380,7 +1381,7 @@ int usb_gadget_register_driver(struct us
+ DBG(dev, "registered gadget driver '%s'\n", driver->driver.name);
+ return 0;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ static void
+ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
+--- a/drivers/usb/gadget/imx_udc.c
++++ b/drivers/usb/gadget/imx_udc.c
+@@ -1319,14 +1319,15 @@ static struct imx_udc_struct controller
+ * USB gadged driver functions
+ *******************************************************************************
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct imx_udc_struct *imx_usb = &controller;
+ int retval;
+
+ if (!driver
+ || driver->speed < USB_SPEED_FULL
+- || !driver->bind
++ || !bind
+ || !driver->disconnect
+ || !driver->setup)
+ return -EINVAL;
+@@ -1342,7 +1343,7 @@ int usb_gadget_register_driver(struct us
+ retval = device_add(&imx_usb->gadget.dev);
+ if (retval)
+ goto fail;
+- retval = driver->bind(&imx_usb->gadget);
++ retval = bind(&imx_usb->gadget);
+ if (retval) {
+ D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n",
+ __func__, driver->driver.name, retval);
+@@ -1362,7 +1363,7 @@ fail:
+ imx_usb->gadget.dev.driver = NULL;
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/inode.c
++++ b/drivers/usb/gadget/inode.c
+@@ -1775,7 +1775,6 @@ static struct usb_gadget_driver gadgetfs
+ .speed = USB_SPEED_FULL,
+ #endif
+ .function = (char *) driver_desc,
+- .bind = gadgetfs_bind,
+ .unbind = gadgetfs_unbind,
+ .setup = gadgetfs_setup,
+ .disconnect = gadgetfs_disconnect,
+@@ -1798,7 +1797,6 @@ static int gadgetfs_probe (struct usb_ga
+
+ static struct usb_gadget_driver probe_driver = {
+ .speed = USB_SPEED_HIGH,
+- .bind = gadgetfs_probe,
+ .unbind = gadgetfs_nop,
+ .setup = (void *)gadgetfs_nop,
+ .disconnect = gadgetfs_nop,
+@@ -1908,7 +1906,7 @@ dev_config (struct file *fd, const char
+
+ /* triggers gadgetfs_bind(); then we can enumerate. */
+ spin_unlock_irq (&dev->lock);
+- value = usb_gadget_register_driver (&gadgetfs_driver);
++ value = usb_gadget_probe_driver(&gadgetfs_driver, gadgetfs_bind);
+ if (value != 0) {
+ kfree (dev->buf);
+ dev->buf = NULL;
+@@ -2047,7 +2045,7 @@ gadgetfs_fill_super (struct super_block
+ return -ESRCH;
+
+ /* fake probe to determine $CHIP */
+- (void) usb_gadget_register_driver (&probe_driver);
++ (void) usb_gadget_probe_driver(&probe_driver, gadgetfs_probe);
+ if (!CHIP)
+ return -ENODEV;
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -1855,7 +1855,8 @@ static DEVICE_ATTR(remote_wakeup, S_IWUS
+ * the driver might get unbound.
+ */
+
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct langwell_udc *dev = the_controller;
+ unsigned long flags;
+@@ -1878,7 +1879,7 @@ int usb_gadget_register_driver(struct us
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- retval = driver->bind(&dev->gadget);
++ retval = bind(&dev->gadget);
+ if (retval) {
+ dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n",
+ driver->driver.name, retval);
+@@ -1916,7 +1917,7 @@ err_unbind:
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+
+ /* unregister gadget driver */
+@@ -1930,7 +1931,7 @@ int usb_gadget_unregister_driver(struct
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+- if (unlikely(!driver || !driver->bind || !driver->unbind))
++ if (unlikely(!driver || !driver->unbind))
+ return -EINVAL;
+
+ /* exit PHY low power suspend */
+--- a/drivers/usb/gadget/lh7a40x_udc.c
++++ b/drivers/usb/gadget/lh7a40x_udc.c
+@@ -408,7 +408,8 @@ static void udc_enable(struct lh7a40x_ud
+ /*
+ Register entry point for the peripheral controller driver.
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct lh7a40x_udc *dev = the_controller;
+ int retval;
+@@ -417,7 +418,7 @@ int usb_gadget_register_driver(struct us
+
+ if (!driver
+ || driver->speed != USB_SPEED_FULL
+- || !driver->bind
++ || !bind
+ || !driver->disconnect
+ || !driver->setup)
+ return -EINVAL;
+@@ -431,7 +432,7 @@ int usb_gadget_register_driver(struct us
+ dev->gadget.dev.driver = &driver->driver;
+
+ device_add(&dev->gadget.dev);
+- retval = driver->bind(&dev->gadget);
++ retval = bind(&dev->gadget);
+ if (retval) {
+ printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
+ dev->gadget.name, driver->driver.name, retval);
+@@ -453,8 +454,7 @@ int usb_gadget_register_driver(struct us
+
+ return 0;
+ }
+-
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ /*
+ Unregister entry point for the peripheral controller driver.
+--- a/drivers/usb/gadget/m66592-udc.c
++++ b/drivers/usb/gadget/m66592-udc.c
+@@ -1454,14 +1454,15 @@ static struct usb_ep_ops m66592_ep_ops =
+ /*-------------------------------------------------------------------------*/
+ static struct m66592 *the_controller;
+
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct m66592 *m66592 = the_controller;
+ int retval;
+
+ if (!driver
+ || driver->speed != USB_SPEED_HIGH
+- || !driver->bind
++ || !bind
+ || !driver->setup)
+ return -EINVAL;
+ if (!m66592)
+@@ -1480,7 +1481,7 @@ int usb_gadget_register_driver(struct us
+ goto error;
+ }
+
+- retval = driver->bind (&m66592->gadget);
++ retval = bind(&m66592->gadget);
+ if (retval) {
+ pr_err("bind to driver error (%d)\n", retval);
+ device_del(&m66592->gadget.dev);
+@@ -1505,7 +1506,7 @@ error:
+
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/net2280.c
++++ b/drivers/usb/gadget/net2280.c
+@@ -1929,7 +1929,8 @@ static void ep0_start (struct net2280 *d
+ * disconnect is reported. then a host may connect again, or
+ * the driver might get unbound.
+ */
+-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct net2280 *dev = the_controller;
+ int retval;
+@@ -1941,8 +1942,7 @@ int usb_gadget_register_driver (struct u
+ */
+ if (!driver
+ || driver->speed != USB_SPEED_HIGH
+- || !driver->bind
+- || !driver->setup)
++ || !bind || !driver->setup)
+ return -EINVAL;
+ if (!dev)
+ return -ENODEV;
+@@ -1957,7 +1957,7 @@ int usb_gadget_register_driver (struct u
+ driver->driver.bus = NULL;
+ dev->driver = driver;
+ dev->gadget.dev.driver = &driver->driver;
+- retval = driver->bind (&dev->gadget);
++ retval = bind(&dev->gadget);
+ if (retval) {
+ DEBUG (dev, "bind to driver %s --> %d\n",
+ driver->driver.name, retval);
+@@ -1993,7 +1993,7 @@ err_unbind:
+ dev->driver = NULL;
+ return retval;
+ }
+-EXPORT_SYMBOL (usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ static void
+ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
+--- a/drivers/usb/gadget/omap_udc.c
++++ b/drivers/usb/gadget/omap_udc.c
+@@ -2102,7 +2102,8 @@ static inline int machine_without_vbus_s
+ );
+ }
+
+-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ int status = -ENODEV;
+ struct omap_ep *ep;
+@@ -2114,8 +2115,7 @@ int usb_gadget_register_driver (struct u
+ if (!driver
+ // FIXME if otg, check: driver->is_otg
+ || driver->speed < USB_SPEED_FULL
+- || !driver->bind
+- || !driver->setup)
++ || !bind || !driver->setup)
+ return -EINVAL;
+
+ spin_lock_irqsave(&udc->lock, flags);
+@@ -2145,7 +2145,7 @@ int usb_gadget_register_driver (struct u
+ if (udc->dc_clk != NULL)
+ omap_udc_enable_clock(1);
+
+- status = driver->bind (&udc->gadget);
++ status = bind(&udc->gadget);
+ if (status) {
+ DBG("bind to %s --> %d\n", driver->driver.name, status);
+ udc->gadget.dev.driver = NULL;
+@@ -2186,7 +2186,7 @@ done:
+ omap_udc_enable_clock(0);
+ return status;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/printer.c
++++ b/drivers/usb/gadget/printer.c
+@@ -1543,7 +1543,6 @@ static struct usb_gadget_driver printer_
+ .speed = DEVSPEED,
+
+ .function = (char *) driver_desc,
+- .bind = printer_bind,
+ .unbind = printer_unbind,
+
+ .setup = printer_setup,
+@@ -1579,11 +1578,11 @@ init(void)
+ return status;
+ }
+
+- status = usb_gadget_register_driver(&printer_driver);
++ status = usb_gadget_probe_driver(&printer_driver, printer_bind);
+ if (status) {
+ class_destroy(usb_gadget_class);
+ unregister_chrdev_region(g_printer_devno, 1);
+- DBG(dev, "usb_gadget_register_driver %x\n", status);
++ DBG(dev, "usb_gadget_probe_driver %x\n", status);
+ }
+
+ return status;
+--- a/drivers/usb/gadget/pxa25x_udc.c
++++ b/drivers/usb/gadget/pxa25x_udc.c
+@@ -1280,14 +1280,15 @@ static void udc_enable (struct pxa25x_ud
+ * disconnect is reported. then a host may connect again, or
+ * the driver might get unbound.
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct pxa25x_udc *dev = the_controller;
+ int retval;
+
+ if (!driver
+ || driver->speed < USB_SPEED_FULL
+- || !driver->bind
++ || !bind
+ || !driver->disconnect
+ || !driver->setup)
+ return -EINVAL;
+@@ -1308,7 +1309,7 @@ fail:
+ dev->gadget.dev.driver = NULL;
+ return retval;
+ }
+- retval = driver->bind(&dev->gadget);
++ retval = bind(&dev->gadget);
+ if (retval) {
+ DMSG("bind to driver %s --> error %d\n",
+ driver->driver.name, retval);
+@@ -1338,7 +1339,7 @@ fail:
+ bind_fail:
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ static void
+ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
+--- a/drivers/usb/gadget/pxa27x_udc.c
++++ b/drivers/usb/gadget/pxa27x_udc.c
+@@ -1792,8 +1792,9 @@ static void udc_enable(struct pxa_udc *u
+ }
+
+ /**
+- * usb_gadget_register_driver - Register gadget driver
++ * usb_gadget_probe_driver - Register gadget driver
+ * @driver: gadget driver
++ * @bind: bind function
+ *
+ * When a driver is successfully registered, it will receive control requests
+ * including set_configuration(), which enables non-control requests. Then
+@@ -1805,12 +1806,13 @@ static void udc_enable(struct pxa_udc *u
+ *
+ * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct pxa_udc *udc = the_controller;
+ int retval;
+
+- if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind
++ if (!driver || driver->speed < USB_SPEED_FULL || !bind
+ || !driver->disconnect || !driver->setup)
+ return -EINVAL;
+ if (!udc)
+@@ -1828,7 +1830,7 @@ int usb_gadget_register_driver(struct us
+ dev_err(udc->dev, "device_add error %d\n", retval);
+ goto add_fail;
+ }
+- retval = driver->bind(&udc->gadget);
++ retval = bind(&udc->gadget);
+ if (retval) {
+ dev_err(udc->dev, "bind to driver %s --> error %d\n",
+ driver->driver.name, retval);
+@@ -1859,7 +1861,7 @@ add_fail:
+ udc->gadget.dev.driver = NULL;
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+
+ /**
+--- a/drivers/usb/gadget/r8a66597-udc.c
++++ b/drivers/usb/gadget/r8a66597-udc.c
+@@ -1405,14 +1405,15 @@ static struct usb_ep_ops r8a66597_ep_ops
+ /*-------------------------------------------------------------------------*/
+ static struct r8a66597 *the_controller;
+
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct r8a66597 *r8a66597 = the_controller;
+ int retval;
+
+ if (!driver
+ || driver->speed != USB_SPEED_HIGH
+- || !driver->bind
++ || !bind
+ || !driver->setup)
+ return -EINVAL;
+ if (!r8a66597)
+@@ -1431,7 +1432,7 @@ int usb_gadget_register_driver(struct us
+ goto error;
+ }
+
+- retval = driver->bind(&r8a66597->gadget);
++ retval = bind(&r8a66597->gadget);
+ if (retval) {
+ printk(KERN_ERR "bind to driver error (%d)\n", retval);
+ device_del(&r8a66597->gadget.dev);
+@@ -1456,7 +1457,7 @@ error:
+
+ return retval;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2523,7 +2523,8 @@ static int s3c_hsotg_corereset(struct s3
+ return 0;
+ }
+
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct s3c_hsotg *hsotg = our_hsotg;
+ int ret;
+@@ -2543,7 +2544,7 @@ int usb_gadget_register_driver(struct us
+ dev_err(hsotg->dev, "%s: bad speed\n", __func__);
+ }
+
+- if (!driver->bind || !driver->setup) {
++ if (!bind || !driver->setup) {
+ dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
+ return -EINVAL;
+ }
+@@ -2562,7 +2563,7 @@ int usb_gadget_register_driver(struct us
+ goto err;
+ }
+
+- ret = driver->bind(&hsotg->gadget);
++ ret = bind(&hsotg->gadget);
+ if (ret) {
+ dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name);
+
+@@ -2687,7 +2688,7 @@ err:
+ hsotg->gadget.dev.driver = NULL;
+ return ret;
+ }
+-EXPORT_SYMBOL(usb_gadget_register_driver);
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ {
+--- a/drivers/usb/gadget/s3c2410_udc.c
++++ b/drivers/usb/gadget/s3c2410_udc.c
+@@ -1632,15 +1632,15 @@ static void s3c2410_udc_enable(struct s3
+ }
+
+ /*
+- * usb_gadget_register_driver
++ * usb_gadget_probe_driver
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ struct s3c2410_udc *udc = the_controller;
+ int retval;
+
+- dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n",
+- driver->driver.name);
++ dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name);
+
+ /* Sanity checks */
+ if (!udc)
+@@ -1649,10 +1649,9 @@ int usb_gadget_register_driver(struct us
+ if (udc->driver)
+ return -EBUSY;
+
+- if (!driver->bind || !driver->setup
+- || driver->speed < USB_SPEED_FULL) {
++ if (!bind || !driver->setup || driver->speed < USB_SPEED_FULL) {
+ printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
+- driver->bind, driver->setup, driver->speed);
++ bind, driver->setup, driver->speed);
+ return -EINVAL;
+ }
+ #if defined(MODULE)
+@@ -1675,7 +1674,7 @@ int usb_gadget_register_driver(struct us
+ dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n",
+ driver->driver.name);
+
+- if ((retval = driver->bind (&udc->gadget)) != 0) {
++ if ((retval = bind(&udc->gadget)) != 0) {
+ device_del(&udc->gadget.dev);
+ goto register_error;
+ }
+@@ -1690,6 +1689,7 @@ register_error:
+ udc->gadget.dev.driver = NULL;
+ return retval;
+ }
++EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+ /*
+ * usb_gadget_unregister_driver
+@@ -2049,7 +2049,6 @@ static void __exit udc_exit(void)
+ }
+
+ EXPORT_SYMBOL(usb_gadget_unregister_driver);
+-EXPORT_SYMBOL(usb_gadget_register_driver);
+
+ module_init(udc_init);
+ module_exit(udc_exit);
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1696,9 +1696,11 @@ void musb_gadget_cleanup(struct musb *mu
+ * -ENOMEM no memeory to perform the operation
+ *
+ * @param driver the gadget driver
++ * @param bind the driver's bind function
+ * @return <0 if error, 0 if everything is fine
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *))
+ {
+ int retval;
+ unsigned long flags;
+@@ -1706,8 +1708,7 @@ int usb_gadget_register_driver(struct us
+
+ if (!driver
+ || driver->speed != USB_SPEED_HIGH
+- || !driver->bind
+- || !driver->setup)
++ || !bind || !driver->setup)
+ return -EINVAL;
+
+ /* driver must be initialized to support peripheral mode */
+@@ -1735,7 +1736,7 @@ int usb_gadget_register_driver(struct us
+ spin_unlock_irqrestore(&musb->lock, flags);
+
+ if (retval == 0) {
+- retval = driver->bind(&musb->g);
++ retval = bind(&musb->g);
+ if (retval != 0) {
+ DBG(3, "bind to driver %s failed --> %d\n",
+ driver->driver.name, retval);
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -705,11 +705,6 @@ static inline int usb_gadget_disconnect(
+ * struct usb_gadget_driver - driver for usb 'slave' devices
+ * @function: String describing the gadget's function
+ * @speed: Highest speed the driver handles.
+- * @bind: Invoked when the driver is bound to a gadget, usually
+- * after registering the driver.
+- * At that point, ep0 is fully initialized, and ep_list holds
+- * the currently-available endpoints.
+- * Called in a context that permits sleeping.
+ * @setup: Invoked for ep0 control requests that aren't handled by
+ * the hardware level driver. Most calls must be handled by
+ * the gadget driver, including descriptor and configuration
+@@ -774,7 +769,6 @@ static inline int usb_gadget_disconnect(
+ struct usb_gadget_driver {
+ char *function;
+ enum usb_device_speed speed;
+- int (*bind)(struct usb_gadget *);
+ void (*unbind)(struct usb_gadget *);
+ int (*setup)(struct usb_gadget *,
+ const struct usb_ctrlrequest *);
+@@ -798,17 +792,19 @@ struct usb_gadget_driver {
+ */
+
+ /**
+- * usb_gadget_register_driver - register a gadget driver
+- * @driver:the driver being registered
++ * usb_gadget_probe_driver - probe a gadget driver
++ * @driver: the driver being registered
++ * @bind: the driver's bind callback
+ * Context: can sleep
+ *
+ * Call this in your gadget driver's module initialization function,
+ * to tell the underlying usb controller driver about your driver.
+- * The driver's bind() function will be called to bind it to a
+- * gadget before this registration call returns. It's expected that
+- * the bind() functions will be in init sections.
++ * The @bind() function will be called to bind it to a gadget before this
++ * registration call returns. It's expected that the @bind() function will
++ * be in init sections.
+ */
+-int usb_gadget_register_driver(struct usb_gadget_driver *driver);
++int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
++ int (*bind)(struct usb_gadget *));
+
+ /**
+ * usb_gadget_unregister_driver - unregister a gadget driver
diff --git a/usb/usb-gadget-functionfs-code-cleanup.patch b/usb/usb-gadget-functionfs-code-cleanup.patch
new file mode 100644
index 00000000000000..04e5d9f3d41761
--- /dev/null
+++ b/usb/usb-gadget-functionfs-code-cleanup.patch
@@ -0,0 +1,208 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:10:32 2010
+Date: Thu, 12 Aug 2010 17:43:48 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: gadget: functionfs: code cleanup
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <4addd8199cfd6a2aa582904cd6efa01bc77a5290.1281625724.git.m.nazarewicz@samsung.com>
+
+This patch removes some of the string registration from the
+FunctionFS Gadget as composite layer can handle the
+iManufacturer and iProduct for us.
+
+It also removes some of the module parameters which were
+redundant as well as changes the name of others to better much
+the module parameter of the composite layer.
+
+Other then that, it also fixes formatting of multiline comments
+to match the coding style.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -52,9 +52,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_AUTHOR("Michal Nazarewicz");
+ MODULE_LICENSE("GPL");
+
+-
+-static unsigned short gfs_vendor_id = 0x1d6b; /* Linux Foundation */
+-static unsigned short gfs_product_id = 0x0105; /* FunctionFS Gadget */
++#define GFS_VENDOR_ID 0x1d6b /* Linux Foundation */
++#define GFS_PRODUCT_ID 0x0105 /* FunctionFS Gadget */
+
+ static struct usb_device_descriptor gfs_dev_desc = {
+ .bLength = sizeof gfs_dev_desc,
+@@ -63,29 +62,16 @@ static struct usb_device_descriptor gfs_dev_desc = {
+ .bcdUSB = cpu_to_le16(0x0200),
+ .bDeviceClass = USB_CLASS_PER_INTERFACE,
+
+- /* Vendor and product id can be overridden by module parameters. */
+- /* .idVendor = cpu_to_le16(gfs_vendor_id), */
+- /* .idProduct = cpu_to_le16(gfs_product_id), */
+- /* .bcdDevice = f(hardware) */
+- /* .iManufacturer = DYNAMIC */
+- /* .iProduct = DYNAMIC */
+- /* NO SERIAL NUMBER */
+- .bNumConfigurations = 1,
++ .idVendor = cpu_to_le16(GFS_VENDOR_ID),
++ .idProduct = cpu_to_le16(GFS_PRODUCT_ID),
+ };
+
+-#define GFS_MODULE_PARAM_DESC(name, field) \
+- MODULE_PARM_DESC(name, "Value of the " #field " field of the device descriptor sent to the host. Takes effect only prior to the user-space driver registering to the FunctionFS.")
+-
+-module_param_named(usb_class, gfs_dev_desc.bDeviceClass, byte, 0644);
+-GFS_MODULE_PARAM_DESC(usb_class, bDeviceClass);
+-module_param_named(usb_subclass, gfs_dev_desc.bDeviceSubClass, byte, 0644);
+-GFS_MODULE_PARAM_DESC(usb_subclass, bDeviceSubClass);
+-module_param_named(usb_protocol, gfs_dev_desc.bDeviceProtocol, byte, 0644);
+-GFS_MODULE_PARAM_DESC(usb_protocol, bDeviceProtocol);
+-module_param_named(usb_vendor, gfs_vendor_id, ushort, 0644);
+-GFS_MODULE_PARAM_DESC(usb_vendor, idVendor);
+-module_param_named(usb_product, gfs_product_id, ushort, 0644);
+-GFS_MODULE_PARAM_DESC(usb_product, idProduct);
++module_param_named(bDeviceClass, gfs_dev_desc.bDeviceClass, byte, 0644);
++MODULE_PARM_DESC(bDeviceClass, "USB Device class");
++module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte, 0644);
++MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass");
++module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644);
++MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol");
+
+
+
+@@ -95,8 +81,10 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = {
+ .bLength = sizeof(struct usb_otg_descriptor),
+ .bDescriptorType = USB_DT_OTG,
+
+- /* REVISIT SRP-only hardware is possible, although
+- * it would not be called "OTG" ... */
++ /*
++ * REVISIT SRP-only hardware is possible, although
++ * it would not be called "OTG" ...
++ */
+ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
+ },
+
+@@ -105,19 +93,7 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = {
+
+ /* string IDs are assigned dynamically */
+
+-enum {
+- GFS_STRING_MANUFACTURER_IDX,
+- GFS_STRING_PRODUCT_IDX,
+- GFS_STRING_FIRST_CONFIG_IDX,
+-};
+-
+-static char gfs_manufacturer[50];
+-static const char gfs_driver_desc[] = DRIVER_DESC;
+-static const char gfs_short_name[] = DRIVER_NAME;
+-
+ static struct usb_string gfs_strings[] = {
+- [GFS_STRING_MANUFACTURER_IDX].s = gfs_manufacturer,
+- [GFS_STRING_PRODUCT_IDX].s = gfs_driver_desc,
+ #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+ { .s = "FunctionFS + RNDIS" },
+ #endif
+@@ -168,11 +144,12 @@ static int gfs_unbind(struct usb_composite_dev *cdev);
+ static int gfs_do_config(struct usb_configuration *c);
+
+ static struct usb_composite_driver gfs_driver = {
+- .name = gfs_short_name,
++ .name = DRIVER_NAME,
+ .dev = &gfs_dev_desc,
+ .strings = gfs_dev_strings,
+ .bind = gfs_bind,
+ .unbind = gfs_unbind,
++ .iProduct = DRIVER_DESC,
+ };
+
+
+@@ -245,20 +222,10 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+ if (unlikely(ret < 0))
+ goto error_quick;
+
+- gfs_dev_desc.idVendor = cpu_to_le16(gfs_vendor_id);
+- gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id);
+-
+- snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s",
+- init_utsname()->sysname, init_utsname()->release,
+- cdev->gadget->name);
+-
+ ret = usb_string_ids_tab(cdev, gfs_strings);
+ if (unlikely(ret < 0))
+ goto error;
+
+- gfs_dev_desc.iManufacturer = gfs_strings[GFS_STRING_MANUFACTURER_IDX].id;
+- gfs_dev_desc.iProduct = gfs_strings[GFS_STRING_PRODUCT_IDX].id;
+-
+ ret = functionfs_bind(gfs_ffs_data, cdev);
+ if (unlikely(ret < 0))
+ goto error;
+@@ -266,9 +233,8 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+ for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
+ struct gfs_configuration *c = gfs_configurations + i;
+
+- ret = GFS_STRING_FIRST_CONFIG_IDX + i;
+- c->c.label = gfs_strings[ret].s;
+- c->c.iConfiguration = gfs_strings[ret].id;
++ c->c.label = gfs_strings[i].s;
++ c->c.iConfiguration = gfs_strings[i].id;
+ c->c.bind = gfs_do_config;
+ c->c.bConfigurationValue = 1 + i;
+ c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER;
+@@ -293,13 +259,14 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+ {
+ ENTER();
+
+- /* We may have been called in an error recovery frem
++ /*
++ * We may have been called in an error recovery from
+ * composite_bind() after gfs_unbind() failure so we need to
+ * check if gfs_ffs_data is not NULL since gfs_bind() handles
+ * all error recovery itself. I'd rather we werent called
+ * from composite on orror recovery, but what you're gonna
+- * do...? */
+-
++ * do...?
++ */
+ if (gfs_ffs_data) {
+ gether_cleanup();
+ functionfs_unbind(gfs_ffs_data);
+@@ -334,14 +301,16 @@ static int gfs_do_config(struct usb_configuration *c)
+ if (unlikely(ret < 0))
+ return ret;
+
+- /* After previous do_configs there may be some invalid
++ /*
++ * After previous do_configs there may be some invalid
+ * pointers in c->interface array. This happens every time
+ * a user space function with fewer interfaces than a user
+ * space function that was run before the new one is run. The
+ * compasit's set_config() assumes that if there is no more
+ * then MAX_CONFIG_INTERFACES interfaces in a configuration
+ * then there is a NULL pointer after the last interface in
+- * c->interface array. We need to make sure this is true. */
++ * c->interface array. We need to make sure this is true.
++ */
+ if (c->next_interface_id < ARRAY_SIZE(c->interface))
+ c->interface[c->next_interface_id] = NULL;
+
+@@ -350,10 +319,12 @@ static int gfs_do_config(struct usb_configuration *c)
+
+
+ #ifdef CONFIG_USB_FUNCTIONFS_ETH
++
+ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+ {
+ return can_support_ecm(c->cdev->gadget)
+ ? ecm_bind_config(c, ethaddr)
+ : geth_bind_config(c, ethaddr);
+ }
++
+ #endif
+--
+1.7.1
+
diff --git a/usb/usb-gadget-g_ffs-fixed-vendor-and-product-id.patch b/usb/usb-gadget-g_ffs-fixed-vendor-and-product-id.patch
new file mode 100644
index 00000000000000..bef147e236c5d8
--- /dev/null
+++ b/usb/usb-gadget-g_ffs-fixed-vendor-and-product-id.patch
@@ -0,0 +1,35 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:09:08 2010
+Date: Thu, 12 Aug 2010 17:43:45 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: gadget: g_ffs: fixed vendor and product ID
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <313ee18ecf53fb8f1c040656b697de869f0c0856.1281625724.git.m.nazarewicz@samsung.com>
+
+This patch fixes the vendor and product ID the gadget uses
+by replacing the temporary IDs that were used during
+development (which should never get into mainline) with
+proper IDs.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/g_ffs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -53,8 +53,8 @@ MODULE_AUTHOR("Michal Nazarewicz");
+ MODULE_LICENSE("GPL");
+
+
+-static unsigned short gfs_vendor_id = 0x0525; /* XXX NetChip */
+-static unsigned short gfs_product_id = 0xa4ac; /* XXX */
++static unsigned short gfs_vendor_id = 0x1d6b; /* Linux Foundation */
++static unsigned short gfs_product_id = 0x0105; /* FunctionFS Gadget */
+
+ static struct usb_device_descriptor gfs_dev_desc = {
+ .bLength = sizeof gfs_dev_desc,
diff --git a/usb/usb-gadget-g_multi-fixed-vendor-and-product-id.patch b/usb/usb-gadget-g_multi-fixed-vendor-and-product-id.patch
new file mode 100644
index 00000000000000..4836d9a7590e66
--- /dev/null
+++ b/usb/usb-gadget-g_multi-fixed-vendor-and-product-id.patch
@@ -0,0 +1,35 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:08:49 2010
+Date: Thu, 12 Aug 2010 17:43:44 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: gadget: g_multi: fixed vendor and product ID
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <76f0f5732bfbbb36d50baf05ecdd12bec3396275.1281625724.git.m.nazarewicz@samsung.com>
+
+This patch fixes the vendor and product ID the gadget uses
+by replacing the temporary IDs that were used during
+development (which should never get into mainline) with
+proper IDs.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/multi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -74,8 +74,8 @@ MODULE_LICENSE("GPL");
+
+ /***************************** Device Descriptor ****************************/
+
+-#define MULTI_VENDOR_NUM 0x0525 /* XXX NetChip */
+-#define MULTI_PRODUCT_NUM 0xa4ab /* XXX */
++#define MULTI_VENDOR_NUM 0x1d6b /* Linux Foundation */
++#define MULTI_PRODUCT_NUM 0x0104 /* Multifunction Composite Gadget */
+
+
+ enum {
diff --git a/usb/usb-gadget-g_multi-moved-strings-handling-code-to-composite.patch b/usb/usb-gadget-g_multi-moved-strings-handling-code-to-composite.patch
new file mode 100644
index 00000000000000..433d82f3c25463
--- /dev/null
+++ b/usb/usb-gadget-g_multi-moved-strings-handling-code-to-composite.patch
@@ -0,0 +1,78 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:13:51 2010
+Date: Thu, 12 Aug 2010 17:43:49 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: gadget: g_multi: moved strings handling code to composite
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <9737a711d395932c8803511ba581722d46be5292.1281625724.git.m.nazarewicz@samsung.com>
+
+This patch removes some of the string registration from the
+Multifunction Composite Gadget as composite layer can handle
+the iManufacturer and iProduct for us.
+
+This also adds the "needs_serial" so that composite layer will
+issue a warning if user space fails to provide the iSerialNumber
+module parameter.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/multi.c | 19 +++----------------
+ 1 file changed, 3 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -121,8 +121,6 @@ static const struct usb_descriptor_heade
+
+
+ enum {
+- MULTI_STRING_MANUFACTURER_IDX,
+- MULTI_STRING_PRODUCT_IDX,
+ #ifdef CONFIG_USB_G_MULTI_RNDIS
+ MULTI_STRING_RNDIS_CONFIG_IDX,
+ #endif
+@@ -131,11 +129,7 @@ enum {
+ #endif
+ };
+
+-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
+@@ -314,20 +308,11 @@ static int __ref multi_bind(struct usb_c
+ device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
+ }
+
+- /* allocate string descriptor numbers */
+- snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+- init_utsname()->sysname, init_utsname()->release,
+- gadget->name);
+-
++ /* allocate string IDs */
+ status = usb_string_ids_tab(cdev, strings_dev);
+ if (unlikely(status < 0))
+ goto fail2;
+
+- device_desc.iManufacturer =
+- strings_dev[MULTI_STRING_MANUFACTURER_IDX].id;
+- device_desc.iProduct =
+- strings_dev[MULTI_STRING_PRODUCT_IDX].id;
+-
+ /* register configurations */
+ status = rndis_config_register(cdev);
+ if (unlikely(status < 0))
+@@ -370,6 +355,8 @@ static struct usb_composite_driver multi
+ .strings = dev_strings,
+ .bind = multi_bind,
+ .unbind = __exit_p(multi_unbind),
++ .iProduct = DRIVER_DESC,
++ .needs_serial = 1,
+ };
+
+
diff --git a/usb/usb-gadget-mass_storage-moved-strings-handling-code.patch b/usb/usb-gadget-mass_storage-moved-strings-handling-code.patch
new file mode 100644
index 00000000000000..bd3174235b69a4
--- /dev/null
+++ b/usb/usb-gadget-mass_storage-moved-strings-handling-code.patch
@@ -0,0 +1,152 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:12:48 2010
+Date: Thu, 12 Aug 2010 17:43:47 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: gadget: mass_storage: moved strings handling code to composite
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <f2f6babb8b593d5c6f6141604bd647658d59f124.1281625724.git.m.nazarewicz@samsung.com>
+
+This patch removes string registration from the Mass Storage
+Gadget. With recent changes to the composite framework, all
+that we need is handled by the composite layer. This means
+composite registers a string ID for manufacturer and product.
+
+This also adds the "needs_serial" so that composite layer will
+issue a warning if user space fails to provide the iSerialNumber
+module parameter.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/mass_storage.c | 72 +++-----------------------------------
+ 1 file changed, 6 insertions(+), 66 deletions(-)
+
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -75,10 +75,6 @@ static struct usb_device_descriptor msg_
+ /* Vendor and product id can be overridden by module parameters. */
+ .idVendor = cpu_to_le16(FSG_VENDOR_ID),
+ .idProduct = cpu_to_le16(FSG_PRODUCT_ID),
+- /* .bcdDevice = f(hardware) */
+- /* .iManufacturer = DYNAMIC */
+- /* .iProduct = DYNAMIC */
+- /* NO SERIAL NUMBER */
+ .bNumConfigurations = 1,
+ };
+
+@@ -86,7 +82,8 @@ static struct usb_otg_descriptor otg_des
+ .bLength = sizeof otg_descriptor,
+ .bDescriptorType = USB_DT_OTG,
+
+- /* REVISIT SRP-only hardware is possible, although
++ /*
++ * REVISIT SRP-only hardware is possible, although
+ * it would not be called "OTG" ...
+ */
+ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
+@@ -98,33 +95,6 @@ static const struct usb_descriptor_heade
+ };
+
+
+-/* string IDs are assigned dynamically */
+-
+-#define STRING_MANUFACTURER_IDX 0
+-#define STRING_PRODUCT_IDX 1
+-#define STRING_CONFIGURATION_IDX 2
+-
+-static char manufacturer[50];
+-
+-static struct usb_string strings_dev[] = {
+- [STRING_MANUFACTURER_IDX].s = manufacturer,
+- [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+- [STRING_CONFIGURATION_IDX].s = "Self Powered",
+- { } /* end of list */
+-};
+-
+-static struct usb_gadget_strings stringtab_dev = {
+- .language = 0x0409, /* en-us */
+- .strings = strings_dev,
+-};
+-
+-static struct usb_gadget_strings *dev_strings[] = {
+- &stringtab_dev,
+- NULL,
+-};
+-
+-
+-
+ /****************************** Configurations ******************************/
+
+ static struct fsg_module_parameters mod_data = {
+@@ -173,52 +143,22 @@ static struct usb_configuration msg_conf
+ .label = "Linux File-Backed Storage",
+ .bind = msg_do_config,
+ .bConfigurationValue = 1,
+- /* .iConfiguration = DYNAMIC */
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+ };
+
+
+-
+ /****************************** Gadget Bind ******************************/
+
+-
+ static int __ref msg_bind(struct usb_composite_dev *cdev)
+ {
+- struct usb_gadget *gadget = cdev->gadget;
+ int status;
+
+- /* Allocate string descriptor numbers ... note that string
+- * contents can be overridden by the composite_dev glue.
+- */
+-
+- /* device descriptor strings: manufacturer, product */
+- snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+- init_utsname()->sysname, init_utsname()->release,
+- gadget->name);
+- status = usb_string_id(cdev);
+- if (status < 0)
+- return status;
+- strings_dev[STRING_MANUFACTURER_IDX].id = status;
+- msg_device_desc.iManufacturer = status;
+-
+- status = usb_string_id(cdev);
+- if (status < 0)
+- return status;
+- strings_dev[STRING_PRODUCT_IDX].id = status;
+- msg_device_desc.iProduct = status;
+-
+- status = usb_string_id(cdev);
+- if (status < 0)
+- return status;
+- strings_dev[STRING_CONFIGURATION_IDX].id = status;
+- msg_config_driver.iConfiguration = status;
+-
+- /* register our second configuration */
+ status = usb_add_config(cdev, &msg_config_driver);
+ if (status < 0)
+ return status;
+
+- dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
++ dev_info(&cdev->gadget->dev,
++ DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+ set_bit(0, &msg_registered);
+ return 0;
+ }
+@@ -226,12 +166,12 @@ static int __ref msg_bind(struct usb_com
+
+ /****************************** Some noise ******************************/
+
+-
+ static struct usb_composite_driver msg_driver = {
+ .name = "g_mass_storage",
+ .dev = &msg_device_desc,
+- .strings = dev_strings,
+ .bind = msg_bind,
++ .iProduct = DRIVER_DESC,
++ .needs_serial = 1,
+ };
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/usb/usb-gadget-mass_storage-optional-scsi-write-fua-bit.patch b/usb/usb-gadget-mass_storage-optional-scsi-write-fua-bit.patch
new file mode 100644
index 00000000000000..b62d7633d44e61
--- /dev/null
+++ b/usb/usb-gadget-mass_storage-optional-scsi-write-fua-bit.patch
@@ -0,0 +1,104 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:11:09 2010
+Date: Thu, 12 Aug 2010 17:43:51 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: usb: gadget: mass_storage: optional SCSI WRITE FUA bit
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org,
+ Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
+Message-id: <550ddf8273d87cb418dd5716cbec906e74aa03d4.1281625724.git.m.nazarewicz@samsung.com>
+
+The nofua parameter (optionally ignore SCSI WRITE FUA) was added
+to the File Storage Gadget some time ago. This patch adds the
+same functionality to the Mass Storage Function.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Cc: Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/f_mass_storage.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -73,6 +73,8 @@
+ * being removable.
+ * ->cdrom Flag specifying that LUN shall be reported as
+ * being a CD-ROM.
++ * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12)
++ * commands for this LUN shall be ignored.
+ *
+ * lun_name_format A printf-like format for names of the LUN
+ * devices. This determines how the
+@@ -127,6 +129,8 @@
+ * Default true, boolean for removable media.
+ * cdrom=b[,b...] Default false, boolean for whether to emulate
+ * a CD-ROM drive.
++ * nofua=b[,b...] Default false, booleans for ignore FUA flag
++ * in SCSI WRITE(10,12) commands
+ * luns=N Default N = number of filenames, number of
+ * LUNs to support.
+ * stall Default determined according to the type of
+@@ -409,6 +413,7 @@ struct fsg_config {
+ char ro;
+ char removable;
+ char cdrom;
++ char nofua;
+ } luns[FSG_MAX_LUNS];
+
+ const char *lun_name_format;
+@@ -887,7 +892,7 @@ static int do_write(struct fsg_common *c
+ curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+ return -EINVAL;
+ }
+- if (common->cmnd[1] & 0x08) { /* FUA */
++ if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
+ spin_lock(&curlun->filp->f_lock);
+ curlun->filp->f_flags |= O_SYNC;
+ spin_unlock(&curlun->filp->f_lock);
+@@ -2662,6 +2667,7 @@ static int fsg_main_thread(void *common_
+
+ /* Write permission is checked per LUN in store_*() functions. */
+ static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
++static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
+ static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
+
+
+@@ -2768,6 +2774,9 @@ static struct fsg_common *fsg_common_ini
+ rc = device_create_file(&curlun->dev, &dev_attr_file);
+ if (rc)
+ goto error_luns;
++ rc = device_create_file(&curlun->dev, &dev_attr_nofua);
++ if (rc)
++ goto error_luns;
+
+ if (lcfg->filename) {
+ rc = fsg_lun_open(curlun, lcfg->filename);
+@@ -2911,6 +2920,7 @@ static void fsg_common_release(struct kr
+
+ /* In error recovery common->nluns may be zero. */
+ for (; i; --i, ++lun) {
++ device_remove_file(&lun->dev, &dev_attr_nofua);
+ device_remove_file(&lun->dev, &dev_attr_ro);
+ device_remove_file(&lun->dev, &dev_attr_file);
+ fsg_lun_close(lun);
+@@ -3069,8 +3079,10 @@ struct fsg_module_parameters {
+ int ro[FSG_MAX_LUNS];
+ int removable[FSG_MAX_LUNS];
+ int cdrom[FSG_MAX_LUNS];
++ int nofua[FSG_MAX_LUNS];
+
+ unsigned int file_count, ro_count, removable_count, cdrom_count;
++ unsigned int nofua_count;
+ unsigned int luns; /* nluns */
+ int stall; /* can_stall */
+ };
+@@ -3096,6 +3108,8 @@ struct fsg_module_parameters {
+ "true to simulate removable media"); \
+ _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \
+ "true to simulate CD-ROM instead of disk"); \
++ _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \
++ "true to ignore SCSI WRITE(10,12) FUA bit"); \
+ _FSG_MODULE_PARAM(prefix, params, luns, uint, \
+ "number of LUNs"); \
+ _FSG_MODULE_PARAM(prefix, params, stall, bool, \
diff --git a/usb/usb-gadget-storage-remove-nofua-file-when-unbinding.patch b/usb/usb-gadget-storage-remove-nofua-file-when-unbinding.patch
new file mode 100644
index 00000000000000..27f8d203ad35d0
--- /dev/null
+++ b/usb/usb-gadget-storage-remove-nofua-file-when-unbinding.patch
@@ -0,0 +1,31 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 14:10:52 2010
+Date: Thu, 12 Aug 2010 17:43:50 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: usb: gadget: storage: remove nofua file when unbinding
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org,
+ Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
+Message-id: <f07e8ff5f36d5893e62764b9e372da0cc305a2b5.1281625724.git.m.nazarewicz@samsung.com>
+
+The dev_attr_nofua file was created during fsg_bind() but
+was never removed. Made it a bit more symmetrical and added
+code to remove the file in fsg_unbind().
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Acked-by: Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/file_storage.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -3178,6 +3178,7 @@ static void /* __init_or_exit */ fsg_unb
+ for (i = 0; i < fsg->nluns; ++i) {
+ curlun = &fsg->luns[i];
+ if (curlun->registered) {
++ device_remove_file(&curlun->dev, &dev_attr_nofua);
+ device_remove_file(&curlun->dev, &dev_attr_ro);
+ device_remove_file(&curlun->dev, &dev_attr_file);
+ fsg_lun_close(curlun);
diff --git a/usb/usb-revert-usb-gadget-section-mismatch-warning-fixed.patch b/usb/usb-revert-usb-gadget-section-mismatch-warning-fixed.patch
new file mode 100644
index 00000000000000..2c2e41371a664b
--- /dev/null
+++ b/usb/usb-revert-usb-gadget-section-mismatch-warning-fixed.patch
@@ -0,0 +1,258 @@
+From m.nazarewicz@samsung.com Wed Sep 1 14:14:21 2010
+Date: Thu, 12 Aug 2010 17:43:52 +0200
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Subject: USB: Revert "USB: gadget: section mismatch warning fixed"
+To: linux-usb@vger.kernel.org, Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org
+Message-id: <ad117de19af4733f113c8631e53556cc308dbf06.1281625724.git.m.nazarewicz@samsung.com>
+
+This reverts a commit which proposed an invalid solution
+for a section mismatch. Next 3 commits will fix it correctly.
+
+Conflicts:
+
+ drivers/usb/gadget/mass_storage.c
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/audio.c | 4 ++--
+ drivers/usb/gadget/cdc2.c | 4 ++--
+ drivers/usb/gadget/ether.c | 6 +++---
+ drivers/usb/gadget/f_loopback.c | 4 ++--
+ drivers/usb/gadget/f_sourcesink.c | 2 +-
+ drivers/usb/gadget/file_storage.c | 2 +-
+ drivers/usb/gadget/gmidi.c | 2 +-
+ drivers/usb/gadget/hid.c | 4 ++--
+ drivers/usb/gadget/mass_storage.c | 4 ++--
+ drivers/usb/gadget/printer.c | 2 +-
+ drivers/usb/gadget/serial.c | 4 ++--
+ drivers/usb/gadget/webcam.c | 4 ++--
+ drivers/usb/gadget/zero.c | 2 +-
+ 13 files changed, 22 insertions(+), 22 deletions(-)
+
+--- a/drivers/usb/gadget/audio.c
++++ b/drivers/usb/gadget/audio.c
+@@ -89,7 +89,7 @@ static const struct usb_descriptor_heade
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref audio_do_config(struct usb_configuration *c)
++static int __init audio_do_config(struct usb_configuration *c)
+ {
+ /* FIXME alloc iConfiguration string, set it in c->strings */
+
+@@ -113,7 +113,7 @@ static struct usb_configuration audio_co
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref audio_bind(struct usb_composite_dev *cdev)
++static int __init audio_bind(struct usb_composite_dev *cdev)
+ {
+ int gcnum;
+ int status;
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -129,7 +129,7 @@ static u8 hostaddr[ETH_ALEN];
+ /*
+ * We _always_ have both CDC ECM and CDC ACM functions.
+ */
+-static int __ref cdc_do_config(struct usb_configuration *c)
++static int __init cdc_do_config(struct usb_configuration *c)
+ {
+ int status;
+
+@@ -159,7 +159,7 @@ static struct usb_configuration cdc_conf
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref cdc_bind(struct usb_composite_dev *cdev)
++static int __init cdc_bind(struct usb_composite_dev *cdev)
+ {
+ int gcnum;
+ struct usb_gadget *gadget = cdev->gadget;
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -237,7 +237,7 @@ static u8 hostaddr[ETH_ALEN];
+ * the first one present. That's to make Microsoft's drivers happy,
+ * and to follow DOCSIS 1.0 (cable modem standard).
+ */
+-static int __ref rndis_do_config(struct usb_configuration *c)
++static int __init rndis_do_config(struct usb_configuration *c)
+ {
+ /* FIXME alloc iConfiguration string, set it in c->strings */
+
+@@ -270,7 +270,7 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM m
+ /*
+ * We _always_ have an ECM, CDC Subset, or EEM configuration.
+ */
+-static int __ref eth_do_config(struct usb_configuration *c)
++static int __init eth_do_config(struct usb_configuration *c)
+ {
+ /* FIXME alloc iConfiguration string, set it in c->strings */
+
+@@ -297,7 +297,7 @@ static struct usb_configuration eth_conf
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref eth_bind(struct usb_composite_dev *cdev)
++static int __init eth_bind(struct usb_composite_dev *cdev)
+ {
+ int gcnum;
+ struct usb_gadget *gadget = cdev->gadget;
+--- a/drivers/usb/gadget/f_loopback.c
++++ b/drivers/usb/gadget/f_loopback.c
+@@ -324,7 +324,7 @@ static void loopback_disable(struct usb_
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref loopback_bind_config(struct usb_configuration *c)
++static int __init loopback_bind_config(struct usb_configuration *c)
+ {
+ struct f_loopback *loop;
+ int status;
+@@ -346,7 +346,7 @@ static int __ref loopback_bind_config(st
+ return status;
+ }
+
+-static struct usb_configuration loopback_driver = {
++static struct usb_configuration loopback_driver = {
+ .label = "loopback",
+ .strings = loopback_strings,
+ .bind = loopback_bind_config,
+--- a/drivers/usb/gadget/f_sourcesink.c
++++ b/drivers/usb/gadget/f_sourcesink.c
+@@ -404,7 +404,7 @@ static void sourcesink_disable(struct us
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref sourcesink_bind_config(struct usb_configuration *c)
++static int __init sourcesink_bind_config(struct usb_configuration *c)
+ {
+ struct f_sourcesink *ss;
+ int status;
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -3348,7 +3348,7 @@ fill_serial:
+ }
+
+
+-static int __ref fsg_bind(struct usb_gadget *gadget)
++static int __init fsg_bind(struct usb_gadget *gadget)
+ {
+ struct fsg_dev *fsg = the_fsg;
+ int rc;
+--- a/drivers/usb/gadget/gmidi.c
++++ b/drivers/usb/gadget/gmidi.c
+@@ -1157,7 +1157,7 @@ fail:
+ /*
+ * Creates an output endpoint, and initializes output ports.
+ */
+-static int __ref gmidi_bind(struct usb_gadget *gadget)
++static int __init gmidi_bind(struct usb_gadget *gadget)
+ {
+ struct gmidi_device *dev;
+ struct usb_ep *in_ep, *out_ep;
+--- a/drivers/usb/gadget/hid.c
++++ b/drivers/usb/gadget/hid.c
+@@ -127,7 +127,7 @@ static struct usb_gadget_strings *dev_st
+
+ /****************************** Configurations ******************************/
+
+-static int __ref do_config(struct usb_configuration *c)
++static int __init do_config(struct usb_configuration *c)
+ {
+ struct hidg_func_node *e;
+ int func = 0, status = 0;
+@@ -156,7 +156,7 @@ static struct usb_configuration config_d
+
+ /****************************** Gadget Bind ******************************/
+
+-static int __ref hid_bind(struct usb_composite_dev *cdev)
++static int __init hid_bind(struct usb_composite_dev *cdev)
+ {
+ struct usb_gadget *gadget = cdev->gadget;
+ struct list_head *tmp;
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -111,7 +111,7 @@ static int msg_thread_exits(struct fsg_c
+ return 0;
+ }
+
+-static int __ref msg_do_config(struct usb_configuration *c)
++static int __init msg_do_config(struct usb_configuration *c)
+ {
+ static const struct fsg_operations ops = {
+ .thread_exits = msg_thread_exits,
+@@ -149,7 +149,7 @@ static struct usb_configuration msg_conf
+
+ /****************************** Gadget Bind ******************************/
+
+-static int __ref msg_bind(struct usb_composite_dev *cdev)
++static int __init msg_bind(struct usb_composite_dev *cdev)
+ {
+ int status;
+
+--- a/drivers/usb/gadget/printer.c
++++ b/drivers/usb/gadget/printer.c
+@@ -1347,7 +1347,7 @@ printer_unbind(struct usb_gadget *gadget
+ set_gadget_data(gadget, NULL);
+ }
+
+-static int __ref
++static int __init
+ printer_bind(struct usb_gadget *gadget)
+ {
+ struct printer_dev *dev;
+--- a/drivers/usb/gadget/serial.c
++++ b/drivers/usb/gadget/serial.c
+@@ -137,7 +137,7 @@ MODULE_PARM_DESC(n_ports, "number of por
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref serial_bind_config(struct usb_configuration *c)
++static int __init serial_bind_config(struct usb_configuration *c)
+ {
+ unsigned i;
+ int status = 0;
+@@ -161,7 +161,7 @@ static struct usb_configuration serial_c
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+ };
+
+-static int __ref gs_bind(struct usb_composite_dev *cdev)
++static int __init gs_bind(struct usb_composite_dev *cdev)
+ {
+ int gcnum;
+ struct usb_gadget *gadget = cdev->gadget;
+--- a/drivers/usb/gadget/webcam.c
++++ b/drivers/usb/gadget/webcam.c
+@@ -308,7 +308,7 @@ static const struct uvc_descriptor_heade
+ * USB configuration
+ */
+
+-static int __ref
++static int __init
+ webcam_config_bind(struct usb_configuration *c)
+ {
+ return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls,
+@@ -330,7 +330,7 @@ webcam_unbind(struct usb_composite_dev *
+ return 0;
+ }
+
+-static int __ref
++static int __init
+ webcam_bind(struct usb_composite_dev *cdev)
+ {
+ int ret;
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -264,7 +264,7 @@ static void zero_resume(struct usb_compo
+
+ /*-------------------------------------------------------------------------*/
+
+-static int __ref zero_bind(struct usb_composite_dev *cdev)
++static int __init zero_bind(struct usb_composite_dev *cdev)
+ {
+ int gcnum;
+ struct usb_gadget *gadget = cdev->gadget;