diff options
Diffstat (limited to 'lib/dynamic_debug.c')
-rw-r--r-- | lib/dynamic_debug.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 8675717c0f16..8fba40179305 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -862,6 +862,41 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, | |||
862 | } | 862 | } |
863 | EXPORT_SYMBOL_GPL(ddebug_add_module); | 863 | EXPORT_SYMBOL_GPL(ddebug_add_module); |
864 | 864 | ||
865 | /* handle both dyndbg=".." and $module.dyndbg=".." params at boot */ | ||
866 | static int ddebug_dyndbg_boot_param_cb(char *param, char *val, | ||
867 | const char *unused) | ||
868 | { | ||
869 | const char *modname = NULL; | ||
870 | char *sep; | ||
871 | |||
872 | sep = strchr(param, '.'); | ||
873 | if (sep) { | ||
874 | *sep = '\0'; | ||
875 | modname = param; | ||
876 | param = sep + 1; | ||
877 | } | ||
878 | if (strcmp(param, "dyndbg")) | ||
879 | return 0; /* skip all other params w/o error */ | ||
880 | |||
881 | vpr_info("module: %s %s=\"%s\"\n", modname, param, val); | ||
882 | |||
883 | ddebug_exec_queries(val ? val : "+p"); | ||
884 | return 0; /* query failure shouldnt stop module load */ | ||
885 | } | ||
886 | |||
887 | /* handle dyndbg args to modprobe */ | ||
888 | int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *doing) | ||
889 | { | ||
890 | if (strcmp(param, "dyndbg")) | ||
891 | return -ENOENT; | ||
892 | |||
893 | vpr_info("module: %s %s=\"%s\"\n", doing, param, val); | ||
894 | |||
895 | ddebug_exec_queries((val ? val : "+p")); | ||
896 | |||
897 | return 0; /* query failure shouldnt stop module load */ | ||
898 | } | ||
899 | |||
865 | static void ddebug_table_free(struct ddebug_table *dt) | 900 | static void ddebug_table_free(struct ddebug_table *dt) |
866 | { | 901 | { |
867 | list_del_init(&dt->link); | 902 | list_del_init(&dt->link); |
@@ -929,6 +964,7 @@ static int __init dynamic_debug_init(void) | |||
929 | { | 964 | { |
930 | struct _ddebug *iter, *iter_start; | 965 | struct _ddebug *iter, *iter_start; |
931 | const char *modname = NULL; | 966 | const char *modname = NULL; |
967 | char *cmdline; | ||
932 | int ret = 0; | 968 | int ret = 0; |
933 | int n = 0; | 969 | int n = 0; |
934 | 970 | ||
@@ -967,6 +1003,18 @@ static int __init dynamic_debug_init(void) | |||
967 | /* keep tables even on ddebug_query parse error */ | 1003 | /* keep tables even on ddebug_query parse error */ |
968 | ret = 0; | 1004 | ret = 0; |
969 | } | 1005 | } |
1006 | /* now that ddebug tables are loaded, process all boot args | ||
1007 | * again to find and activate queries given in dyndbg params. | ||
1008 | * While this has already been done for known boot params, it | ||
1009 | * ignored the unknown ones (dyndbg in particular). Reusing | ||
1010 | * parse_args avoids ad-hoc parsing. This will also attempt | ||
1011 | * to activate queries for not-yet-loaded modules, which is | ||
1012 | * slightly noisy if verbose, but harmless. | ||
1013 | */ | ||
1014 | cmdline = kstrdup(saved_command_line, GFP_KERNEL); | ||
1015 | parse_args("dyndbg params", cmdline, NULL, | ||
1016 | 0, 0, 0, &ddebug_dyndbg_boot_param_cb); | ||
1017 | kfree(cmdline); | ||
970 | 1018 | ||
971 | out_free: | 1019 | out_free: |
972 | if (ret) | 1020 | if (ret) |
@@ -977,5 +1025,6 @@ out_free: | |||
977 | } | 1025 | } |
978 | /* Allow early initialization for boot messages via boot param */ | 1026 | /* Allow early initialization for boot messages via boot param */ |
979 | arch_initcall(dynamic_debug_init); | 1027 | arch_initcall(dynamic_debug_init); |
1028 | |||
980 | /* Debugfs setup must be done later */ | 1029 | /* Debugfs setup must be done later */ |
981 | module_init(dynamic_debug_init_debugfs); | 1030 | module_init(dynamic_debug_init_debugfs); |