[PATCHv2] USB: composite: allow optional removal of __init and __exittags

From: Michal Nazarewicz
Date: Mon Mar 15 2010 - 08:48:46 EST


The composite framework has been written using __init and __exit tags
to mark init and exit functions as such. This works with most of the
composite gadgets however some may need to call init/exit functions
during normal operations. One example is mass storage gadget which
needs to call exit functions.

This patch allows gadgets to define USB_NO_INIT_SEGMENT or
USB_NO_EXIT_SEGMENT to remove the __init and __exit declarations
from composite framework.

For example see mass_storage.c.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@xxxxxxxxxxx>
Cc: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
Sorry about the previous version. It was obviously an unfixed version
(files got mixed). This is the correct version.

drivers/usb/gadget/composite.c | 25 +++++++++++++------------
drivers/usb/gadget/config.c | 6 ++++--
drivers/usb/gadget/epautoconf.c | 13 +++++++------
drivers/usb/gadget/mass_storage.c | 4 ++++
drivers/usb/gadget/usb-init-exit.h | 23 +++++++++++++++++++++++
5 files changed, 51 insertions(+), 20 deletions(-)
create mode 100644 drivers/usb/gadget/usb-init-exit.h

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 09289bb..0039aba 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -27,6 +27,8 @@

#include <linux/usb/composite.h>

+#include "usb-init-exit.h"
+

/*
* The code in this file is utility code, used to build a gadget driver
@@ -85,7 +87,7 @@ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
* This function returns the value of the function's bind(), which is
* zero for success else a negative errno value.
*/
-int __init usb_add_function(struct usb_configuration *config,
+int __usb_init usb_add_function(struct usb_configuration *config,
struct usb_function *function)
{
int value = -EINVAL;
@@ -215,7 +217,7 @@ int usb_function_activate(struct usb_function *function)
* Returns the interface ID which was allocated; or -ENODEV if no
* more interface IDs can be allocated.
*/
-int __init usb_interface_id(struct usb_configuration *config,
+int __usb_init usb_interface_id(struct usb_configuration *config,
struct usb_function *function)
{
unsigned id = config->next_interface_id;
@@ -480,7 +482,7 @@ done:
* assigns global resources including string IDs, and per-configuration
* resources such as interface IDs and endpoints.
*/
-int __init usb_add_config(struct usb_composite_dev *cdev,
+int __usb_init usb_add_config(struct usb_composite_dev *cdev,
struct usb_configuration *config)
{
int status = -EINVAL;
@@ -677,7 +679,7 @@ static int get_string(struct usb_composite_dev *cdev,
* ensure that for example different functions don't wrongly assign
* different meanings to the same identifier.
*/
-int __init usb_string_id(struct usb_composite_dev *cdev)
+int __usb_init usb_string_id(struct usb_composite_dev *cdev)
{
if (cdev->next_string_id < 254) {
/* string id 0 is reserved */
@@ -898,7 +900,7 @@ static void composite_disconnect(struct usb_gadget *gadget)

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

-static void /* __init_or_exit */
+static void __usb_init_or_exit
composite_unbind(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
@@ -947,7 +949,7 @@ composite_unbind(struct usb_gadget *gadget)
composite = NULL;
}

-static void __init
+static void __usb_init
string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
{
struct usb_string *str = tab->strings;
@@ -960,7 +962,7 @@ string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
}
}

-static void __init
+static void __usb_init
string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
{
while (*tab) {
@@ -969,7 +971,7 @@ string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
}
}

-static int __init composite_bind(struct usb_gadget *gadget)
+static int __usb_init composite_bind(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev;
int status = -ENOMEM;
@@ -1092,8 +1094,7 @@ static struct usb_gadget_driver composite_driver = {
.speed = USB_SPEED_HIGH,

.bind = composite_bind,
- /* .unbind = __exit_p(composite_unbind), */
- .unbind = composite_unbind,
+ .unbind = __usb_exit_p(composite_unbind),

.setup = composite_setup,
.disconnect = composite_disconnect,
@@ -1121,7 +1122,7 @@ 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 __init usb_composite_register(struct usb_composite_driver *driver)
+int __usb_init usb_composite_register(struct usb_composite_driver *driver)
{
if (!driver || !driver->dev || !driver->bind || composite)
return -EINVAL;
@@ -1142,7 +1143,7 @@ int __init usb_composite_register(struct usb_composite_driver *driver)
* This function is used to unregister drivers using the composite
* driver framework.
*/
-void /* __exit */ usb_composite_unregister(struct usb_composite_driver *driver)
+void __usb_exit usb_composite_unregister(struct usb_composite_driver *driver)
{
if (composite != driver)
return;
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index e1191b9..31741ed 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -27,6 +27,8 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>

+#include "usb-init-exit.h"
+

/**
* usb_descriptor_fillbuf - fill buffer with descriptors
@@ -127,7 +129,7 @@ int usb_gadget_config_buf(
* with identifiers (for interfaces, strings, endpoints, and more)
* as needed by a given function instance.
*/
-struct usb_descriptor_header **__init
+struct usb_descriptor_header **__usb_init
usb_copy_descriptors(struct usb_descriptor_header **src)
{
struct usb_descriptor_header **tmp;
@@ -174,7 +176,7 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
* intended use is to help remembering the endpoint descriptor to use
* when enabling a given endpoint.
*/
-struct usb_endpoint_descriptor *__init
+struct usb_endpoint_descriptor *__usb_init
usb_find_endpoint(
struct usb_descriptor_header **src,
struct usb_descriptor_header **copy,
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index cd0914e..ba2af33 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -31,15 +31,16 @@
#include <linux/usb/gadget.h>

#include "gadget_chips.h"
+#include "usb-init-exit.h"


/* we must assign addresses for configurable endpoints (like net2280) */
-static __initdata unsigned epnum;
+static __usb_initdata unsigned epnum;

// #define MANY_ENDPOINTS
#ifdef MANY_ENDPOINTS
/* more than 15 configurable endpoints */
-static __initdata unsigned in_epnum;
+static __usb_initdata unsigned in_epnum;
#endif


@@ -59,7 +60,7 @@ static __initdata unsigned in_epnum;
* NOTE: each endpoint is unidirectional, as specified by its USB
* descriptor; and isn't specific to a configuration or altsetting.
*/
-static int __init
+static int __usb_init
ep_matches (
struct usb_gadget *gadget,
struct usb_ep *ep,
@@ -187,7 +188,7 @@ ep_matches (
return 1;
}

-static struct usb_ep * __init
+static struct usb_ep * __usb_init
find_ep (struct usb_gadget *gadget, const char *name)
{
struct usb_ep *ep;
@@ -229,7 +230,7 @@ find_ep (struct usb_gadget *gadget, const char *name)
*
* On failure, this returns a null endpoint descriptor.
*/
-struct usb_ep * __init usb_ep_autoconfig (
+struct usb_ep * __usb_init usb_ep_autoconfig (
struct usb_gadget *gadget,
struct usb_endpoint_descriptor *desc
)
@@ -296,7 +297,7 @@ struct usb_ep * __init usb_ep_autoconfig (
* state such as ep->driver_data and the record of assigned endpoints
* used by usb_ep_autoconfig().
*/
-void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget)
+void __usb_init usb_ep_autoconfig_reset (struct usb_gadget *gadget)
{
struct usb_ep *ep;

diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 19619fb..3d4b2ac 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -57,6 +57,10 @@
* a "gcc --combine ... part1.c part2.c part3.c ... " build would.
*/

+/* Do not mark composite_unbind() and usb_composite_unregister() as
+ * __exit, we may need it even if we are not unloaded. */
+#define USB_NO_EXIT_SEGMENT 1
+
#include "composite.c"
#include "usbstring.c"
#include "config.c"
diff --git a/drivers/usb/gadget/usb-init-exit.h b/drivers/usb/gadget/usb-init-exit.h
new file mode 100644
index 0000000..04cd624
--- /dev/null
+++ b/drivers/usb/gadget/usb-init-exit.h
@@ -0,0 +1,23 @@
+#ifndef __usb_init
+# if defined USB_NO_INIT_SEGMENT
+# define __usb_init __cold
+# define __usb_initdata
+# else
+# define __usb_init __init
+# define __usb_initdata __initdata
+# endif
+# if defined USB_NO_EXIT_SEGMENT
+# define __usb_exit __cold
+# define __usb_exit_p(func) func
+# define __usb_exitdata
+# else
+# define __usb_exit __exit
+# define __usb_exit_p(func) __exit_p(func)
+# define __usb_exitdata __exitdata
+# endif
+# if defined USB_NO_INIT_SEGMENT || defined USB_NO_EXIT_SEGMENT
+# define __usb_init_or_exit __cold
+# else
+# define __usb_init_or_exit /* __init_or_exit */
+# endif
+#endif
--
1.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/