2010-08-09 13:33:23

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCH 1/3] 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]>
Cc: Greg Kroah-Hartman <[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(-)

Uwe's original patch missed dbgp.c, added it in this version.

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 93ead19..387e503 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1628,7 +1628,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;
@@ -1636,7 +1637,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;
@@ -1653,9 +1654,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);
@@ -1671,7 +1672,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 e483f80..4590c6a 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1177,7 +1177,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,
@@ -1217,7 +1216,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 772b057..ae609ba 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3607,7 +3607,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,
@@ -3649,7 +3648,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 08a9a62..c16b402 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1765,7 +1765,8 @@ static irqreturn_t fsl_udc_irq(int irq, 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;
@@ -1775,8 +1776,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)
@@ -1792,7 +1792,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;
@@ -1814,7 +1814,7 @@ out:
retval);
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);

/* Disconnect from gadget driver */
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
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 c2d2a20..3e6f8ad 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -1807,7 +1807,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;
@@ -1830,7 +1831,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);
@@ -1868,7 +1869,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 */
@@ -1882,7 +1883,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 9807624..027d66f 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1792,8 +1792,9 @@ static void udc_enable(struct pxa_udc *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
@@ -1805,12 +1806,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)
@@ -1828,7 +1830,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);
@@ -1859,7 +1861,7 @@ add_fail:
udc->gadget.dev.driver = NULL;
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);


/**
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 6fca870..d940e80 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1696,9 +1696,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;
@@ -1706,8 +1708,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 */
@@ -1735,7 +1736,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-09 13:32:57

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCH 2/3] 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]>
Cc: Greg Kroah-Hartman <[email protected]>
---
drivers/usb/gadget/audio.c | 3 +--
drivers/usb/gadget/cdc2.c | 3 +--
drivers/usb/gadget/composite.c | 19 +++++++++++++------
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 | 15 +++------------
12 files changed, 26 insertions(+), 38 deletions(-)

This replaces Uwe's patch which used __refdata for instances of struct
usb_composite_driver. This patch replaces usb_composite_register() with
usb_composite_probe() in similar fashion to other two Uwe's patches.

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 4590c6a..3cafda7 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -39,6 +39,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.
@@ -1094,15 +1095,15 @@ 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;

cdev->desc = *composite->dev;
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;

- /* strings can't be assigned before bind() allocates the
- * releavnt identifiers
+ /* strings can't be assigned before composite_gadget_bind()
+ * allocates the releavnt identifiers
*/
if (cdev->desc.iManufacturer && iManufacturer)
string_override(composite->strings,
@@ -1191,8 +1192,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
@@ -1205,9 +1210,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->name)
@@ -1215,6 +1221,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 a9474f8..6ab2d74 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -171,7 +171,6 @@ static struct usb_composite_driver gfs_driver = {
.name = gfs_short_name,
.dev = &gfs_dev_desc,
.strings = gfs_dev_strings,
- .bind = gfs_bind,
.unbind = gfs_unbind,
};

@@ -210,7 +209,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 306098f..a992c78 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -231,7 +231,6 @@ static struct usb_composite_driver msg_driver = {
.name = "g_mass_storage",
.dev = &msg_device_desc,
.strings = dev_strings,
- .bind = msg_bind,
};

MODULE_DESCRIPTION(DRIVER_DESC);
@@ -240,7 +239,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 795d762..384b3e1 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -368,14 +368,13 @@ static struct usb_composite_driver multi_driver = {
.name = "g_multi",
.dev = &device_desc,
.strings = dev_strings,
- .bind = multi_bind,
.unbind = __exit_p(multi_unbind),
};


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 890bc14..ff37718 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -241,10 +241,6 @@ int usb_add_config(struct usb_composite_dev *,
* identifiers.
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and language IDs provided in control requests
- * @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
* this driver.
* @suspend: Notifies when the host stops sending USB traffic,
@@ -268,12 +264,6 @@ struct usb_composite_driver {
const struct usb_device_descriptor *dev;
struct usb_gadget_strings **strings;

- /* 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 *);
@@ -283,8 +273,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-09 13:33:19

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCH 3/3] 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]>
Cc: Greg Kroah-Hartman <[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(-)

Uwe's original patch did not apply on -next for me (g_ffs.c and multi.c
conflicted) so fixed that.

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 3cafda7..f794c5e 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -471,18 +471,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;
@@ -491,7 +493,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 */
@@ -508,7 +510,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;
@@ -534,7 +536,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 6ab2d74..ba145ee 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -268,11 +268,10 @@ static int gfs_bind(struct usb_composite_dev *cdev)
ret = GFS_STRING_FIRST_CONFIG_IDX + i;
c->c.label = gfs_strings[ret].s;
c->c.iConfiguration = gfs_strings[ret].id;
- c->c.bind = gfs_do_config;
c->c.bConfigurationValue = 1 + i;
c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER;

- ret = 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 a992c78..bb83d4d 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -171,7 +171,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,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -214,7 +213,7 @@ static int __init msg_bind(struct usb_composite_dev *cdev)
msg_config_driver.iConfiguration = status;

/* register our second configuration */
- 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 384b3e1..ca54b47 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -170,7 +170,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;

@@ -197,7 +197,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,
};
@@ -205,7 +204,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
@@ -222,7 +221,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;

@@ -249,7 +248,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,
};
@@ -257,7 +255,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 ff37718..9a22b33 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-09 15:20:19

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 2/3] usb gadget: don't save bind callback in struct usb_composite_driver

Hello Michał,

On Mon, Aug 09, 2010 at 03:33:49PM +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]>
> Cc: Greg Kroah-Hartman <[email protected]>
> ---
> drivers/usb/gadget/audio.c | 3 +--
> drivers/usb/gadget/cdc2.c | 3 +--
> drivers/usb/gadget/composite.c | 19 +++++++++++++------
> 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 | 15 +++------------
> 12 files changed, 26 insertions(+), 38 deletions(-)
>
> This replaces Uwe's patch which used __refdata for instances of struct
> usb_composite_driver. This patch replaces usb_composite_register() with
> usb_composite_probe() in similar fashion to other two Uwe's patches.
>
> 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 4590c6a..3cafda7 100644
> --- a/drivers/usb/gadget/composite.c
> +++ b/drivers/usb/gadget/composite.c
> @@ -39,6 +39,7 @@
> #define USB_BUFSIZ 1024
>
> static struct usb_composite_driver *composite;
> +static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);
This can be __initdata, can't it?

I thought about usb_composite_drivers, too, and wondered if it would be
sensible to change the additional argument of usb_gadget_probe_driver to
struct usb_gadget_probe_data *probe_data. Then you could do the
following

struct usb_composite_probe_data {
struct usb_gadget_probe_data usb_probe_data;
int (*composite_gadget_bind)(struct usb_composite_dev *);
}

and in composite_bind use container_of to get the gadget_bind function.

Maybe that's overengineered though. As there is already a dependency on
a global variable (i.e. composite) your patch doesn't make it much
worse. Just my 0.02€.

Best regards
Uwe

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

2010-08-09 15:35:14

by Michal Nazarewicz

[permalink] [raw]
Subject: Re: [PATCH 2/3] usb gadget: don't save bind callback in struct usb_composite_driver

> On Mon, Aug 09, 2010 at 03:33:49PM +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.

>> diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
>> --- a/drivers/usb/gadget/composite.c
>> +++ b/drivers/usb/gadget/composite.c
>> @@ -39,6 +39,7 @@
>> #define USB_BUFSIZ 1024
>>
>> static struct usb_composite_driver *composite;
>> +static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);

On Mon, 09 Aug 2010 17:20:10 +0200, Uwe Kleine-König wrote:
> This can be __initdata, can't it?

No. g_ffs.c uses usb_composite_probe() not only in init so neither
usb_composite_probe() nor this new variable can be in init section.

> I thought about usb_composite_drivers, too, and wondered if it would be
> sensible to change the additional argument of usb_gadget_probe_driver to
> struct usb_gadget_probe_data *probe_data. Then you could do the
> following
>
> struct usb_composite_probe_data {
> struct usb_gadget_probe_data usb_probe_data;
> int (*composite_gadget_bind)(struct usb_composite_dev *);
> }
>
> and in composite_bind use container_of to get the gadget_bind function.

Yes, this seems sensible, however I'm not sure if it's worth the effort.
Note that the whole gadget API is designed in a way that there can be
only one gadget registered so that passing private data with
usb_gadget_probe_driver() as well as with usb_composite_probe() is not
really crucial and we can manage with global variables.

> Maybe that's overengineered though. As there is already a dependency on
> a global variable (i.e. composite) your patch doesn't make it much
> worse. Just my 0.02€.

Yep, that was my reasoning as well.

I guess we'll have to worry about it when (if) boards with many UDCs
became common. ;)

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