extern __printf(2, 3)
int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
+extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
+ const char *modname);
+
struct device;
extern __printf(3, 4)
#else
+#include <linux/string.h>
+#include <linux/errno.h>
+
static inline int ddebug_remove_module(const char *mod)
{
return 0;
}
+static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
+ const char *modname)
+{
+ if (strstr(param, "dyndbg")) {
+ pr_warn("dyndbg supported only in "
+ "CONFIG_DYNAMIC_DEBUG builds\n");
+ return 0; /* allow and ignore */
+ }
+ return -EINVAL;
+}
+
#define dynamic_pr_debug(fmt, ...) \
do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
#define dynamic_dev_dbg(dev, fmt, ...) \
}
EXPORT_SYMBOL_GPL(ddebug_add_module);
+/* handle both dyndbg=".." and $module.dyndbg=".." params at boot */
+static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
+ const char *unused)
+{
+ const char *modname = NULL;
+ char *sep;
+
+ sep = strchr(param, '.');
+ if (sep) {
+ *sep = '\0';
+ modname = param;
+ param = sep + 1;
+ }
+ if (strcmp(param, "dyndbg"))
+ return 0; /* skip all other params w/o error */
+
+ vpr_info("module: %s %s=\"%s\"\n", modname, param, val);
+
+ ddebug_exec_queries(val ? val : "+p");
+ return 0; /* query failure shouldnt stop module load */
+}
+
+/* handle dyndbg args to modprobe */
+int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *doing)
+{
+ if (strcmp(param, "dyndbg"))
+ return -ENOENT;
+
+ vpr_info("module: %s %s=\"%s\"\n", doing, param, val);
+
+ ddebug_exec_queries((val ? val : "+p"));
+
+ return 0; /* query failure shouldnt stop module load */
+}
+
static void ddebug_table_free(struct ddebug_table *dt)
{
list_del_init(&dt->link);
{
struct _ddebug *iter, *iter_start;
const char *modname = NULL;
+ char *cmdline;
int ret = 0;
int n = 0;
/* keep tables even on ddebug_query parse error */
ret = 0;
}
+ /* now that ddebug tables are loaded, process all boot args
+ * again to find and activate queries given in dyndbg params.
+ * While this has already been done for known boot params, it
+ * ignored the unknown ones (dyndbg in particular). Reusing
+ * parse_args avoids ad-hoc parsing. This will also attempt
+ * to activate queries for not-yet-loaded modules, which is
+ * slightly noisy if verbose, but harmless.
+ */
+ cmdline = kstrdup(saved_command_line, GFP_KERNEL);
+ parse_args("dyndbg params", cmdline, NULL,
+ 0, 0, 0, &ddebug_dyndbg_boot_param_cb);
+ kfree(cmdline);
out_free:
if (ret)
}
/* Allow early initialization for boot messages via boot param */
arch_initcall(dynamic_debug_init);
+
/* Debugfs setup must be done later */
module_init(dynamic_debug_init_debugfs);