aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch937
-rw-r--r--f.patch102
-rw-r--r--f2.patch188
-rw-r--r--f3.patch71
-rw-r--r--f4.patch55
-rw-r--r--f5.patch87
-rw-r--r--series4
7 files changed, 1444 insertions, 0 deletions
diff --git a/driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch b/driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch
new file mode 100644
index 00000000000000..7e6abbb91c296c
--- /dev/null
+++ b/driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch
@@ -0,0 +1,937 @@
+From jbaron@redhat.com Tue Aug 12 17:09:39 2008
+From: Jason Baron <jbaron@redhat.com>
+Date: Tue, 12 Aug 2008 16:46:19 -0400
+Subject: driver core: basic infrastructure for per-module dynamic debug messages
+To: Greg KH <greg@kroah.com>
+Cc: Randy Dunlap <randy.dunlap@oracle.com>, linux-kernel@vger.kernel.org, akpm@linux-foundation.org, joe@perches.com, nick@nick-andrew.net
+Message-ID: <20080812204619.GE6056@redhat.com>
+Content-Disposition: inline
+
+Base infrastructure to enable per-module debug messages.
+
+I've introduced CONFIG_DYNAMIC_PRINTK_DEBUG, which when enabled centralizes
+control of debugging statements on a per-module basis in one /proc file,
+currently, <debugfs>/dynamic_printk/modules. When, CONFIG_DYNAMIC_PRINTK_DEBUG,
+is not set, debugging statements can still be enabled as before, often by
+defining 'DEBUG' for the proper compilation unit. Thus, this patch set has no
+affect when CONFIG_DYNAMIC_PRINTK_DEBUG is not set.
+
+The infrastructure currently ties into all pr_debug() and dev_dbg() calls. That
+is, if CONFIG_DYNAMIC_PRINTK_DEBUG is set, all pr_debug() and dev_dbg() calls
+can be dynamically enabled/disabled on a per-module basis.
+
+Future plans include extending this functionality to subsystems, that define
+their own debug levels and flags.
+
+Usage:
+
+Dynamic debugging is controlled by the debugfs file,
+<debugfs>/dynamic_printk/modules. This file contains a list of the modules that
+can be enabled. The format of the file is as follows:
+
+ <module_name> <enabled=0/1>
+ .
+ .
+ .
+
+ <module_name> : Name of the module in which the debug call resides
+ <enabled=0/1> : whether the messages are enabled or not
+
+For example:
+
+ snd_hda_intel enabled=0
+ fixup enabled=1
+ driver enabled=0
+
+Enable a module:
+
+ $echo "set enabled=1 <module_name>" > dynamic_printk/modules
+
+Disable a module:
+
+ $echo "set enabled=0 <module_name>" > dynamic_printk/modules
+
+Enable all modules:
+
+ $echo "set enabled=1 all" > dynamic_printk/modules
+
+Disable all modules:
+
+ $echo "set enabled=0 all" > dynamic_printk/modules
+
+Finally, passing "dynamic_printk" at the command line enables
+debugging for all modules. This mode can be turned off via the above
+disable command.
+
+
+
+Signed-off-by: Jason Baron <jbaron@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ Documentation/kernel-parameters.txt | 5
+ include/asm-generic/vmlinux.lds.h | 10
+ include/linux/device.h | 6
+ include/linux/dynamic_printk.h | 96 ++++++++
+ include/linux/kernel.h | 7
+ include/linux/module.h | 4
+ kernel/module.c | 22 +
+ lib/Kconfig.debug | 55 ++++
+ lib/Makefile | 2
+ lib/dynamic_printk.c | 412 ++++++++++++++++++++++++++++++++++++
+ net/netfilter/nf_conntrack_pptp.c | 2
+ scripts/Makefile.lib | 11
+ scripts/basic/Makefile | 2
+ scripts/basic/hash.c | 64 +++++
+ 14 files changed, 692 insertions(+), 6 deletions(-)
+
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1675,6 +1675,11 @@ and is between 256 and 4096 characters.
+ autoconfiguration.
+ Ranges are in pairs (memory base and size).
+
++ dynamic_printk
++ Enables pr_debug()/dev_dbg() calls if
++ CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
++ be switched on/off via <debugfs>/dynamic_printk/modules
++
+ print-fatal-signals=
+ [KNL] debug: print fatal signals
+ print-fatal-signals=1: print segfault info to
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -268,7 +268,15 @@
+ CPU_DISCARD(init.data) \
+ CPU_DISCARD(init.rodata) \
+ MEM_DISCARD(init.data) \
+- MEM_DISCARD(init.rodata)
++ MEM_DISCARD(init.rodata) \
++ /* implement dynamic printk debug */ \
++ VMLINUX_SYMBOL(__start___verbose_strings) = .; \
++ *(__verbose_strings) \
++ VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
++ . = ALIGN(8); \
++ VMLINUX_SYMBOL(__start___verbose) = .; \
++ *(__verbose) \
++ VMLINUX_SYMBOL(__stop___verbose) = .;
+
+ #define INIT_TEXT \
+ *(.init.text) \
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -538,7 +538,11 @@ extern const char *dev_driver_string(con
+ #define dev_info(dev, format, arg...) \
+ dev_printk(KERN_INFO , dev , format , ## arg)
+
+-#ifdef DEBUG
++#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
++#define dev_dbg(dev, format, ...) do { \
++ dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
++ } while (0)
++#elif defined(DEBUG)
+ #define dev_dbg(dev, format, arg...) \
+ dev_printk(KERN_DEBUG , dev , format , ## arg)
+ #else
+--- /dev/null
++++ b/include/linux/dynamic_printk.h
+@@ -0,0 +1,96 @@
++#ifndef _DYNAMIC_PRINTK_H
++#define _DYNAMIC_PRINTK_H
++
++#include <linux/string.h>
++#include <linux/hash.h>
++
++#define DYNAMIC_DEBUG_HASH_BITS 6
++#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
++
++#define TYPE_BOOLEAN 1
++
++#define DYNAMIC_ENABLED_ALL 0
++#define DYNAMIC_ENABLED_NONE 1
++#define DYNAMIC_ENABLED_SOME 2
++
++extern int dynamic_enabled;
++
++/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
++ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
++ * use independent hash functions, to reduce the chance of false positives.
++ */
++extern long long dynamic_printk_enabled;
++extern long long dynamic_printk_enabled2;
++
++struct mod_debug {
++ char *modname;
++ char *logical_modname;
++ char *flag_names;
++ int type;
++ int hash;
++ int hash2;
++} __attribute__((aligned(8)));
++
++int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
++ char *flags, int hash, int hash2);
++
++#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
++extern int unregister_dynamic_debug_module(char *mod_name);
++extern int __dynamic_dbg_enabled_helper(char *modname, int type,
++ int value, int hash);
++
++#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \
++ int ret = 0; \
++ if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \
++ (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \
++ ret = __dynamic_dbg_enabled_helper(module, type, \
++ value, hash);\
++ ret; })
++
++#define dynamic_pr_debug(fmt, ...) do { \
++ static char mod_name[] \
++ __attribute__((section("__verbose_strings"))) \
++ = KBUILD_MODNAME; \
++ static struct mod_debug descriptor \
++ __used \
++ __attribute__((section("__verbose"), aligned(8))) = \
++ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
++ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
++ 0, 0, DEBUG_HASH)) \
++ printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
++ ##__VA_ARGS__); \
++ } while (0)
++
++#define dynamic_dev_dbg(dev, format, ...) do { \
++ static char mod_name[] \
++ __attribute__((section("__verbose_strings"))) \
++ = KBUILD_MODNAME; \
++ static struct mod_debug descriptor \
++ __used \
++ __attribute__((section("__verbose"), aligned(8))) = \
++ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
++ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
++ 0, 0, DEBUG_HASH)) \
++ dev_printk(KERN_DEBUG, dev, \
++ KBUILD_MODNAME ": " format, \
++ ##__VA_ARGS__); \
++ } while (0)
++
++#else
++
++static inline int unregister_dynamic_debug_module(const char *mod_name)
++{
++ return 0;
++}
++static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
++ int value, int hash)
++{
++ return 0;
++}
++
++#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; })
++#define dynamic_pr_debug(fmt, ...) do { } while (0)
++#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
++#endif
++
++#endif
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -16,6 +16,7 @@
+ #include <linux/log2.h>
+ #include <linux/typecheck.h>
+ #include <linux/ratelimit.h>
++#include <linux/dynamic_printk.h>
+ #include <asm/byteorder.h>
+ #include <asm/bug.h>
+
+@@ -303,8 +304,12 @@ static inline char *pack_hex_byte(char *
+ #define pr_info(fmt, arg...) \
+ printk(KERN_INFO fmt, ##arg)
+
+-#ifdef DEBUG
+ /* If you are writing a driver, please use dev_dbg instead */
++#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
++#define pr_debug(fmt, ...) do { \
++ dynamic_pr_debug(fmt, ##__VA_ARGS__); \
++ } while (0)
++#elif defined(DEBUG)
+ #define pr_debug(fmt, arg...) \
+ printk(KERN_DEBUG fmt, ##arg)
+ #else
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -346,6 +346,10 @@ struct module
+ struct module_ref ref[NR_CPUS];
+ #endif
+
++#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
++ struct mod_debug *start_verbose;
++ unsigned int num_verbose;
++#endif
+ };
+ #ifndef MODULE_ARCH_INIT
+ #define MODULE_ARCH_INIT {}
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -784,6 +784,7 @@ sys_delete_module(const char __user *nam
+ mutex_lock(&module_mutex);
+ /* Store the name of the last unloaded module for diagnostic purposes */
+ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
++ unregister_dynamic_debug_module(mod->name);
+ free_module(mod);
+
+ out:
+@@ -1831,6 +1832,9 @@ static struct module *load_module(void _
+ #endif
+ unsigned int markersindex;
+ unsigned int markersstringsindex;
++ unsigned int verboseindex;
++ struct mod_debug *iter;
++ unsigned long value;
+ struct module *mod;
+ long err = 0;
+ void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
+@@ -2117,6 +2121,7 @@ static struct module *load_module(void _
+ markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
+ markersstringsindex = find_sec(hdr, sechdrs, secstrings,
+ "__markers_strings");
++ verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
+
+ /* Now do relocations. */
+ for (i = 1; i < hdr->e_shnum; i++) {
+@@ -2144,6 +2149,11 @@ static struct module *load_module(void _
+ mod->num_markers =
+ sechdrs[markersindex].sh_size / sizeof(*mod->markers);
+ #endif
++#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
++ mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr;
++ mod->num_verbose = sechdrs[verboseindex].sh_size /
++ sizeof(*mod->start_verbose);
++#endif
+
+ /* Find duplicate symbols */
+ err = verify_export_symbols(mod);
+@@ -2167,6 +2177,18 @@ static struct module *load_module(void _
+ marker_update_probe_range(mod->markers,
+ mod->markers + mod->num_markers);
+ #endif
++#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
++ for (value = (unsigned long)mod->start_verbose;
++ value < (unsigned long)mod->start_verbose +
++ (unsigned long)(mod->num_verbose * sizeof(struct mod_debug));
++ value += sizeof(struct mod_debug)) {
++ iter = (struct mod_debug *)value;
++ register_dynamic_debug_module(iter->modname,
++ iter->type,
++ iter->logical_modname,
++ iter->flag_names, iter->hash, iter->hash2);
++ }
++#endif
+ err = module_finalize(hdr, sechdrs, mod);
+ if (err < 0)
+ goto cleanup;
+--- /dev/null
++++ b/lib/dynamic_printk.c
+@@ -0,0 +1,412 @@
++/*
++ * lib/dynamic_printk.c
++ *
++ * make pr_debug()/dev_dbg() calls runtime configurable based upon their
++ * their source module.
++ *
++ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/uaccess.h>
++#include <linux/seq_file.h>
++#include <linux/debugfs.h>
++#include <linux/fs.h>
++
++extern struct mod_debug __start___verbose[];
++extern struct mod_debug __stop___verbose[];
++
++struct debug_name {
++ struct hlist_node hlist;
++ struct hlist_node hlist2;
++ int hash1;
++ int hash2;
++ char *name;
++ int enable;
++ int type;
++};
++
++static int nr_entries;
++static int num_enabled;
++int dynamic_enabled = DYNAMIC_ENABLED_NONE;
++static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
++ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
++static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
++ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
++static DECLARE_MUTEX(debug_list_mutex);
++
++/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
++ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
++ * use independent hash functions, to reduce the chance of false positives.
++ */
++long long dynamic_printk_enabled;
++EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
++long long dynamic_printk_enabled2;
++EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
++
++/* returns the debug module pointer. */
++static struct debug_name *find_debug_module(char *module_name)
++{
++ int i;
++ struct hlist_head *head;
++ struct hlist_node *node;
++ struct debug_name *element;
++
++ element = NULL;
++ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
++ head = &module_table[i];
++ hlist_for_each_entry_rcu(element, node, head, hlist)
++ if (!strcmp(element->name, module_name))
++ return element;
++ }
++ return NULL;
++}
++
++/* returns the debug module pointer. */
++static struct debug_name *find_debug_module_hash(char *module_name, int hash)
++{
++ struct hlist_head *head;
++ struct hlist_node *node;
++ struct debug_name *element;
++
++ element = NULL;
++ head = &module_table[hash];
++ hlist_for_each_entry_rcu(element, node, head, hlist)
++ if (!strcmp(element->name, module_name))
++ return element;
++ return NULL;
++}
++
++/* caller must hold mutex*/
++static int __add_debug_module(char *mod_name, int hash, int hash2)
++{
++ struct debug_name *new;
++ char *module_name;
++ int ret = 0;
++
++ if (find_debug_module(mod_name)) {
++ ret = -EINVAL;
++ goto out;
++ }
++ module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
++ if (!module_name) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ module_name = strcpy(module_name, mod_name);
++ module_name[strlen(mod_name)] = '\0';
++ new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
++ if (!new) {
++ kfree(module_name);
++ ret = -ENOMEM;
++ goto out;
++ }
++ INIT_HLIST_NODE(&new->hlist);
++ INIT_HLIST_NODE(&new->hlist2);
++ new->name = module_name;
++ new->hash1 = hash;
++ new->hash2 = hash2;
++ hlist_add_head_rcu(&new->hlist, &module_table[hash]);
++ hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
++ nr_entries++;
++out:
++ return ret;
++}
++
++int unregister_dynamic_debug_module(char *mod_name)
++{
++ struct debug_name *element;
++ int ret = 0;
++
++ down(&debug_list_mutex);
++ element = find_debug_module(mod_name);
++ if (!element) {
++ ret = -EINVAL;
++ goto out;
++ }
++ hlist_del_rcu(&element->hlist);
++ hlist_del_rcu(&element->hlist2);
++ synchronize_rcu();
++ kfree(element->name);
++ if (element->enable)
++ num_enabled--;
++ kfree(element);
++ nr_entries--;
++out:
++ up(&debug_list_mutex);
++ return 0;
++}
++EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
++
++int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
++ char *flags, int hash, int hash2)
++{
++ struct debug_name *elem;
++ int ret = 0;
++
++ down(&debug_list_mutex);
++ elem = find_debug_module(mod_name);
++ if (!elem) {
++ if (__add_debug_module(mod_name, hash, hash2))
++ goto out;
++ elem = find_debug_module(mod_name);
++ if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
++ !strcmp(mod_name, share_name)) {
++ elem->enable = true;
++ num_enabled++;
++ }
++ }
++ elem->type |= type;
++out:
++ up(&debug_list_mutex);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
++
++int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
++{
++ struct debug_name *elem;
++ int ret = 0;
++
++ if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
++ return 1;
++ rcu_read_lock();
++ elem = find_debug_module_hash(mod_name, hash);
++ if (elem && elem->enable)
++ ret = 1;
++ rcu_read_unlock();
++ return ret;
++}
++EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
++
++static void set_all(bool enable)
++{
++ struct debug_name *e;
++ struct hlist_node *node;
++ int i;
++ long long enable_mask;
++
++ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
++ if (module_table[i].first != NULL) {
++ hlist_for_each_entry(e, node, &module_table[i], hlist) {
++ e->enable = enable;
++ }
++ }
++ }
++ if (enable)
++ enable_mask = ULLONG_MAX;
++ else
++ enable_mask = 0;
++ dynamic_printk_enabled = enable_mask;
++ dynamic_printk_enabled2 = enable_mask;
++}
++
++static int disabled_hash(int i, bool first_table)
++{
++ struct debug_name *e;
++ struct hlist_node *node;
++
++ if (first_table) {
++ hlist_for_each_entry(e, node, &module_table[i], hlist) {
++ if (e->enable)
++ return 0;
++ }
++ } else {
++ hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
++ if (e->enable)
++ return 0;
++ }
++ }
++ return 1;
++}
++
++static ssize_t pr_debug_write(struct file *file, const char __user *buf,
++ size_t length, loff_t *ppos)
++{
++ char *buffer, *s, *value_str, *setting_str;
++ int err, value;
++ struct debug_name *elem = NULL;
++ int all = 0;
++
++ if (length > PAGE_SIZE || length < 0)
++ return -EINVAL;
++
++ buffer = (char *)__get_free_page(GFP_KERNEL);
++ if (!buffer)
++ return -ENOMEM;
++
++ err = -EFAULT;
++ if (copy_from_user(buffer, buf, length))
++ goto out;
++
++ err = -EINVAL;
++ if (length < PAGE_SIZE)
++ buffer[length] = '\0';
++ else if (buffer[PAGE_SIZE-1])
++ goto out;
++
++ err = -EINVAL;
++ down(&debug_list_mutex);
++
++ if (strncmp("set", buffer, 3))
++ goto out_up;
++ s = buffer + 3;
++ setting_str = strsep(&s, "=");
++ if (s == NULL)
++ goto out_up;
++ setting_str = strstrip(setting_str);
++ value_str = strsep(&s, " ");
++ if (s == NULL)
++ goto out_up;
++ s = strstrip(s);
++ if (!strncmp(s, "all", 3))
++ all = 1;
++ else
++ elem = find_debug_module(s);
++ if (!strncmp(setting_str, "enable", 6)) {
++ value = !!simple_strtol(value_str, NULL, 10);
++ if (all) {
++ if (value) {
++ set_all(true);
++ num_enabled = nr_entries;
++ dynamic_enabled = DYNAMIC_ENABLED_ALL;
++ } else {
++ set_all(false);
++ num_enabled = 0;
++ dynamic_enabled = DYNAMIC_ENABLED_NONE;
++ }
++ err = 0;
++ } else {
++ if (elem) {
++ if (value && (elem->enable == 0)) {
++ dynamic_printk_enabled |=
++ (1LL << elem->hash1);
++ dynamic_printk_enabled2 |=
++ (1LL << elem->hash2);
++ elem->enable = 1;
++ num_enabled++;
++ dynamic_enabled = DYNAMIC_ENABLED_SOME;
++ err = 0;
++ } else if (!value && (elem->enable == 1)) {
++ elem->enable = 0;
++ num_enabled--;
++ if (disabled_hash(elem->hash1, true))
++ dynamic_printk_enabled &=
++ ~(1LL << elem->hash1);
++ if (disabled_hash(elem->hash2, false))
++ dynamic_printk_enabled2 &=
++ ~(1LL << elem->hash2);
++ if (num_enabled)
++ dynamic_enabled =
++ DYNAMIC_ENABLED_SOME;
++ else
++ dynamic_enabled =
++ DYNAMIC_ENABLED_NONE;
++ err = 0;
++ }
++ }
++ }
++ }
++ if (!err)
++ err = length;
++out_up:
++ up(&debug_list_mutex);
++out:
++ free_page((unsigned long)buffer);
++ return err;
++}
++
++static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
++{
++ return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
++}
++
++static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
++{
++ (*pos)++;
++ if (*pos >= DEBUG_HASH_TABLE_SIZE)
++ return NULL;
++ return pos;
++}
++
++static void pr_debug_seq_stop(struct seq_file *s, void *v)
++{
++ /* Nothing to do */
++}
++
++static int pr_debug_seq_show(struct seq_file *s, void *v)
++{
++ struct hlist_head *head;
++ struct hlist_node *node;
++ struct debug_name *elem;
++ unsigned int i = *(loff_t *) v;
++
++ rcu_read_lock();
++ head = &module_table[i];
++ hlist_for_each_entry_rcu(elem, node, head, hlist) {
++ seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
++ seq_printf(s, "\n");
++ }
++ rcu_read_unlock();
++ return 0;
++}
++
++static struct seq_operations pr_debug_seq_ops = {
++ .start = pr_debug_seq_start,
++ .next = pr_debug_seq_next,
++ .stop = pr_debug_seq_stop,
++ .show = pr_debug_seq_show
++};
++
++static int pr_debug_open(struct inode *inode, struct file *filp)
++{
++ return seq_open(filp, &pr_debug_seq_ops);
++}
++
++static const struct file_operations pr_debug_operations = {
++ .open = pr_debug_open,
++ .read = seq_read,
++ .write = pr_debug_write,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int __init dynamic_printk_init(void)
++{
++ struct dentry *dir, *file;
++ struct mod_debug *iter;
++ unsigned long value;
++
++ dir = debugfs_create_dir("dynamic_printk", NULL);
++ if (!dir)
++ return -ENOMEM;
++ file = debugfs_create_file("modules", 0644, dir, NULL,
++ &pr_debug_operations);
++ if (!file) {
++ debugfs_remove(dir);
++ return -ENOMEM;
++ }
++ for (value = (unsigned long)__start___verbose;
++ value < (unsigned long)__stop___verbose;
++ value += sizeof(struct mod_debug)) {
++ iter = (struct mod_debug *)value;
++ register_dynamic_debug_module(iter->modname,
++ iter->type,
++ iter->logical_modname,
++ iter->flag_names, iter->hash, iter->hash2);
++ }
++ return 0;
++}
++module_init(dynamic_printk_init);
++/* may want to move this earlier so we can get traces as early as possible */
++
++static int __init dynamic_printk_setup(char *str)
++{
++ if (str)
++ return -ENOENT;
++ set_all(true);
++ return 0;
++}
++/* Use early_param(), so we can get debug output as early as possible */
++early_param("dynamic_printk", dynamic_printk_setup);
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -744,6 +744,61 @@ menuconfig BUILD_DOCSRC
+
+ Say N if you are unsure.
+
++config DYNAMIC_PRINTK_DEBUG
++ bool "Enable dynamic printk() call support"
++ default n
++ depends on PRINTK
++ select PRINTK_DEBUG
++ help
++
++ Compiles debug level messages into the kernel, which would not
++ otherwise be available at runtime. These messages can then be
++ enabled/disabled on a per module basis. This mechanism implicitly
++ enables all pr_debug() and dev_dbg() calls. The impact of this
++ compile option is a larger kernel text size of about 2%.
++
++ Usage:
++
++ Dynamic debugging is controlled by the debugfs file,
++ dynamic_printk/modules. This file contains a list of the modules that
++ can be enabled. The format of the file is the module name, followed
++ by a set of flags that can be enabled. The first flag is always the
++ 'enabled' flag. For example:
++
++ <module_name> <enabled=0/1>
++ .
++ .
++ .
++
++ <module_name> : Name of the module in which the debug call resides
++ <enabled=0/1> : whether the messages are enabled or not
++
++ From a live system:
++
++ snd_hda_intel enabled=0
++ fixup enabled=0
++ driver enabled=0
++
++ Enable a module:
++
++ $echo "set enabled=1 <module_name>" > dynamic_printk/modules
++
++ Disable a module:
++
++ $echo "set enabled=0 <module_name>" > dynamic_printk/modules
++
++ Enable all modules:
++
++ $echo "set enabled=1 all" > dynamic_printk/modules
++
++ Disable all modules:
++
++ $echo "set enabled=0 all" > dynamic_printk/modules
++
++ Finally, passing "dynamic_printk" at the command line enables
++ debugging for all modules. This mode can be turned off via the above
++ disable command.
++
+ source "samples/Kconfig"
+
+ source "lib/Kconfig.kgdb"
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -80,6 +80,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
+
+ obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
+
++obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
++
+ hostprogs-y := gen_crc32table
+ clean-files := crc32table.h
+
+--- a/net/netfilter/nf_conntrack_pptp.c
++++ b/net/netfilter/nf_conntrack_pptp.c
+@@ -65,7 +65,7 @@ void
+ struct nf_conntrack_expect *exp) __read_mostly;
+ EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
+
+-#ifdef DEBUG
++#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+ /* PptpControlMessageType names */
+ const char *const pptp_msg_name[] = {
+ "UNKNOWN_MESSAGE",
+--- /dev/null
++++ b/scripts/basic/hash.c
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define DYNAMIC_DEBUG_HASH_BITS 6
++
++static const char *program;
++
++static void usage(void)
++{
++ printf("Usage: %s <djb2|r5> <modname>\n", program);
++ exit(1);
++}
++
++/* djb2 hashing algorithm by Dan Bernstein. From:
++ * http://www.cse.yorku.ca/~oz/hash.html
++ */
++
++unsigned int djb2_hash(char *str)
++{
++ unsigned long hash = 5381;
++ int c;
++
++ c = *str;
++ while (c) {
++ hash = ((hash << 5) + hash) + c;
++ c = *++str;
++ }
++ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
++}
++
++unsigned int r5_hash(char *str)
++{
++ unsigned long hash = 0;
++ int c;
++
++ c = *str;
++ while (c) {
++ hash = (hash + (c << 4) + (c >> 4)) * 11;
++ c = *++str;
++ }
++ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
++}
++
++int main(int argc, char *argv[])
++{
++ program = argv[0];
++
++ if (argc != 3)
++ usage();
++ if (!strcmp(argv[1], "djb2"))
++ printf("%d\n", djb2_hash(argv[2]));
++ else if (!strcmp(argv[1], "r5"))
++ printf("%d\n", r5_hash(argv[2]));
++ else
++ usage();
++ exit(0);
++}
++
+--- a/scripts/basic/Makefile
++++ b/scripts/basic/Makefile
+@@ -9,7 +9,7 @@
+ # fixdep: Used to generate dependency information during build process
+ # docproc: Used in Documentation/DocBook
+
+-hostprogs-y := fixdep docproc
++hostprogs-y := fixdep docproc hash
+ always := $(hostprogs-y)
+
+ # fixdep is needed to compile other host programs
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUI
+ modname_flags = $(if $(filter 1,$(words $(modname))),\
+ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
+
++#hash values
++ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
++debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
++ -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
++else
++debug_flags =
++endif
++
+ orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
+ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
+ _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
+@@ -121,7 +129,8 @@ endif
+
+ c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
+ $(__c_flags) $(modkern_cflags) \
+- -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
++ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
++ $(debug_flags)
+
+ a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
+ $(__a_flags) $(modkern_aflags)
diff --git a/f.patch b/f.patch
new file mode 100644
index 00000000000000..e5c817387d7814
--- /dev/null
+++ b/f.patch
@@ -0,0 +1,102 @@
+---
+ drivers/usb/gadget/Makefile | 4 ++--
+ drivers/usb/gadget/cdc2.c | 6 +++++-
+ drivers/usb/gadget/ether.c | 2 +-
+ drivers/usb/gadget/u_ether.c | 14 +++++++-------
+ 4 files changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -19,11 +19,15 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++#include "u_ether.c"
++#include "f_ecm.c"
++#undef DRIVER_VERSION
++
+ #include <linux/kernel.h>
+ #include <linux/utsname.h>
+
+-#include "u_ether.h"
+ #include "u_serial.h"
++#include "u_ether.h"
+
+
+ #define DRIVER_DESC "CDC Composite Gadget"
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -25,7 +25,7 @@
+ #include <linux/kernel.h>
+ #include <linux/utsname.h>
+
+-#include "u_ether.h"
++#include "u_ether.c"
+
+
+ /*
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -25,7 +25,7 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ C_UTILS = composite.o usbstring.o config.o epautoconf.o
+
+ g_zero-objs := zero.o f_sourcesink.o f_loopback.o $(C_UTILS)
+-g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS)
++g_ether-objs := ether.o f_subset.o f_ecm.o $(C_UTILS)
+ g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS)
+ g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o
+ gadgetfs-objs := inode.o
+@@ -33,7 +33,7 @@ g_file_storage-objs := file_storage.o u
+ epautoconf.o
+ g_printer-objs := printer.o usbstring.o config.o \
+ epautoconf.o
+-g_cdc-objs := cdc2.o u_ether.o f_ecm.o \
++g_cdc-objs := cdc2.o f_ecm.o \
+ u_serial.o f_acm.o $(C_UTILS)
+
+ ifeq ($(CONFIG_USB_ETH_RNDIS),y)
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -115,8 +115,8 @@ static inline int qlen(struct usb_gadget
+
+ #undef DBG
+ #undef VDBG
+-#undef ERROR
+-#undef INFO
++#undef ether_ERROR
++#undef ether_INFO
+
+ #define xprintk(d, level, fmt, args...) \
+ printk(level "%s: " fmt , (d)->net->name , ## args)
+@@ -137,9 +137,9 @@ static inline int qlen(struct usb_gadget
+ do { } while (0)
+ #endif /* DEBUG */
+
+-#define ERROR(dev, fmt, args...) \
++#define ether_ERROR(dev, fmt, args...) \
+ xprintk(dev , KERN_ERR , fmt , ## args)
+-#define INFO(dev, fmt, args...) \
++#define ether_INFO(dev, fmt, args...) \
+ xprintk(dev , KERN_INFO , fmt , ## args)
+
+ /*-------------------------------------------------------------------------*/
+@@ -197,7 +197,7 @@ static void defer_kevent(struct eth_dev
+ if (test_and_set_bit(flag, &dev->todo))
+ return;
+ if (!schedule_work(&dev->work))
+- ERROR(dev, "kevent %d may have been dropped\n", flag);
++ ether_ERROR(dev, "kevent %d may have been dropped\n", flag);
+ else
+ DBG(dev, "kevent %d scheduled\n", flag);
+ }
+@@ -789,8 +789,8 @@ int __init gether_setup(struct usb_gadge
+ } else {
+ DECLARE_MAC_BUF(tmp);
+
+- INFO(dev, "MAC %s\n", print_mac(tmp, net->dev_addr));
+- INFO(dev, "HOST MAC %s\n", print_mac(tmp, dev->host_mac));
++ ether_INFO(dev, "MAC %s\n", print_mac(tmp, net->dev_addr));
++ ether_INFO(dev, "HOST MAC %s\n", print_mac(tmp, dev->host_mac));
+
+ the_dev = dev;
+ }
diff --git a/f2.patch b/f2.patch
new file mode 100644
index 00000000000000..6aa21a6ddab2fb
--- /dev/null
+++ b/f2.patch
@@ -0,0 +1,188 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Wed, 13 Aug 2008 20:08:35 -0700
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: USB gadget: make g_util.ko
+
+This moves the "C_UTILS" files in the USB gadget subsystem into a common
+kernel module. This solves a number of kernel build issues (same .o
+file being included into multiple .ko, etc.)
+
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/Makefile | 34 +++++++++++++++++-----------------
+ drivers/usb/gadget/composite.c | 20 ++++++++++++++++++++
+ drivers/usb/gadget/config.c | 5 ++++-
+ drivers/usb/gadget/epautoconf.c | 2 ++
+ drivers/usb/gadget/usbstring.c | 2 +-
+ 5 files changed, 44 insertions(+), 19 deletions(-)
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -126,6 +126,7 @@ done:
+ function->name, function, value);
+ return value;
+ }
++EXPORT_SYMBOL_GPL(usb_add_function);
+
+ /**
+ * usb_interface_id() - allocate an unused interface ID
+@@ -162,6 +163,7 @@ int __init usb_interface_id(struct usb_c
+ }
+ return -ENODEV;
+ }
++EXPORT_SYMBOL_GPL(usb_interface_id);
+
+ static int config_buf(struct usb_configuration *config,
+ enum usb_device_speed speed, void *buf, u8 type)
+@@ -452,6 +454,7 @@ done:
+ config->bConfigurationValue, status);
+ return status;
+ }
++EXPORT_SYMBOL_GPL(usb_add_config);
+
+ /*-------------------------------------------------------------------------*/
+
+@@ -594,6 +597,7 @@ int __init usb_string_id(struct usb_comp
+ }
+ return -ENODEV;
+ }
++EXPORT_SYMBOL_GPL(usb_string_id);
+
+ /*-------------------------------------------------------------------------*/
+
+@@ -1025,6 +1029,7 @@ int __init usb_composite_register(struct
+
+ return usb_gadget_register_driver(&composite_driver);
+ }
++EXPORT_SYMBOL_GPL(usb_composite_register);
+
+ /**
+ * usb_composite_unregister() - unregister a composite driver
+@@ -1039,3 +1044,18 @@ void __exit usb_composite_unregister(str
+ return;
+ usb_gadget_unregister_driver(&composite_driver);
+ }
++EXPORT_SYMBOL_GPL(usb_composite_unregister);
++
++static int __init composite_init(void)
++{
++ return 0;
++}
++
++static void __exit composite_exit(void)
++{
++}
++
++module_init(composite_init);
++module_exit(composite_exit);
++
++MODULE_LICENSE("GPL");
+--- a/drivers/usb/gadget/config.c
++++ b/drivers/usb/gadget/config.c
+@@ -61,7 +61,7 @@ usb_descriptor_fillbuf(void *buf, unsign
+ }
+ return dest - (u8 *)buf;
+ }
+-
++EXPORT_SYMBOL_GPL(usb_descriptor_fillbuf);
+
+ /**
+ * usb_gadget_config_buf - builts a complete configuration descriptor
+@@ -114,6 +114,7 @@ int usb_gadget_config_buf(
+ cp->bmAttributes |= USB_CONFIG_ATT_ONE;
+ return len;
+ }
++EXPORT_SYMBOL_GPL(usb_gadget_config_buf);
+
+ /**
+ * usb_copy_descriptors - copy a vector of USB descriptors
+@@ -163,6 +164,7 @@ usb_copy_descriptors(struct usb_descript
+
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(usb_copy_descriptors);
+
+ /**
+ * usb_find_endpoint - find a copy of an endpoint descriptor
+@@ -189,3 +191,4 @@ usb_find_endpoint(
+ }
+ return NULL;
+ }
++EXPORT_SYMBOL_GPL(usb_find_endpoint);
+--- a/drivers/usb/gadget/epautoconf.c
++++ b/drivers/usb/gadget/epautoconf.c
+@@ -286,6 +286,7 @@ struct usb_ep * __init usb_ep_autoconfig
+ /* Fail */
+ return NULL;
+ }
++EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
+
+ /**
+ * usb_ep_autoconfig_reset - reset endpoint autoconfig state
+@@ -308,4 +309,5 @@ void __init usb_ep_autoconfig_reset (str
+ #endif
+ epnum = 0;
+ }
++EXPORT_SYMBOL_GPL(usb_ep_autoconfig_reset);
+
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -22,30 +22,30 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ #
+ # USB gadget drivers
+ #
+-C_UTILS = composite.o usbstring.o config.o epautoconf.o
+
+-g_zero-objs := zero.o f_sourcesink.o f_loopback.o $(C_UTILS)
+-g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS)
+-g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS)
+-g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o
+-gadgetfs-objs := inode.o
+-g_file_storage-objs := file_storage.o usbstring.o config.o \
+- epautoconf.o
+-g_printer-objs := printer.o usbstring.o config.o \
++g_utils-objs := composite.o usbstring.o config.o \
+ epautoconf.o
++
++g_zero-objs := zero.o f_sourcesink.o f_loopback.o
++g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o
++g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o
++g_midi-objs := gmidi.o
++gadgetfs-objs := inode.o
++g_file_storage-objs := file_storage.o
++g_printer-objs := printer.o
+ g_cdc-objs := cdc2.o u_ether.o f_ecm.o \
+- u_serial.o f_acm.o $(C_UTILS)
++ u_serial.o f_acm.o
+
+ ifeq ($(CONFIG_USB_ETH_RNDIS),y)
+ g_ether-objs += f_rndis.o rndis.o
+ endif
+
+-obj-$(CONFIG_USB_ZERO) += g_zero.o
+-obj-$(CONFIG_USB_ETH) += g_ether.o
++obj-$(CONFIG_USB_ZERO) += g_zero.o g_utils.o
++obj-$(CONFIG_USB_ETH) += g_ether.o g_utils.o
+ obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
+-obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o
+-obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
+-obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
+-obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
+-obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
++obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o g_utils.o
++obj-$(CONFIG_USB_G_SERIAL) += g_serial.o g_utils.o
++obj-$(CONFIG_USB_G_PRINTER) += g_printer.o g_utils.o
++obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o g_utils.o
++obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o g_utils.o
+
+--- a/drivers/usb/gadget/usbstring.c
++++ b/drivers/usb/gadget/usbstring.c
+@@ -133,4 +133,4 @@ usb_gadget_get_string (struct usb_gadget
+ buf [1] = USB_DT_STRING;
+ return buf [0];
+ }
+-
++EXPORT_SYMBOL_GPL(usb_gadget_get_string);
diff --git a/f3.patch b/f3.patch
new file mode 100644
index 00000000000000..97e019066c7273
--- /dev/null
+++ b/f3.patch
@@ -0,0 +1,71 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Wed, 13 Aug 2008 20:08:35 -0700
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: USB gadget: add u_ether.c to g_util.ko
+
+As u_ether.c is also included in multiple .ko files, move it into
+g_util.ko
+
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/Makefile | 6 +++---
+ drivers/usb/gadget/u_ether.c | 5 ++++-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -24,16 +24,16 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ #
+
+ g_utils-objs := composite.o usbstring.o config.o \
+- epautoconf.o
++ epautoconf.o u_ether.o
+
+ g_zero-objs := zero.o f_sourcesink.o f_loopback.o
+-g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o
++g_ether-objs := ether.o f_subset.o f_ecm.o
+ g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o
+ g_midi-objs := gmidi.o
+ gadgetfs-objs := inode.o
+ g_file_storage-objs := file_storage.o
+ g_printer-objs := printer.o
+-g_cdc-objs := cdc2.o u_ether.o f_ecm.o \
++g_cdc-objs := cdc2.o f_ecm.o \
+ u_serial.o f_acm.o
+
+ ifeq ($(CONFIG_USB_ETH_RNDIS),y)
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -797,6 +797,7 @@ int __init gether_setup(struct usb_gadge
+
+ return status;
+ }
++EXPORT_SYMBOL_GPL(gether_setup);
+
+ /**
+ * gether_cleanup - remove Ethernet-over-USB device
+@@ -817,7 +818,7 @@ void gether_cleanup(void)
+
+ the_dev = NULL;
+ }
+-
++EXPORT_SYMBOL_GPL(gether_cleanup);
+
+ /**
+ * gether_connect - notify network layer that USB link is active
+@@ -891,6 +892,7 @@ fail0:
+ return ERR_PTR(result);
+ return dev->net;
+ }
++EXPORT_SYMBOL_GPL(gether_connect);
+
+ /**
+ * gether_disconnect - notify network layer that USB link is inactive
+@@ -962,3 +964,4 @@ void gether_disconnect(struct gether *li
+ link->ioport = NULL;
+ spin_unlock(&dev->lock);
+ }
++EXPORT_SYMBOL_GPL(gether_disconnect);
diff --git a/f4.patch b/f4.patch
new file mode 100644
index 00000000000000..b880f2cee29a28
--- /dev/null
+++ b/f4.patch
@@ -0,0 +1,55 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Wed, 13 Aug 2008 20:08:35 -0700
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: USB gadget: add f_ecm.c to g_util.ko
+
+As f_ecm.c is also included in multiple .ko files, move it into
+g_util.ko
+
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/Makefile | 7 +++----
+ drivers/usb/gadget/f_ecm.c | 2 ++
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -734,6 +734,7 @@ fail:
+
+ return status;
+ }
++EXPORT_SYMBOL_GPL(ecm_bind);
+
+ static void
+ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
+@@ -829,3 +830,4 @@ int __init ecm_bind_config(struct usb_co
+ }
+ return status;
+ }
++EXPORT_SYMBOL_GPL(ecm_bind_config);
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -24,17 +24,16 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ #
+
+ g_utils-objs := composite.o usbstring.o config.o \
+- epautoconf.o u_ether.o
++ epautoconf.o u_ether.o f_ecm.o
+
+ g_zero-objs := zero.o f_sourcesink.o f_loopback.o
+-g_ether-objs := ether.o f_subset.o f_ecm.o
++g_ether-objs := ether.o f_subset.o
+ g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o
+ g_midi-objs := gmidi.o
+ gadgetfs-objs := inode.o
+ g_file_storage-objs := file_storage.o
+ g_printer-objs := printer.o
+-g_cdc-objs := cdc2.o f_ecm.o \
+- u_serial.o f_acm.o
++g_cdc-objs := cdc2.o u_serial.o f_acm.o
+
+ ifeq ($(CONFIG_USB_ETH_RNDIS),y)
+ g_ether-objs += f_rndis.o rndis.o
diff --git a/f5.patch b/f5.patch
new file mode 100644
index 00000000000000..075f98c4dcf6a7
--- /dev/null
+++ b/f5.patch
@@ -0,0 +1,87 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Wed, 13 Aug 2008 20:08:35 -0700
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: USB gadget: add f_acm.c and u_serial.c to g_util.ko
+
+As f_acm.c and u_serial.c are also included in multiple .ko files, move
+it into g_util.ko
+
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/Makefile | 7 ++++---
+ drivers/usb/gadget/f_acm.c | 2 ++
+ drivers/usb/gadget/u_serial.c | 4 ++++
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/f_acm.c
++++ b/drivers/usb/gadget/f_acm.c
+@@ -661,6 +661,7 @@ fail:
+
+ return status;
+ }
++EXPORT_SYMBOL_GPL(acm_bind);
+
+ static void
+ acm_unbind(struct usb_configuration *c, struct usb_function *f)
+@@ -757,3 +758,4 @@ int __init acm_bind_config(struct usb_co
+ kfree(acm);
+ return status;
+ }
++EXPORT_SYMBOL_GPL(acm_bind_config);
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -24,16 +24,17 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ #
+
+ g_utils-objs := composite.o usbstring.o config.o \
+- epautoconf.o u_ether.o f_ecm.o
++ epautoconf.o u_ether.o f_ecm.o \
++ f_acm.o u_serial.o
+
+ g_zero-objs := zero.o f_sourcesink.o f_loopback.o
+ g_ether-objs := ether.o f_subset.o
+-g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o
++g_serial-objs := serial.o f_serial.o
+ g_midi-objs := gmidi.o
+ gadgetfs-objs := inode.o
+ g_file_storage-objs := file_storage.o
+ g_printer-objs := printer.o
+-g_cdc-objs := cdc2.o u_serial.o f_acm.o
++g_cdc-objs := cdc2.o
+
+ ifeq ($(CONFIG_USB_ETH_RNDIS),y)
+ g_ether-objs += f_rndis.o rndis.o
+--- a/drivers/usb/gadget/u_serial.c
++++ b/drivers/usb/gadget/u_serial.c
+@@ -1140,6 +1140,7 @@ fail:
+ gs_tty_driver = NULL;
+ return status;
+ }
++EXPORT_SYMBOL_GPL(gserial_setup);
+
+ static int gs_closed(struct gs_port *port)
+ {
+@@ -1198,6 +1199,7 @@ void gserial_cleanup(void)
+
+ pr_debug("%s: cleaned up ttyGS* support\n", __func__);
+ }
++EXPORT_SYMBOL_GPL(gserial_cleanup);
+
+ /**
+ * gserial_connect - notify TTY I/O glue that USB link is active
+@@ -1277,6 +1279,7 @@ fail_out:
+ gser->in->driver_data = NULL;
+ return status;
+ }
++EXPORT_SYMBOL_GPL(gserial_connect);
+
+ /**
+ * gserial_disconnect - notify TTY I/O glue that USB link is inactive
+@@ -1328,3 +1331,4 @@ void gserial_disconnect(struct gserial *
+ gs_free_requests(gser->in, &port->write_pool);
+ spin_unlock_irqrestore(&port->port_lock, flags);
+ }
++EXPORT_SYMBOL_GPL(gserial_disconnect);
diff --git a/series b/series
index 81013f343a525f..27d60b836a9a3c 100644
--- a/series
+++ b/series
@@ -169,5 +169,9 @@ usb/usb-gotemp.patch
#ns/module-usb-serial.patch
#ns/modpost
+f2.patch
+f3.patch
+f4.patch
+f5.patch
driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch