2010-08-12 15:42:21

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 00/13] Various USB improvements

Andy Shevchenko has found a bug in one of my patch sent earlier so
resending everything rebased on next. This also include Uwe's and
mine patches for section mismatches with my previous approach
reverted.

This patchset contains all my patches sent earlier.

* The first two patches should be included as quickly as possible. *

Sorry for spamming but I might have less time to work on those in the
next few weeks so I just wanted to send everything I have ready for
submission.

Michal Nazarewicz (11):
USB: gadget: g_multi: fixed vendor and product ID
USB: gadget: g_ffs: fixed vendor and product ID
USB: gadget: composite: Better string override handling
USB: gadget: mass_storage: moved strings handling code to composite
USB: gadget: functionfs: code cleanup
USB: gadget: g_multi: moved strings handling code to composite
usb: gadget: storage: remove nofua file when unbinding
usb: gadget: mass_storage: optional SCSI WRITE FUA bit
Revert "USB: gadget: section mismatch warning fixed"
usb gadget: don't save bind callback in struct usb_composite_driver
init.h: add some more documentation to __ref* tags

Uwe Kleine-König (2):
usb gadget: don't save bind callback in struct usb_gadget_driver
usb gadget: don't save bind callback in struct usb_configuration

drivers/usb/gadget/amd5536udc.c | 9 ++-
drivers/usb/gadget/at91_udc.c | 11 ++--
drivers/usb/gadget/atmel_usba_udc.c | 7 +-
drivers/usb/gadget/audio.c | 10 +--
drivers/usb/gadget/cdc2.c | 10 +--
drivers/usb/gadget/ci13xxx_udc.c | 18 +++--
drivers/usb/gadget/composite.c | 128 +++++++++++++++++++++++------------
drivers/usb/gadget/dbgp.c | 3 +-
drivers/usb/gadget/dummy_hcd.c | 10 ++--
drivers/usb/gadget/ether.c | 16 ++---
drivers/usb/gadget/f_loopback.c | 7 +-
drivers/usb/gadget/f_mass_storage.c | 16 ++++-
drivers/usb/gadget/f_sourcesink.c | 5 +-
drivers/usb/gadget/file_storage.c | 6 +-
drivers/usb/gadget/fsl_qe_udc.c | 12 ++--
drivers/usb/gadget/fsl_udc_core.c | 10 ++--
drivers/usb/gadget/g_ffs.c | 91 ++++++++-----------------
drivers/usb/gadget/gmidi.c | 5 +-
drivers/usb/gadget/goku_udc.c | 9 ++-
drivers/usb/gadget/hid.c | 10 +--
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/mass_storage.c | 82 +++--------------------
drivers/usb/gadget/multi.c | 36 +++-------
drivers/usb/gadget/net2280.c | 10 ++--
drivers/usb/gadget/nokia.c | 8 +-
drivers/usb/gadget/omap_udc.c | 10 ++--
drivers/usb/gadget/printer.c | 7 +-
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/gadget/serial.c | 11 ++--
drivers/usb/gadget/webcam.c | 11 ++--
drivers/usb/gadget/zero.c | 5 +-
drivers/usb/musb/musb_gadget.c | 9 ++-
include/linux/init.h | 13 +++-
include/linux/usb/composite.h | 40 ++++++-----
include/linux/usb/gadget.h | 20 ++---
43 files changed, 350 insertions(+), 404 deletions(-)


2010-08-12 15:42:23

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 01/13] USB: gadget: g_multi: fixed vendor and product ID

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 <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/multi.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 795d762..36d67a3 100644
--- 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 {
--
1.7.1

2010-08-12 15:42:51

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 09/13] Revert "USB: gadget: section mismatch warning fixed"

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: Michał Nazarewicz <[email protected]>
---
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(-)

diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index b744ccd..a62af7b 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -89,7 +89,7 @@ static const struct usb_descriptor_header *otg_desc[] = {

/*-------------------------------------------------------------------------*/

-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_config_driver = {

/*-------------------------------------------------------------------------*/

-static int __ref audio_bind(struct usb_composite_dev *cdev)
+static int __init audio_bind(struct usb_composite_dev *cdev)
{
int gcnum;
int status;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 1f5ba2f..928137d 100644
--- 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_config_driver = {

/*-------------------------------------------------------------------------*/

-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;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 114fa02..400f803 100644
--- 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 mode");
/*
* 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_config_driver = {

/*-------------------------------------------------------------------------*/

-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;
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 4322587..e91d1b1 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -324,7 +324,7 @@ static void loopback_disable(struct usb_function *f)

/*-------------------------------------------------------------------------*/

-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(struct usb_configuration *c)
return status;
}

-static struct usb_configuration loopback_driver = {
+static struct usb_configuration loopback_driver = {
.label = "loopback",
.strings = loopback_strings,
.bind = loopback_bind_config,
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index 685d768..6d3cc44 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -404,7 +404,7 @@ static void sourcesink_disable(struct usb_function *f)

/*-------------------------------------------------------------------------*/

-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;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ab77792..aae04c2 100644
--- 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;
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 1b413a5..b7bf880 100644
--- 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;
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 735495b..7757226 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -127,7 +127,7 @@ static struct usb_gadget_strings *dev_strings[] = {

/****************************** 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_driver = {

/****************************** 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;
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 493d153..05e9bd3 100644
--- 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_common *common)
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_config_driver = {

/****************************** Gadget Bind ******************************/

-static int __ref msg_bind(struct usb_composite_dev *cdev)
+static int __init msg_bind(struct usb_composite_dev *cdev)
{
int status;

diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index cf241c3..04c7bbf 100644
--- 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;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b22eedb..f46a609 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -137,7 +137,7 @@ MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");

/*-------------------------------------------------------------------------*/

-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_config_driver = {
.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;
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index de1deb7..288d211 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -308,7 +308,7 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
* 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 *cdev)
return 0;
}

-static int __ref
+static int __init
webcam_bind(struct usb_composite_dev *cdev)
{
int ret;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index cf35392..807280d 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -264,7 +264,7 @@ static void zero_resume(struct usb_composite_dev *cdev)

/*-------------------------------------------------------------------------*/

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

2010-08-12 15:42:55

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 11/13] usb gadget: don't save bind callback in struct usb_composite_driver

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 <[email protected]>
Cc: Uwe Kleine-König <[email protected]>
---
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(-)

diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index a62af7b..5a65fbb 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -166,13 +166,12 @@ static struct usb_composite_driver audio_driver = {
.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);

diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 928137d..1f2a9b1 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -245,7 +245,6 @@ static struct usb_composite_driver cdc_driver = {
.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);

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 0d3f4b7..6f3b5fb 100644
--- 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.
@@ -1109,7 +1110,7 @@ static int composite_bind(struct usb_gadget *gadget)
* 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;

@@ -1221,8 +1222,12 @@ static struct usb_gadget_driver composite_driver = {
};

/**
- * 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
@@ -1235,9 +1240,10 @@ static struct usb_gadget_driver composite_driver = {
* 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)
@@ -1247,6 +1253,7 @@ int usb_composite_register(struct usb_composite_driver *driver)
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);
}
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 400f803..33076bc 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -402,7 +402,6 @@ static struct usb_composite_driver eth_driver = {
.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);

diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 52fd3fa..9fcb158 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -147,7 +147,6 @@ static struct usb_composite_driver gfs_driver = {
.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(struct ffs_data *ffs)
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;
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 7757226..77f4952 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -256,7 +256,6 @@ static struct usb_composite_driver hidg_driver = {
.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);

diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 05e9bd3..a5e4a77 100644
--- 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_composite_dev *cdev)
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);

diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index ca51661..91170a0 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -353,7 +353,6 @@ static struct usb_composite_driver multi_driver = {
.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_driver = {

static int __init multi_init(void)
{
- return usb_composite_register(&multi_driver);
+ return usb_composite_probe(&multi_driver, multi_bind);
}
module_init(multi_init);

diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index f46a609..0b81d7b 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -242,7 +242,6 @@ static struct usb_composite_driver gserial_driver = {
.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);

diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index 288d211..de65b80 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -373,14 +373,13 @@ static struct usb_composite_driver webcam_driver = {
.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
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 807280d..6d16db9 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -340,7 +340,6 @@ static struct usb_composite_driver zero_driver = {
.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);

diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index d590904..101e788 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -248,11 +248,7 @@ int usb_add_config(struct usb_composite_dev *,
* 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.
* @suspend: Notifies when the host stops sending USB traffic,
* after function notifications
@@ -262,7 +258,7 @@ int usb_add_config(struct usb_composite_dev *,
* 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
@@ -278,12 +274,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 *);
@@ -293,8 +283,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);


/**
--
1.7.1

2010-08-12 15:42:25

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 03/13] USB: gadget: composite: Better string override handling

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 <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/composite.c | 96 ++++++++++++++++++++++++++-------------
include/linux/usb/composite.h | 13 +++++
2 files changed, 77 insertions(+), 32 deletions(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index e483f80..471c759 100644
--- 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_composite_dev *cdev,
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_composite_dev *cdev,
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 *gadget)
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)
@@ -1101,19 +1116,34 @@ static int composite_bind(struct usb_gadget *gadget)
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;
@@ -1211,6 +1241,8 @@ int usb_composite_register(struct usb_composite_driver *driver)
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;
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 890bc14..d590904 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -237,10 +237,17 @@ int usb_add_config(struct usb_composite_dev *,
/**
* 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
@@ -265,8 +272,11 @@ int usb_add_config(struct usb_composite_dev *,
*/
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
@@ -333,6 +343,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.
--
1.7.1

2010-08-12 15:42:40

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 12/13] usb gadget: don't save bind callback in struct usb_configuration

From: Uwe Kleine-König <[email protected]>

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 <[email protected]>
[[email protected]: updated for -next]
Signed-off-by: Michał Nazarewicz <[email protected]>
---
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(-)

diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index 5a65fbb..93b999e 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -105,7 +105,6 @@ static int __init audio_do_config(struct usb_configuration *c)

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_composite_dev *cdev)
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;

diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 1f2a9b1..2720ab0 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -151,7 +151,6 @@ static int __init cdc_do_config(struct usb_configuration *c)

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_composite_dev *cdev)
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;

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 6f3b5fb..942a4da 100644
--- 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_dev *cdev,
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_dev *cdev,
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_dev *cdev,
}
}

- /* 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);
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 33076bc..1690c9d 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -251,7 +251,6 @@ static int __init rndis_do_config(struct usb_configuration *c)

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 usb_configuration *c)

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_composite_dev *cdev)

/* 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;

diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index e91d1b1..b37960f 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -349,7 +349,6 @@ static int __init loopback_bind_config(struct usb_configuration *c)
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_composite_dev *cdev, bool autoresume)
loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
}

- return usb_add_config(cdev, &loopback_driver);
+ return usb_add_config(cdev, &loopback_driver, loopback_bind_config);
}
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index 6d3cc44..e403a53 100644
--- 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_composite_dev *cdev, bool autoresume)
sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
}

- return usb_add_config(cdev, &sourcesink_driver);
+ return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config);
}
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 9fcb158..af75e36 100644
--- 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_dev *cdev)

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;
}
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 77f4952..2523e54 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -148,7 +148,6 @@ static int __init do_config(struct usb_configuration *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_composite_dev *cdev)
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;

diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index a5e4a77..0769179 100644
--- 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 usb_configuration *c)

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_composite_dev *cdev)
{
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;

diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 91170a0..d9feced 100644
--- 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 usb_configuration *c)
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 usb_composite_dev *cdev)
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 usb_composite_dev *cdev)

#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 usb_configuration *c)
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 usb_composite_dev *cdev)
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
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index 7d6b66a..a7dda39 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -135,7 +135,6 @@ static int __init nokia_bind_config(struct usb_configuration *c)

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_config_500ma_driver = {

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_composite_dev *cdev)
}

/* 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;

diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 0b81d7b..1ac57a9 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -155,7 +155,6 @@ static int __init serial_bind_config(struct usb_configuration *c)

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_composite_dev *cdev)
}

/* 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;

diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index de65b80..a5a0fdb 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -317,7 +317,6 @@ webcam_config_bind(struct usb_configuration *c)

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 *cdev)
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");
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 101e788..fecc173 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -161,8 +161,6 @@ ep_choose(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
* 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
--
1.7.1

2010-08-12 15:42:43

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 13/13] init.h: add some more documentation to __ref* tags

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 <[email protected]>
Acked-by: Uwe Kleine-König <[email protected]>
Cc: Sam Ravnborg <[email protected]>
---
include/linux/init.h | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/init.h b/include/linux/init.h
index de99430..577671c 100644
--- 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)
--
1.7.1

2010-08-12 15:42:47

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 10/13] usb gadget: don't save bind callback in struct usb_gadget_driver

From: Uwe Kleine-König <[email protected]>

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 <[email protected]>
[[email protected]: added dbgp]
Signed-off-by: Michał Nazarewicz <[email protected]>
---
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(-)

diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index 731150d..fadebfd 100644
--- 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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)

return 0;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);

/* shutdown requests and disconnect from gadget */
static void
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index d90c9e8..bdec36a 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1627,7 +1627,8 @@ static void at91_vbus_timer(unsigned long data)
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;
@@ -1635,7 +1636,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)

if (!driver
|| driver->speed < USB_SPEED_FULL
- || !driver->bind
+ || !bind
|| !driver->setup) {
DBG("bad parameter.\n");
return -EINVAL;
@@ -1652,9 +1653,9 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
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);
@@ -1670,7 +1671,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index d623c7b..e4810c6 100644
--- 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 usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 6996951..98b36fc 100644
--- 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_ops = {
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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
trace("%p", driver);

if (driver == NULL ||
- driver->bind == NULL ||
driver->unbind == NULL ||
driver->setup == NULL ||
driver->disconnect == NULL ||
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 471c759..0d3f4b7 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1207,7 +1207,6 @@ composite_resume(struct usb_gadget *gadget)
static struct usb_gadget_driver composite_driver = {
.speed = USB_SPEED_HIGH,

- .bind = composite_bind,
.unbind = composite_unbind,

.setup = composite_setup,
@@ -1249,7 +1248,7 @@ int usb_composite_register(struct usb_composite_driver *driver)
composite_driver.driver.name = driver->name;
composite = driver;

- return usb_gadget_register_driver(&composite_driver);
+ return usb_gadget_probe_driver(&composite_driver, composite_bind);
}

/**
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c
index 0ed50a2..40cd3a0 100644
--- a/drivers/usb/gadget/dbgp.c
+++ b/drivers/usb/gadget/dbgp.c
@@ -405,7 +405,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,
@@ -417,7 +416,7 @@ static struct usb_gadget_driver dbgp_driver = {

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)
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index dc65462..7bb9d78 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -748,7 +748,8 @@ static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
*/

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_gadget_driver *driver)
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_gadget_driver *driver)
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_gadget_driver *driver)
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)
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index aae04c2..132a1c0 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3608,7 +3608,6 @@ static struct usb_gadget_driver fsg_driver = {
.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;
}
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index a5ea2c1..792d5ef 100644
--- 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, void *_udc)
}

/*-------------------------------------------------------------------------
- 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 usb_gadget_driver *driver)

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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index d933e63..4c55eda 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1759,7 +1759,8 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
* 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;
@@ -1769,8 +1770,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)

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)
@@ -1786,7 +1786,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
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;
@@ -1808,7 +1808,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)
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index b7bf880..0ab7e14 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -1292,7 +1292,6 @@ static void gmidi_resume(struct usb_gadget *gadget)
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_driver = {

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

diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 1088d08..49fbd4d 100644
--- 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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
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)
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index e743122..ed02664 100644
--- 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 usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index fc35406..e2e8eda 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1775,7 +1775,6 @@ static struct usb_gadget_driver gadgetfs_driver = {
.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_gadget *gadget)

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 __user *buf, size_t len, loff_t *ptr)

/* 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 *sb, void *opts, int silent)
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;

diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index d41b69c..6200e21 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -1804,7 +1804,8 @@ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
* 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;
@@ -1827,7 +1828,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)

spin_unlock_irqrestore(&dev->lock, flags);

- retval = driver->bind(&dev->gadget);
+ retval = bind(&dev->gadget);
if (retval) {
DBG(dev, "bind to driver %s --> %d\n",
driver->driver.name, retval);
@@ -1865,7 +1866,7 @@ err_unbind:
DBG(dev, "<--- %s()\n", __func__);
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);


/* unregister gadget driver */
@@ -1879,7 +1880,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)

DBG(dev, "---> %s()\n", __func__);

- if (unlikely(!driver || !driver->bind || !driver->unbind))
+ if (unlikely(!driver || !driver->unbind))
return -EINVAL;

/* unbind OTG transceiver */
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index fded3fc..6b58bd8 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -408,7 +408,8 @@ static void udc_enable(struct lh7a40x_udc *dev)
/*
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 usb_gadget_driver *driver)

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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)

return 0;
}
-
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);

/*
Unregister entry point for the peripheral controller driver.
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 166bf71..2ce1f49 100644
--- 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 usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 9498be8..d09155b 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -1929,7 +1929,8 @@ static void ep0_start (struct net2280 *dev)
* 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 usb_gadget_driver *driver)
*/
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 usb_gadget_driver *driver)
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)
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index f81e4f0..61d3ca6 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2102,7 +2102,8 @@ static inline int machine_without_vbus_sense(void)
);
}

-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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 04c7bbf..ded080a 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -1543,7 +1543,6 @@ static struct usb_gadget_driver printer_driver = {
.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;
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index be5fb34..b37f92c 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -1280,14 +1280,15 @@ static void udc_enable (struct pxa25x_udc *dev)
* 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)
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 98dfa18..2efd673 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1790,8 +1790,9 @@ static void udc_enable(struct pxa_udc *udc)
}

/**
- * 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
@@ -1803,12 +1804,13 @@ static void udc_enable(struct pxa_udc *udc)
*
* 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)
@@ -1826,7 +1828,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
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);
@@ -1857,7 +1859,7 @@ add_fail:
udc->gadget.dev.driver = NULL;
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);


/**
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 70a8178..5545d41 100644
--- 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 usb_gadget_driver *driver)
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)
{
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 521ebed..ec9db61 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -2525,7 +2525,8 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg)
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;
@@ -2545,7 +2546,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
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;
}
@@ -2564,7 +2565,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
goto err;
}

- ret = driver->bind(&hsotg->gadget);
+ ret = bind(&hsotg->gadget);
if (ret) {
dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name);

@@ -2689,7 +2690,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)
{
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index ea2b3c7..c244895 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1632,15 +1632,15 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev)
}

/*
- * 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 usb_gadget_driver *driver)
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 usb_gadget_driver *driver)
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);
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index a83a139..7cc713f 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1695,9 +1695,11 @@ void musb_gadget_cleanup(struct musb *musb)
* -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;
@@ -1705,8 +1707,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)

if (!driver
|| driver->speed != USB_SPEED_HIGH
- || !driver->bind
- || !driver->setup)
+ || !bind || !driver->setup)
return -EINVAL;

/* driver must be initialized to support peripheral mode */
@@ -1734,7 +1735,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
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);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index d3ef42d..006412c 100644
--- 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 *gadget)
* 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 *gadget)
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
--
1.7.1

2010-08-12 15:43:53

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 05/13] USB: gadget: functionfs: code cleanup

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 <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/g_ffs.c | 85 ++++++++++++++-----------------------------
1 files changed, 28 insertions(+), 57 deletions(-)

diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 3c2f0a4..52fd3fa 100644
--- 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

2010-08-12 15:44:12

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 04/13] USB: gadget: mass_storage: moved strings handling code to composite

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 <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/mass_storage.c | 72 +++---------------------------------
1 files changed, 6 insertions(+), 66 deletions(-)

diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 585f255..493d153 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -75,10 +75,6 @@ static struct usb_device_descriptor msg_device_desc = {
/* 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_descriptor = {
.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_header *otg_desc[] = {
};


-/* 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_config_driver = {
.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_composite_dev *cdev)

/****************************** 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);
--
1.7.1

2010-08-12 15:44:15

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 07/13] usb: gadget: storage: remove nofua file when unbinding

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 <[email protected]>
Acked-by: Andy Shevchenko <[email protected]>
---
drivers/usb/gadget/file_storage.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index a857b7a..ab77792 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3178,6 +3178,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
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);
--
1.7.1

2010-08-12 15:44:08

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 08/13] usb: gadget: mass_storage: optional SCSI WRITE FUA bit

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 <[email protected]>
Cc: Andy Shevchenko <[email protected]>
---
drivers/usb/gadget/f_mass_storage.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 32cce02..44e5ffe 100644
--- 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 *common)
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_init(struct fsg_common *common,
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 kref *ref)

/* 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, \
--
1.7.1

2010-08-12 15:44:52

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 06/13] USB: gadget: g_multi: moved strings handling code to composite

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 <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/multi.c | 19 +++----------------
1 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 36d67a3..ca51661 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -121,8 +121,6 @@ static const struct usb_descriptor_header *otg_desc[] = {


enum {
- MULTI_STRING_MANUFACTURER_IDX,
- MULTI_STRING_PRODUCT_IDX,
#ifdef CONFIG_USB_G_MULTI_RNDIS
MULTI_STRING_RNDIS_CONFIG_IDX,
#endif
@@ -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_composite_dev *cdev)
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_driver = {
.strings = dev_strings,
.bind = multi_bind,
.unbind = __exit_p(multi_unbind),
+ .iProduct = DRIVER_DESC,
+ .needs_serial = 1,
};


--
1.7.1

2010-08-12 15:45:07

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCHv8 02/13] USB: gadget: g_ffs: fixed vendor and product ID

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 <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
drivers/usb/gadget/g_ffs.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index a9474f8..3c2f0a4 100644
--- 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,
--
1.7.1

2010-08-12 15:45:46

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCHv8 11/13] usb gadget: don't save bind callback in struct usb_composite_driver

On Thu, Aug 12, 2010 at 05:43:54PM +0200, Michal Nazarewicz wrote:
> 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 <[email protected]>
> Cc: Uwe Kleine-König <[email protected]>
Ack

Thanks
Uwe

--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |

2010-08-12 15:48:20

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCHv8 13/13] init.h: add some more documentation to __ref* tags

On Thu, Aug 12, 2010 at 05:43:56PM +0200, Michal Nazarewicz wrote:
> 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 <[email protected]>
> Acked-by: Uwe Kleine-K?nig <[email protected]>
> Cc: Sam Ravnborg <[email protected]>
Acked-by: Sam Ravnborg <[email protected]>

2010-08-12 22:34:24

by David Brownell

[permalink] [raw]
Subject: Re: [PATCHv8 04/13] USB: gadget: mass_storage: moved strings handling code to composite

Looks OK, but I can't test or give it
a detailed review just now. An ACK from
Alan would be nice.

2010-08-13 15:15:19

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCHv8 04/13] USB: gadget: mass_storage: moved strings handling code to composite

On Thu, 12 Aug 2010, David Brownell wrote:

> Looks OK, but I can't test or give it
> a detailed review just now. An ACK from
> Alan would be nice.

There's nothing obviously wrong with this change. However based on all
the preceding discussion, I now think the best approach may be _never_
to make up a fake serial number. Use the module parameter, if any, and
otherwise issue a warning and don't have a serial number string
descriptor (even though that violates the spec).

At this point it should be easy to write a patch to implement and
document the new behavior, for both file-storage and mass-storage.

Alan Stern

2010-08-13 20:30:30

by David Brownell

[permalink] [raw]
Subject: Re: [PATCHv8 04/13] USB: gadget: mass_storage: moved strings handling code to composite



--- On Fri, 8/13/10, Alan Stern <[email protected]> wrote:
.?
> ... based on all
> the preceding discussion, I now think the best
> approach may be _never
> to make up a fake serial number.? Use the module
> parameter, if any, and
> otherwise issue a warning and don't have
> a serial number string
> descriptor (even though that violates the spec).


Agreed, and that's what I had asked for. I didn't
see code faking up a serial ... did I miss such?

If so, let's see a new patch with no faking.


2010-08-14 00:23:45

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCHv8 04/13] USB: gadget: mass_storage: moved strings handling code to composite

On Fri, 13 Aug 2010, David Brownell wrote:

> --- On Fri, 8/13/10, Alan Stern <[email protected]> wrote:
> .?
> > ... based on all
> > the preceding discussion, I now think the best
> > approach may be _never
> > to make up a fake serial number.? Use the module
> > parameter, if any, and
> > otherwise issue a warning and don't have
> > a serial number string
> > descriptor (even though that violates the spec).
>
>
> Agreed, and that's what I had asked for. I didn't
> see code faking up a serial ... did I miss such?

That code has been present in g_file_storage since the beginning.
There were some patches earlier which moved the code to a different
location. I guess you missed it. The current round of patches doesn't
touch that code.

> If so, let's see a new patch with no faking.

An extra patch or two would be needed to remove the fake-serial
generation.

Alan Stern

2010-08-18 01:26:59

by Michal Nazarewicz

[permalink] [raw]
Subject: Re: [PATCHv8 04/13] USB: gadget: mass_storage: moved strings handling code to composite

On Sat, 14 Aug 2010 02:23:42 +0200, Alan Stern <[email protected]> wrote:

> On Fri, 13 Aug 2010, David Brownell wrote:
>
>> --- On Fri, 8/13/10, Alan Stern <[email protected]> wrote:
>> .> ... based on all
>> > the preceding discussion, I now think the best
>> > approach may be _never
>> > to make up a fake serial number. Use the module
>> > parameter, if any, and
>> > otherwise issue a warning and don't have
>> > a serial number string
>> > descriptor (even though that violates the spec).
>>
>>
>> Agreed, and that's what I had asked for. I didn't
>> see code faking up a serial ... did I miss such?
>
> That code has been present in g_file_storage since the beginning.
> There were some patches earlier which moved the code to a different
> location. I guess you missed it. The current round of patches doesn't
> touch that code.

Yep. I originally moved code from g_file_storage to g_mass_storage (and
g_multi) but after David's objections the patches have been dropped so
currently only g_file_storage has this code.

>> If so, let's see a new patch with no faking.
>
> An extra patch or two would be needed to remove the fake-serial
> generation.

This should be a straightforward patch. If no one else does it
I can post it but it may take up to a month for me to find the time
to work on it.

--
Best regards, _ _
| Humble Liege of Serenely Enlightened Majesty of o' \,=./ `o
| Computer Science, Michał "mina86" Nazarewicz (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--