aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-06-25 11:28:30 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-25 11:28:30 -0700
commitc23087dad116bf3266e64605046361d985e7f493 (patch)
treeac685016c567fbe4c13a74d11413379554ee27f7
parente1e6cbaa48b0a9cc53d33cf1a9b5ffd9166bcc6f (diff)
downloadpatches-c23087dad116bf3266e64605046361d985e7f493.tar.gz
usb and staging and a firmware patch
-rw-r--r--driver-core/firmware-update-hotplug-script-remove-sysfs-files.patch50
-rw-r--r--series6
-rw-r--r--staging.current/staging-rtl8192s_usb-remove-duplicate-device-id.patch26
-rw-r--r--staging.current/staging-rtl8192u_usb-add-lg-device-id-043e-7a01.patch30
-rw-r--r--usb.current/usb-gadget-f_mass_storage-fixed-fs-descriptors-not-being-updated.patch106
-rw-r--r--usb.current/usb-gadget-f_mass_storage-stale-common-fsg-value-bug-fix.patch326
-rw-r--r--usb/usb-gadget-f_mass_storage-added-eject-callback.patch16
-rw-r--r--usb/usb-gadget-f_mass_storage-dead-code-removed.patch2
-rw-r--r--usb/usb-gadget-f_mass_storage-fsg_add-renamed-to-fsg_bind_config.patch4
-rw-r--r--usb/usb-gadget-g_fs-code-cleanup.patch358
10 files changed, 913 insertions, 11 deletions
diff --git a/driver-core/firmware-update-hotplug-script-remove-sysfs-files.patch b/driver-core/firmware-update-hotplug-script-remove-sysfs-files.patch
new file mode 100644
index 00000000000000..32be7849cfcc8c
--- /dev/null
+++ b/driver-core/firmware-update-hotplug-script-remove-sysfs-files.patch
@@ -0,0 +1,50 @@
+From magnus.damm@gmail.com Fri Jun 25 11:20:37 2010
+From: Magnus Damm <magnus.damm@gmail.com>
+Date: Fri, 25 Jun 2010 17:55:11 +0900
+Subject: firmware: Update hotplug script
+To: linux-kernel@vger.kernel.org
+Cc: Greg Kroah-Hartman <gregkh@suse.de>, Randy Dunlap <rdunlap@xenotime.net>, linux-doc@vger.kernel.org, Johannes Berg <johannes.berg@intel.com>, Dmitry Torokhov <dtor@mail.ru>, Marcel Holtmann <marcel@holtmann.org>, Magnus Damm <magnus.damm@gmail.com>, Ming Lei <tom.leiming@gmail.com>
+Message-ID: <20100625085511.30949.41045.sendpatchset@t400s>
+
+
+From: Magnus Damm <damm@opensource.se>
+
+Update the in-kernel hotplug example script to work
+properly with recent kernels. Without this fix the
+script may load the firmware twice - both at "add"
+and "remove" time.
+
+The second load only triggers in the case when multiple
+firmware images are used. A good example is the b43
+driver which does not work properly without this fix.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/firmware_class/hotplug-script | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/Documentation/firmware_class/hotplug-script
++++ b/Documentation/firmware_class/hotplug-script
+@@ -6,11 +6,12 @@
+
+ HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
+
+-echo 1 > /sys/$DEVPATH/loading
+-cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
+-echo 0 > /sys/$DEVPATH/loading
+-
+-# To cancel the load in case of error:
+-#
+-# echo -1 > /sys/$DEVPATH/loading
+-#
++if [ "$SUBSYSTEM" == "firmware" -a "$ACTION" == "add" ]; then
++ if [ -f $HOTPLUG_FW_DIR/$FIRMWARE ]; then
++ echo 1 > /sys/$DEVPATH/loading
++ cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
++ echo 0 > /sys/$DEVPATH/loading
++ else
++ echo -1 > /sys/$DEVPATH/loading
++ fi
++fi
diff --git a/series b/series
index 4b8d83d7d7c77e..b6912308e01116 100644
--- a/series
+++ b/series
@@ -37,6 +37,8 @@ usb.current/usb-musb_core-make-disconnect-and-suspend-interrupts-work-again.patc
usb.current/usb-musb-make-non-omap-platforms-build-with-config_pm-y.patch
usb.current/usb-musb-fix-blackfin-ulpi-stubs.patch
usb.current/usb-musb-enable-the-maximum-supported-burst-mode-for-dma.patch
+usb.current/usb-gadget-f_mass_storage-fixed-fs-descriptors-not-being-updated.patch
+usb.current/usb-gadget-f_mass_storage-stale-common-fsg-value-bug-fix.patch
#################################
# Staging patches for 2.6.35
@@ -55,6 +57,8 @@ staging.current/staging-rtl8192su-remove-device-ids.patch
staging.current/staging-rtl8192su-add-device-ids.patch
staging.current/staging-comedi-fix-read-past-end-of-array-in-cb_pcidda_attach.patch
staging.current/staging-rt2870-add-device-id-for-zyxel-nwd-270n.patch
+staging.current/staging-rtl8192s_usb-remove-duplicate-device-id.patch
+staging.current/staging-rtl8192u_usb-add-lg-device-id-043e-7a01.patch
#####################################################################
# Stuff to be merged after 2.6.35 is out
@@ -75,6 +79,7 @@ driver-core/firmware-loader-embed-device-into-firmware_priv-structure.patch
driver-core/driver-core-use-kmemdup-in-platform_device_add_resources.patch
driver-core/driver-core-reduce-duplicated-code-for-platform_device-creation.patch
driver-core/driver-core-move-platform-device-creation-helpers-to-.init.text-if-module-n.patch
+driver-core/firmware-update-hotplug-script-remove-sysfs-files.patch
#####################################
# TTY patches for after 2.6.35 is out
@@ -180,6 +185,7 @@ usb/usb-gadget-composite-added-disconnect-callback.patch
usb/usb-gadget-f_mass_storage-added-eject-callback.patch
usb/usb-gadget-section-mismatch-warning-fixed.patch
usb/usb-convert-usb_hcd-bitfields-into-atomic-flags.patch
+usb/usb-gadget-g_fs-code-cleanup.patch
# staging stuff is now in the staging-next tree on git.kernel.org
diff --git a/staging.current/staging-rtl8192s_usb-remove-duplicate-device-id.patch b/staging.current/staging-rtl8192s_usb-remove-duplicate-device-id.patch
new file mode 100644
index 00000000000000..52fba2b037f6bf
--- /dev/null
+++ b/staging.current/staging-rtl8192s_usb-remove-duplicate-device-id.patch
@@ -0,0 +1,26 @@
+From ben@decadent.org.uk Thu Jun 24 17:35:06 2010
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 25 Jun 2010 01:35:01 +0100
+Subject: Staging: rtl8192s_usb: Remove duplicate device ID
+To: Greg KH <greg@kroah.com>
+Cc: devel@driverdev.osuosl.org, Florian Schilhabel <florian.c.schilhabel@googlemail.com>, Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>, Guy Sheffer <guysoft@gmail.com>
+Message-ID: <1277426101.26161.168.camel@localhost>
+
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rtl8192su/r8192U_core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/staging/rtl8192su/r8192U_core.c
++++ b/drivers/staging/rtl8192su/r8192U_core.c
+@@ -134,7 +134,6 @@ static const struct usb_device_id rtl819
+ {USB_DEVICE(0x0E66, 0x0016)},
+ {USB_DEVICE(0x0b05, 0x1786)},
+ /* these are not in the official list */
+- {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
+ {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
+ {}
+ };
diff --git a/staging.current/staging-rtl8192u_usb-add-lg-device-id-043e-7a01.patch b/staging.current/staging-rtl8192u_usb-add-lg-device-id-043e-7a01.patch
new file mode 100644
index 00000000000000..9b8749d1303f63
--- /dev/null
+++ b/staging.current/staging-rtl8192u_usb-add-lg-device-id-043e-7a01.patch
@@ -0,0 +1,30 @@
+From ben@decadent.org.uk Thu Jun 24 17:35:53 2010
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 25 Jun 2010 01:35:49 +0100
+Subject: Staging: rtl8192u_usb: Add LG device ID 043e:7a01
+To: Greg KH <greg@kroah.com>
+Cc: devel@driverdev.osuosl.org, Florian Schilhabel <florian.c.schilhabel@googlemail.com>, Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>, Guy Sheffer <guysoft@gmail.com>
+Message-ID: <1277426149.26161.169.camel@localhost>
+
+
+Add another device ID as listed in the vendor driver version
+0003.0825.2009.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rtl8192u/r8192U_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/staging/rtl8192u/r8192U_core.c
++++ b/drivers/staging/rtl8192u/r8192U_core.c
+@@ -121,6 +121,8 @@ static const struct usb_device_id rtl819
+ {USB_DEVICE(0x2001, 0x3301)},
+ /* Zinwell */
+ {USB_DEVICE(0x5a57, 0x0290)},
++ /* LG */
++ {USB_DEVICE(0x043e, 0x7a01)},
+ {}
+ };
+
diff --git a/usb.current/usb-gadget-f_mass_storage-fixed-fs-descriptors-not-being-updated.patch b/usb.current/usb-gadget-f_mass_storage-fixed-fs-descriptors-not-being-updated.patch
new file mode 100644
index 00000000000000..053d59cd4fc6d1
--- /dev/null
+++ b/usb.current/usb-gadget-f_mass_storage-fixed-fs-descriptors-not-being-updated.patch
@@ -0,0 +1,106 @@
+From m.nazarewicz@samsung.com Fri Jun 25 11:23:02 2010
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Date: Fri, 25 Jun 2010 16:29:26 +0200
+Subject: USB: gadget: f_mass_storage: fixed fs descriptors not being updated
+To: linux-usb@vger.kernel.org
+Cc: David Brownell <dbrownell@users.sourceforge.net>, Greg KH <greg@kroah.com>, Kyungmin Park <kyungmin.park@samsung.com>, Marek Szyprowski <m.szyprowski@samsung.com>, linux-kernel@vger.kernel.org, Dries Van Puymbroeck <Dries.VanPuymbroeck@dekimo.com>
+Message-ID: <195465048ef0e96371d42a9bc754a2f35a03bccd.1277461024.git.m.nazarewicz@samsung.com>
+
+
+The full speed descriptors were copied to the usb_function structure
+in the fsg_bind_config function before call to the usb_ep_autoconfig.
+The usb_ep_autoconfig was called in fsg_bind using the original
+descriptors. In effect copied descriptors were not updated.
+
+This patch changes the copy full speed descriptors after the call to
+usb_op_autoconfig is performed. This way, copied full speed
+descriptors have updated values.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Reported-by: Dries Van Puymbroeck <Dries.VanPuymbroeck@dekimo.com>
+Tested-by: Dries Van Puymbroeck <Dries.VanPuymbroeck@dekimo.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/f_mass_storage.c | 34 ++++++++++++----------------------
+ 1 file changed, 12 insertions(+), 22 deletions(-)
+
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2970,7 +2970,6 @@ static int fsg_bind(struct usb_configura
+ {
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct usb_gadget *gadget = c->cdev->gadget;
+- int rc;
+ int i;
+ struct usb_ep *ep;
+
+@@ -2996,6 +2995,11 @@ static int fsg_bind(struct usb_configura
+ ep->driver_data = fsg->common; /* claim the endpoint */
+ fsg->bulk_out = ep;
+
++ /* Copy descriptors */
++ f->descriptors = usb_copy_descriptors(fsg_fs_function);
++ if (unlikely(!f->descriptors))
++ return -ENOMEM;
++
+ if (gadget_is_dualspeed(gadget)) {
+ /* Assume endpoint addresses are the same for both speeds */
+ fsg_hs_bulk_in_desc.bEndpointAddress =
+@@ -3003,16 +3007,17 @@ static int fsg_bind(struct usb_configura
+ fsg_hs_bulk_out_desc.bEndpointAddress =
+ fsg_fs_bulk_out_desc.bEndpointAddress;
+ f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
+- if (unlikely(!f->hs_descriptors))
++ if (unlikely(!f->hs_descriptors)) {
++ usb_free_descriptors(f->descriptors);
+ return -ENOMEM;
++ }
+ }
+
+ return 0;
+
+ autoconf_fail:
+ ERROR(fsg, "unable to autoconfigure all endpoints\n");
+- rc = -ENOTSUPP;
+- return rc;
++ return -ENOTSUPP;
+ }
+
+
+@@ -3036,11 +3041,6 @@ static int fsg_add(struct usb_composite_
+
+ fsg->function.name = FSG_DRIVER_DESC;
+ fsg->function.strings = fsg_strings_array;
+- fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function);
+- if (unlikely(!fsg->function.descriptors)) {
+- rc = -ENOMEM;
+- goto error_free_fsg;
+- }
+ fsg->function.bind = fsg_bind;
+ fsg->function.unbind = fsg_unbind;
+ fsg->function.setup = fsg_setup;
+@@ -3056,19 +3056,9 @@ static int fsg_add(struct usb_composite_
+
+ rc = usb_add_function(c, &fsg->function);
+ if (unlikely(rc))
+- goto error_free_all;
+-
+- fsg_common_get(fsg->common);
+- return 0;
+-
+-error_free_all:
+- usb_free_descriptors(fsg->function.descriptors);
+- /* fsg_bind() might have copied those; or maybe not? who cares
+- * -- free it just in case. */
+- usb_free_descriptors(fsg->function.hs_descriptors);
+-error_free_fsg:
+- kfree(fsg);
+-
++ kfree(fsg);
++ else
++ fsg_common_get(fsg->common);
+ return rc;
+ }
+
diff --git a/usb.current/usb-gadget-f_mass_storage-stale-common-fsg-value-bug-fix.patch b/usb.current/usb-gadget-f_mass_storage-stale-common-fsg-value-bug-fix.patch
new file mode 100644
index 00000000000000..2e2d400d9aaca8
--- /dev/null
+++ b/usb.current/usb-gadget-f_mass_storage-stale-common-fsg-value-bug-fix.patch
@@ -0,0 +1,326 @@
+From m.nazarewicz@samsung.com Fri Jun 25 11:23:22 2010
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Date: Fri, 25 Jun 2010 16:29:28 +0200
+Subject: USB: gadget: f_mass_storage: stale common->fsg value bug fix
+To: linux-usb@vger.kernel.org
+Cc: David Brownell <dbrownell@users.sourceforge.net>, Greg KH <greg@kroah.com>, Kyungmin Park <kyungmin.park@samsung.com>, Marek Szyprowski <m.szyprowski@samsung.com>, linux-kernel@vger.kernel.org
+Message-ID: <023d27cf18cf64018bb96f0913b0e61bade38c39.1277475111.git.m.nazarewicz@samsung.com>
+
+
+On fsg_unbind the common->fsg pointer was not NULLed if the
+unbound fsg_dev instance was the current one. As an effect,
+the incorrect pointer was preserved in all further operations
+which caused do_set_interface to reference an invalid region.
+
+This commit fixes this by raising an exception in fsg_bind
+which will change the common->fsg pointer. This also requires
+an wait queue so that the thread in fsg_bind can wait till the
+worker thread handles the exception.
+
+This commit removes also a config and new_config fields of
+fsg_common as they are no longer needed since fsg can be
+used to determine whether function is active or not.
+
+Moreover, this commit removes possible race condition where
+the fsg field was modified in both the worker thread and
+form various other contexts. This is fixed by replacing
+prev_fsg with new_fsg. At this point, fsg is assigned only
+in worker thread.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/f_mass_storage.c | 162 +++++++++++++-----------------------
+ 1 file changed, 62 insertions(+), 100 deletions(-)
+
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -321,8 +321,8 @@ struct fsg_dev;
+ /* Data shared by all the FSG instances. */
+ struct fsg_common {
+ struct usb_gadget *gadget;
+- struct fsg_dev *fsg;
+- struct fsg_dev *prev_fsg;
++ struct fsg_dev *fsg, *new_fsg;
++ wait_queue_head_t fsg_wait;
+
+ /* filesem protects: backing files in use */
+ struct rw_semaphore filesem;
+@@ -351,7 +351,6 @@ struct fsg_common {
+ enum fsg_state state; /* For exception handling */
+ unsigned int exception_req_tag;
+
+- u8 config, new_config;
+ enum data_direction data_dir;
+ u32 data_size;
+ u32 data_size_from_cmnd;
+@@ -595,7 +594,7 @@ static int fsg_setup(struct usb_function
+ u16 w_value = le16_to_cpu(ctrl->wValue);
+ u16 w_length = le16_to_cpu(ctrl->wLength);
+
+- if (!fsg->common->config)
++ if (!fsg_is_set(fsg->common))
+ return -EOPNOTSUPP;
+
+ switch (ctrl->bRequest) {
+@@ -2303,24 +2302,20 @@ static int alloc_request(struct fsg_comm
+ return -ENOMEM;
+ }
+
+-/*
+- * Reset interface setting and re-init endpoint state (toggle etc).
+- * Call with altsetting < 0 to disable the interface. The only other
+- * available altsetting is 0, which enables the interface.
+- */
+-static int do_set_interface(struct fsg_common *common, int altsetting)
++/* Reset interface setting and re-init endpoint state (toggle etc). */
++static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
+ {
+- int rc = 0;
+- int i;
+- const struct usb_endpoint_descriptor *d;
++ const struct usb_endpoint_descriptor *d;
++ struct fsg_dev *fsg;
++ int i, rc = 0;
+
+ if (common->running)
+ DBG(common, "reset interface\n");
+
+ reset:
+ /* Deallocate the requests */
+- if (common->prev_fsg) {
+- struct fsg_dev *fsg = common->prev_fsg;
++ if (common->fsg) {
++ fsg = common->fsg;
+
+ for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+ struct fsg_buffhd *bh = &common->buffhds[i];
+@@ -2345,88 +2340,53 @@ reset:
+ fsg->bulk_out_enabled = 0;
+ }
+
+- common->prev_fsg = 0;
++ common->fsg = NULL;
++ wake_up(&common->fsg_wait);
+ }
+
+ common->running = 0;
+- if (altsetting < 0 || rc != 0)
++ if (!new_fsg || rc)
+ return rc;
+
+- DBG(common, "set interface %d\n", altsetting);
++ common->fsg = new_fsg;
++ fsg = common->fsg;
++
++ /* Enable the endpoints */
++ d = fsg_ep_desc(common->gadget,
++ &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
++ rc = enable_endpoint(common, fsg->bulk_in, d);
++ if (rc)
++ goto reset;
++ fsg->bulk_in_enabled = 1;
++
++ d = fsg_ep_desc(common->gadget,
++ &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
++ rc = enable_endpoint(common, fsg->bulk_out, d);
++ if (rc)
++ goto reset;
++ fsg->bulk_out_enabled = 1;
++ common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
++ clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
++
++ /* Allocate the requests */
++ for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
++ struct fsg_buffhd *bh = &common->buffhds[i];
+
+- if (fsg_is_set(common)) {
+- struct fsg_dev *fsg = common->fsg;
+- common->prev_fsg = common->fsg;
+-
+- /* Enable the endpoints */
+- d = fsg_ep_desc(common->gadget,
+- &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
+- rc = enable_endpoint(common, fsg->bulk_in, d);
++ rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+ if (rc)
+ goto reset;
+- fsg->bulk_in_enabled = 1;
+-
+- d = fsg_ep_desc(common->gadget,
+- &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
+- rc = enable_endpoint(common, fsg->bulk_out, d);
++ rc = alloc_request(common, fsg->bulk_out, &bh->outreq);
+ if (rc)
+ goto reset;
+- fsg->bulk_out_enabled = 1;
+- common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
+- clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+-
+- /* Allocate the requests */
+- for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+- struct fsg_buffhd *bh = &common->buffhds[i];
+-
+- rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+- if (rc)
+- goto reset;
+- rc = alloc_request(common, fsg->bulk_out, &bh->outreq);
+- if (rc)
+- goto reset;
+- bh->inreq->buf = bh->outreq->buf = bh->buf;
+- bh->inreq->context = bh->outreq->context = bh;
+- bh->inreq->complete = bulk_in_complete;
+- bh->outreq->complete = bulk_out_complete;
+- }
+-
+- common->running = 1;
+- for (i = 0; i < common->nluns; ++i)
+- common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+- return rc;
+- } else {
+- return -EIO;
++ bh->inreq->buf = bh->outreq->buf = bh->buf;
++ bh->inreq->context = bh->outreq->context = bh;
++ bh->inreq->complete = bulk_in_complete;
++ bh->outreq->complete = bulk_out_complete;
+ }
+-}
+-
+-
+-/*
+- * Change our operational configuration. This code must agree with the code
+- * that returns config descriptors, and with interface altsetting code.
+- *
+- * It's also responsible for power management interactions. Some
+- * configurations might not work with our current power sources.
+- * For now we just assume the gadget is always self-powered.
+- */
+-static int do_set_config(struct fsg_common *common, u8 new_config)
+-{
+- int rc = 0;
+
+- /* Disable the single interface */
+- if (common->config != 0) {
+- DBG(common, "reset config\n");
+- common->config = 0;
+- rc = do_set_interface(common, -1);
+- }
+-
+- /* Enable the interface */
+- if (new_config != 0) {
+- common->config = new_config;
+- rc = do_set_interface(common, 0);
+- if (rc != 0)
+- common->config = 0; /* Reset on errors */
+- }
++ common->running = 1;
++ for (i = 0; i < common->nluns; ++i)
++ common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+ return rc;
+ }
+
+@@ -2437,9 +2397,7 @@ static int do_set_config(struct fsg_comm
+ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+ {
+ struct fsg_dev *fsg = fsg_from_func(f);
+- fsg->common->prev_fsg = fsg->common->fsg;
+- fsg->common->fsg = fsg;
+- fsg->common->new_config = 1;
++ fsg->common->new_fsg = fsg;
+ raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+ return 0;
+ }
+@@ -2447,9 +2405,7 @@ static int fsg_set_alt(struct usb_functi
+ static void fsg_disable(struct usb_function *f)
+ {
+ struct fsg_dev *fsg = fsg_from_func(f);
+- fsg->common->prev_fsg = fsg->common->fsg;
+- fsg->common->fsg = fsg;
+- fsg->common->new_config = 0;
++ fsg->common->new_fsg = NULL;
+ raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+ }
+
+@@ -2459,19 +2415,17 @@ static void fsg_disable(struct usb_funct
+ static void handle_exception(struct fsg_common *common)
+ {
+ siginfo_t info;
+- int sig;
+ int i;
+ struct fsg_buffhd *bh;
+ enum fsg_state old_state;
+- u8 new_config;
+ struct fsg_lun *curlun;
+ unsigned int exception_req_tag;
+- int rc;
+
+ /* Clear the existing signals. Anything but SIGUSR1 is converted
+ * into a high-priority EXIT exception. */
+ for (;;) {
+- sig = dequeue_signal_lock(current, &current->blocked, &info);
++ int sig =
++ dequeue_signal_lock(current, &current->blocked, &info);
+ if (!sig)
+ break;
+ if (sig != SIGUSR1) {
+@@ -2482,7 +2436,7 @@ static void handle_exception(struct fsg_
+ }
+
+ /* Cancel all the pending transfers */
+- if (fsg_is_set(common)) {
++ if (likely(common->fsg)) {
+ for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+ bh = &common->buffhds[i];
+ if (bh->inreq_busy)
+@@ -2523,7 +2477,6 @@ static void handle_exception(struct fsg_
+ common->next_buffhd_to_fill = &common->buffhds[0];
+ common->next_buffhd_to_drain = &common->buffhds[0];
+ exception_req_tag = common->exception_req_tag;
+- new_config = common->new_config;
+ old_state = common->state;
+
+ if (old_state == FSG_STATE_ABORT_BULK_OUT)
+@@ -2573,12 +2526,12 @@ static void handle_exception(struct fsg_
+ break;
+
+ case FSG_STATE_CONFIG_CHANGE:
+- rc = do_set_config(common, new_config);
++ do_set_interface(common, common->new_fsg);
+ break;
+
+ case FSG_STATE_EXIT:
+ case FSG_STATE_TERMINATED:
+- do_set_config(common, 0); /* Free resources */
++ do_set_interface(common, NULL); /* Free resources */
+ spin_lock_irq(&common->lock);
+ common->state = FSG_STATE_TERMINATED; /* Stop the thread */
+ spin_unlock_irq(&common->lock);
+@@ -2863,6 +2816,7 @@ buffhds_first_it:
+ goto error_release;
+ }
+ init_completion(&common->thread_notifier);
++ init_waitqueue_head(&common->fsg_wait);
+ #undef OR
+
+
+@@ -2957,9 +2911,17 @@ static void fsg_common_release(struct kr
+ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+ struct fsg_dev *fsg = fsg_from_func(f);
++ struct fsg_common *common = fsg->common;
+
+ DBG(fsg, "unbind\n");
+- fsg_common_put(fsg->common);
++ if (fsg->common->fsg == fsg) {
++ fsg->common->new_fsg = NULL;
++ raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
++ /* FIXME: make interruptible or killable somehow? */
++ wait_event(common->fsg_wait, common->fsg != fsg);
++ }
++
++ fsg_common_put(common);
+ usb_free_descriptors(fsg->function.descriptors);
+ usb_free_descriptors(fsg->function.hs_descriptors);
+ kfree(fsg);
diff --git a/usb/usb-gadget-f_mass_storage-added-eject-callback.patch b/usb/usb-gadget-f_mass_storage-added-eject-callback.patch
index d659df76f5cec3..0f91194de7a046 100644
--- a/usb/usb-gadget-f_mass_storage-added-eject-callback.patch
+++ b/usb/usb-gadget-f_mass_storage-added-eject-callback.patch
@@ -58,7 +58,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* Data shared by all the FSG instances. */
-@@ -369,8 +390,8 @@ struct fsg_common {
+@@ -368,8 +389,8 @@ struct fsg_common {
struct completion thread_notifier;
struct task_struct *thread_task;
@@ -69,7 +69,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* Gadget's private data. */
void *private_data;
-@@ -394,12 +415,8 @@ struct fsg_config {
+@@ -393,12 +414,8 @@ struct fsg_config {
const char *lun_name_format;
const char *thread_name;
@@ -84,7 +84,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* Gadget's private data. */
void *private_data;
-@@ -435,6 +452,7 @@ static inline int __fsg_is_set(struct fs
+@@ -434,6 +451,7 @@ static inline int __fsg_is_set(struct fs
if (common->fsg)
return 1;
ERROR(common, "common->fsg is NULL in %s at %u\n", func, line);
@@ -92,7 +92,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return 0;
}
-@@ -1393,43 +1411,55 @@ static int do_start_stop(struct fsg_comm
+@@ -1392,43 +1410,55 @@ static int do_start_stop(struct fsg_comm
} else if (!curlun->removable) {
curlun->sense_data = SS_INVALID_COMMAND;
return -EINVAL;
@@ -175,7 +175,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
-@@ -2654,7 +2684,8 @@ static int fsg_main_thread(void *common_
+@@ -2607,7 +2637,8 @@ static int fsg_main_thread(void *common_
common->thread_task = NULL;
spin_unlock_irq(&common->lock);
@@ -185,7 +185,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
struct fsg_lun *curlun = common->luns;
unsigned i = common->nluns;
-@@ -2730,6 +2761,7 @@ static struct fsg_common *fsg_common_ini
+@@ -2683,6 +2714,7 @@ static struct fsg_common *fsg_common_ini
common->free_storage_on_release = 0;
}
@@ -193,7 +193,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
common->private_data = cfg->private_data;
common->gadget = gadget;
-@@ -2851,7 +2883,6 @@ buffhds_first_it:
+@@ -2804,7 +2836,6 @@ buffhds_first_it:
/* Tell the thread to start working */
@@ -201,7 +201,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
common->thread_task =
kthread_create(fsg_main_thread, common,
OR(cfg->thread_name, "file-storage"));
-@@ -3148,8 +3179,8 @@ fsg_config_from_params(struct fsg_config
+@@ -3100,8 +3131,8 @@ fsg_config_from_params(struct fsg_config
cfg->product_name = 0;
cfg->release = 0xffff;
diff --git a/usb/usb-gadget-f_mass_storage-dead-code-removed.patch b/usb/usb-gadget-f_mass_storage-dead-code-removed.patch
index 25433abd9f3fcd..6b3c52efab12dc 100644
--- a/usb/usb-gadget-f_mass_storage-dead-code-removed.patch
+++ b/usb/usb-gadget-f_mass_storage-dead-code-removed.patch
@@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
struct fsg_buffhd *next_buffhd_to_fill;
struct fsg_buffhd *next_buffhd_to_drain;
-@@ -624,8 +623,6 @@ static int fsg_setup(struct usb_function
+@@ -623,8 +622,6 @@ static int fsg_setup(struct usb_function
/* Respond with data/status */
req->length = min((u16)1, w_length);
diff --git a/usb/usb-gadget-f_mass_storage-fsg_add-renamed-to-fsg_bind_config.patch b/usb/usb-gadget-f_mass_storage-fsg_add-renamed-to-fsg_bind_config.patch
index d361f1f9bb74fd..0cbb4578dda2cf 100644
--- a/usb/usb-gadget-f_mass_storage-fsg_add-renamed-to-fsg_bind_config.patch
+++ b/usb/usb-gadget-f_mass_storage-fsg_add-renamed-to-fsg_bind_config.patch
@@ -23,7 +23,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
-@@ -3023,9 +3023,9 @@ static struct usb_gadget_strings *fsg_st
+@@ -2990,9 +2990,9 @@ static struct usb_gadget_strings *fsg_st
NULL,
};
@@ -36,7 +36,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
{
struct fsg_dev *fsg;
int rc;
-@@ -3072,6 +3072,13 @@ error_free_fsg:
+@@ -3024,6 +3024,13 @@ static int fsg_add(struct usb_composite_
return rc;
}
diff --git a/usb/usb-gadget-g_fs-code-cleanup.patch b/usb/usb-gadget-g_fs-code-cleanup.patch
new file mode 100644
index 00000000000000..3dc7363f30f6c5
--- /dev/null
+++ b/usb/usb-gadget-g_fs-code-cleanup.patch
@@ -0,0 +1,358 @@
+From m.nazarewicz@samsung.com Fri Jun 25 11:23:58 2010
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Date: Fri, 25 Jun 2010 16:29:27 +0200
+Subject: USB: gadget: g_fs: code cleanup
+To: linux-usb@vger.kernel.org
+Cc: David Brownell <dbrownell@users.sourceforge.net>, Kyungmin Park <kyungmin.park@samsung.com>, Marek Szyprowski <m.szyprowski@samsung.com>, linux-kernel@vger.kernel.org
+Message-ID: <b51342e058f33dc9d78491c1209d0e86d09ed9db.1276170819.git.m.nazarewicz@samsung.com>
+
+
+This commit cleans the g_fs gadget hopefully making it more
+readable. This is achieved by usage of the usb_string_ids_tab()
+function for batch string IDs registration as well as
+generalising configuration so that a single routine is
+used to add each configuration and bind interfaces. As an
+effect, the code is shorter and has fewer #ifdefs.
+
+Moreover, in some circumstances previous code #defined
+CONFIG_USB_FUNCTIONFS_GENERIC macro to prevent a situation
+where gadget with no configurations is built. This code removes
+the #define form source code and achieves the same effect using
+select in Kconfig.
+
+This patch also changes wording and names of the Kconfig options.
+
+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/Kconfig | 23 +++--
+ drivers/usb/gadget/g_ffs.c | 174 ++++++++++++---------------------------------
+ 2 files changed, 60 insertions(+), 137 deletions(-)
+
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -714,6 +714,7 @@ config USB_GADGETFS
+ config USB_FUNCTIONFS
+ tristate "Function Filesystem (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
++ select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
+ help
+ The Function Filesystem (FunctioFS) lets one create USB
+ composite functions in user space in the same way as GadgetFS
+@@ -722,31 +723,31 @@ config USB_FUNCTIONFS
+ implemented in kernel space (for instance Ethernet, serial or
+ mass storage) and other are implemented in user space.
+
++ If you say "y" or "m" here you will be able what kind of
++ configurations the gadget will provide.
++
+ Say "y" to link the driver statically, or "m" to build
+ a dynamically linked module called "g_ffs".
+
+ config USB_FUNCTIONFS_ETH
+- bool "Include CDC ECM (Ethernet) function"
++ bool "Include configuration with CDC ECM (Ethernet)"
+ depends on USB_FUNCTIONFS && NET
+ help
+- Include an CDC ECM (Ethernet) funcion in the CDC ECM (Funcion)
+- Filesystem. If you also say "y" to the RNDIS query below the
+- gadget will have two configurations.
++ Include a configuration with CDC ECM funcion (Ethernet) and the
++ Funcion Filesystem.
+
+ config USB_FUNCTIONFS_RNDIS
+- bool "Include RNDIS (Ethernet) function"
++ bool "Include configuration with RNDIS (Ethernet)"
+ depends on USB_FUNCTIONFS && NET
+ help
+- Include an RNDIS (Ethernet) funcion in the Funcion Filesystem.
+- If you also say "y" to the CDC ECM query above the gadget will
+- have two configurations.
++ Include a configuration with RNDIS funcion (Ethernet) and the Filesystem.
+
+ config USB_FUNCTIONFS_GENERIC
+ bool "Include 'pure' configuration"
+- depends on USB_FUNCTIONFS && (USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
++ depends on USB_FUNCTIONFS
+ help
+- Include a configuration with FunctionFS and no Ethernet
+- configuration.
++ Include a configuration with the Function Filesystem alone with
++ no Ethernet interface.
+
+ config USB_FILE_STORAGE
+ tristate "File-backed Storage Gadget"
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -32,12 +32,13 @@
+ # include "u_ether.c"
+
+ static u8 gfs_hostaddr[ETH_ALEN];
+-#else
+-# if !defined CONFIG_USB_FUNCTIONFS_GENERIC
+-# define CONFIG_USB_FUNCTIONFS_GENERIC
++# ifdef CONFIG_USB_FUNCTIONFS_ETH
++static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+ # endif
++#else
+ # define gether_cleanup() do { } while (0)
+ # define gether_setup(gadget, hostaddr) ((int)0)
++# define gfs_hostaddr NULL
+ #endif
+
+ #include "f_fs.c"
+@@ -107,15 +108,7 @@ static const struct usb_descriptor_heade
+ enum {
+ GFS_STRING_MANUFACTURER_IDX,
+ GFS_STRING_PRODUCT_IDX,
+-#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+- GFS_STRING_RNDIS_CONFIG_IDX,
+-#endif
+-#ifdef CONFIG_USB_FUNCTIONFS_ETH
+- GFS_STRING_ECM_CONFIG_IDX,
+-#endif
+-#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
+- GFS_STRING_GENERIC_CONFIG_IDX,
+-#endif
++ GFS_STRING_FIRST_CONFIG_IDX,
+ };
+
+ static char gfs_manufacturer[50];
+@@ -126,13 +119,13 @@ 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
+- [GFS_STRING_RNDIS_CONFIG_IDX].s = "FunctionFS + RNDIS",
++ { .s = "FunctionFS + RNDIS" },
+ #endif
+ #ifdef CONFIG_USB_FUNCTIONFS_ETH
+- [GFS_STRING_ECM_CONFIG_IDX].s = "FunctionFS + ECM",
++ { .s = "FunctionFS + ECM" },
+ #endif
+ #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
+- [GFS_STRING_GENERIC_CONFIG_IDX].s = "FunctionFS",
++ { .s = "FunctionFS" },
+ #endif
+ { } /* end of list */
+ };
+@@ -146,59 +139,33 @@ static struct usb_gadget_strings *gfs_de
+ };
+
+
+-#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+-static int gfs_do_rndis_config(struct usb_configuration *c);
+
+-static struct usb_configuration gfs_rndis_config_driver = {
+- .label = "FunctionFS + RNDIS",
+- .bind = gfs_do_rndis_config,
+- .bConfigurationValue = 1,
+- /* .iConfiguration = DYNAMIC */
+- .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+-};
+-# define gfs_add_rndis_config(cdev) \
+- usb_add_config(cdev, &gfs_rndis_config_driver)
+-#else
+-# define gfs_add_rndis_config(cdev) 0
++struct gfs_configuration {
++ struct usb_configuration c;
++ int (*eth)(struct usb_configuration *c, u8 *ethaddr);
++} gfs_configurations[] = {
++#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++ {
++ .eth = rndis_bind_config,
++ },
+ #endif
+
+-
+ #ifdef CONFIG_USB_FUNCTIONFS_ETH
+-static int gfs_do_ecm_config(struct usb_configuration *c);
+-
+-static struct usb_configuration gfs_ecm_config_driver = {
+- .label = "FunctionFS + ECM",
+- .bind = gfs_do_ecm_config,
+- .bConfigurationValue = 1,
+- /* .iConfiguration = DYNAMIC */
+- .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+-};
+-# define gfs_add_ecm_config(cdev) \
+- usb_add_config(cdev, &gfs_ecm_config_driver)
+-#else
+-# define gfs_add_ecm_config(cdev) 0
++ {
++ .eth = eth_bind_config,
++ },
+ #endif
+
+-
+ #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
+-static int gfs_do_generic_config(struct usb_configuration *c);
+-
+-static struct usb_configuration gfs_generic_config_driver = {
+- .label = "FunctionFS",
+- .bind = gfs_do_generic_config,
+- .bConfigurationValue = 2,
+- /* .iConfiguration = DYNAMIC */
+- .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
+-};
+-# define gfs_add_generic_config(cdev) \
+- usb_add_config(cdev, &gfs_generic_config_driver)
+-#else
+-# define gfs_add_generic_config(cdev) 0
++ {
++ },
+ #endif
++};
+
+
+ static int gfs_bind(struct usb_composite_dev *cdev);
+ 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,
+@@ -267,7 +234,7 @@ static int functionfs_check_dev_callback
+
+ static int gfs_bind(struct usb_composite_dev *cdev)
+ {
+- int ret;
++ int ret, i;
+
+ ENTER();
+
+@@ -284,57 +251,32 @@ static int gfs_bind(struct usb_composite
+ snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s",
+ init_utsname()->sysname, init_utsname()->release,
+ cdev->gadget->name);
+- ret = usb_string_id(cdev);
+- if (unlikely(ret < 0))
+- goto error;
+- gfs_strings[GFS_STRING_MANUFACTURER_IDX].id = ret;
+- gfs_dev_desc.iManufacturer = ret;
+
+- ret = usb_string_id(cdev);
++ ret = usb_string_ids_tab(cdev, gfs_strings);
+ if (unlikely(ret < 0))
+ goto error;
+- gfs_strings[GFS_STRING_PRODUCT_IDX].id = ret;
+- gfs_dev_desc.iProduct = ret;
+
+-#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+- ret = usb_string_id(cdev);
+- if (unlikely(ret < 0))
+- goto error;
+- gfs_strings[GFS_STRING_RNDIS_CONFIG_IDX].id = ret;
+- gfs_rndis_config_driver.iConfiguration = ret;
+-#endif
+-
+-#ifdef CONFIG_USB_FUNCTIONFS_ETH
+- ret = usb_string_id(cdev);
+- if (unlikely(ret < 0))
+- goto error;
+- gfs_strings[GFS_STRING_ECM_CONFIG_IDX].id = ret;
+- gfs_ecm_config_driver.iConfiguration = ret;
+-#endif
+-
+-#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
+- ret = usb_string_id(cdev);
+- if (unlikely(ret < 0))
+- goto error;
+- gfs_strings[GFS_STRING_GENERIC_CONFIG_IDX].id = ret;
+- gfs_generic_config_driver.iConfiguration = ret;
+-#endif
++ 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;
+
+- ret = gfs_add_rndis_config(cdev);
+- if (unlikely(ret < 0))
+- goto error_unbind;
++ for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
++ struct gfs_configuration *c = gfs_configurations + i;
+
+- ret = gfs_add_ecm_config(cdev);
+- if (unlikely(ret < 0))
+- goto error_unbind;
++ ret = GFS_STRING_FIRST_CONFIG_IDX + i;
++ c->c.label = gfs_strings[ret].s;
++ c->c.iConfiguration = gfs_strings[ret].id;
++ c->c.bind = gfs_do_config;
++ c->c.bConfigurationValue = 1 + i;
++ c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER;
+
+- ret = gfs_add_generic_config(cdev);
+- if (unlikely(ret < 0))
+- goto error_unbind;
++ ret = usb_add_config(cdev, &c->c);
++ if (unlikely(ret < 0))
++ goto error_unbind;
++ }
+
+ return 0;
+
+@@ -368,10 +310,10 @@ static int gfs_unbind(struct usb_composi
+ }
+
+
+-static int __gfs_do_config(struct usb_configuration *c,
+- int (*eth)(struct usb_configuration *c, u8 *ethaddr),
+- u8 *ethaddr)
++static int gfs_do_config(struct usb_configuration *c)
+ {
++ struct gfs_configuration *gc =
++ container_of(c, struct gfs_configuration, c);
+ int ret;
+
+ if (WARN_ON(!gfs_ffs_data))
+@@ -382,8 +324,8 @@ static int __gfs_do_config(struct usb_co
+ c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ }
+
+- if (eth) {
+- ret = eth(c, ethaddr);
++ if (gc->eth) {
++ ret = gc->eth(c, gfs_hostaddr);
+ if (unlikely(ret < 0))
+ return ret;
+ }
+@@ -406,32 +348,12 @@ static int __gfs_do_config(struct usb_co
+ return 0;
+ }
+
+-#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+-static int gfs_do_rndis_config(struct usb_configuration *c)
+-{
+- ENTER();
+-
+- return __gfs_do_config(c, rndis_bind_config, gfs_hostaddr);
+-}
+-#endif
+
+ #ifdef CONFIG_USB_FUNCTIONFS_ETH
+-static int gfs_do_ecm_config(struct usb_configuration *c)
++static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+ {
+- ENTER();
+-
+- return __gfs_do_config(c,
+- can_support_ecm(c->cdev->gadget)
+- ? ecm_bind_config : geth_bind_config,
+- gfs_hostaddr);
+-}
+-#endif
+-
+-#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
+-static int gfs_do_generic_config(struct usb_configuration *c)
+-{
+- ENTER();
+-
+- return __gfs_do_config(c, NULL, NULL);
++ return can_support_ecm(c->cdev->gadget)
++ ? ecm_bind_config(c, ethaddr)
++ : geth_bind_config(c, ethaddr);
+ }
+ #endif