1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2e9d376f0SJason Baron #ifndef _DYNAMIC_DEBUG_H
3e9d376f0SJason Baron #define _DYNAMIC_DEBUG_H
4e9d376f0SJason Baron
5e9666d10SMasahiro Yamada #if defined(CONFIG_JUMP_LABEL)
69049fc74SJason Baron #include <linux/jump_label.h>
79049fc74SJason Baron #endif
89049fc74SJason Baron
9ca90fca7SJim Cromie #include <linux/build_bug.h>
10ca90fca7SJim Cromie
11e9d376f0SJason Baron /*
12e9d376f0SJason Baron * An instance of this structure is created in a special
13e9d376f0SJason Baron * ELF section at every dynamic debug callsite. At runtime,
14e9d376f0SJason Baron * the special section is treated as an array of these.
15e9d376f0SJason Baron */
16e9d376f0SJason Baron struct _ddebug {
17e9d376f0SJason Baron /*
18e9d376f0SJason Baron * These fields are used to drive the user interface
19e9d376f0SJason Baron * for selecting and displaying debug callsites.
20e9d376f0SJason Baron */
21e9d376f0SJason Baron const char *modname;
22e9d376f0SJason Baron const char *function;
23e9d376f0SJason Baron const char *filename;
24e9d376f0SJason Baron const char *format;
25e703ddaeSJim Cromie unsigned int lineno:18;
26ca90fca7SJim Cromie #define CLS_BITS 6
27ca90fca7SJim Cromie unsigned int class_id:CLS_BITS;
28ca90fca7SJim Cromie #define _DPRINTK_CLASS_DFLT ((1 << CLS_BITS) - 1)
29e9d376f0SJason Baron /*
30e9d376f0SJason Baron * The flags field controls the behaviour at the callsite.
31e9d376f0SJason Baron * The bits here are changed dynamically when the user
322b2f68b5SFlorian Ragwitz * writes commands to <debugfs>/dynamic_debug/control
33e9d376f0SJason Baron */
345ca7d2a6SJim Cromie #define _DPRINTK_FLAGS_NONE 0
35e9d376f0SJason Baron #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */
368ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_MODNAME (1<<1)
378ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2)
388ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
398ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_TID (1<<4)
4031ed379bSThomas Weißschuh #define _DPRINTK_FLAGS_INCL_SOURCENAME (1<<5)
41640d1eafSJim Cromie
42640d1eafSJim Cromie #define _DPRINTK_FLAGS_INCL_ANY \
43640d1eafSJim Cromie (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
4431ed379bSThomas Weißschuh _DPRINTK_FLAGS_INCL_LINENO | _DPRINTK_FLAGS_INCL_TID |\
4531ed379bSThomas Weißschuh _DPRINTK_FLAGS_INCL_SOURCENAME)
46640d1eafSJim Cromie
47b558c96fSJim Cromie #if defined DEBUG
48b558c96fSJim Cromie #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
49b558c96fSJim Cromie #else
50e9d376f0SJason Baron #define _DPRINTK_FLAGS_DEFAULT 0
51b558c96fSJim Cromie #endif
52e9d376f0SJason Baron unsigned int flags:8;
53e9666d10SMasahiro Yamada #ifdef CONFIG_JUMP_LABEL
549049fc74SJason Baron union {
559049fc74SJason Baron struct static_key_true dd_key_true;
569049fc74SJason Baron struct static_key_false dd_key_false;
579049fc74SJason Baron } key;
589049fc74SJason Baron #endif
59e9d376f0SJason Baron } __attribute__((aligned(8)));
60e9d376f0SJason Baron
61aad0214fSJim Cromie enum class_map_type {
62aad0214fSJim Cromie DD_CLASS_TYPE_DISJOINT_BITS,
63aad0214fSJim Cromie /**
64aad0214fSJim Cromie * DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, one per bit.
65aad0214fSJim Cromie * expecting hex input. Built for drm.debug, basis for other types.
66aad0214fSJim Cromie */
67aad0214fSJim Cromie DD_CLASS_TYPE_LEVEL_NUM,
68aad0214fSJim Cromie /**
69aad0214fSJim Cromie * DD_CLASS_TYPE_LEVEL_NUM: input is numeric level, 0-N.
70aad0214fSJim Cromie * N turns on just bits N-1 .. 0, so N=0 turns all bits off.
71aad0214fSJim Cromie */
72aad0214fSJim Cromie DD_CLASS_TYPE_DISJOINT_NAMES,
73aad0214fSJim Cromie /**
74aad0214fSJim Cromie * DD_CLASS_TYPE_DISJOINT_NAMES: input is a CSV of [+-]CLASS_NAMES,
75aad0214fSJim Cromie * classes are independent, like _DISJOINT_BITS.
76aad0214fSJim Cromie */
77aad0214fSJim Cromie DD_CLASS_TYPE_LEVEL_NAMES,
78aad0214fSJim Cromie /**
79aad0214fSJim Cromie * DD_CLASS_TYPE_LEVEL_NAMES: input is a CSV of [+-]CLASS_NAMES,
80aad0214fSJim Cromie * intended for names like: INFO,DEBUG,TRACE, with a module prefix
81aad0214fSJim Cromie * avoid EMERG,ALERT,CRIT,ERR,WARNING: they're not debug
82aad0214fSJim Cromie */
83aad0214fSJim Cromie };
84aad0214fSJim Cromie
85aad0214fSJim Cromie struct ddebug_class_map {
86aad0214fSJim Cromie struct list_head link;
87aad0214fSJim Cromie struct module *mod;
88aad0214fSJim Cromie const char *mod_name; /* needed for builtins */
89aad0214fSJim Cromie const char **class_names;
90aad0214fSJim Cromie const int length;
91aad0214fSJim Cromie const int base; /* index of 1st .class_id, allows split/shared space */
92aad0214fSJim Cromie enum class_map_type map_type;
93aad0214fSJim Cromie };
94aad0214fSJim Cromie
95aad0214fSJim Cromie /**
96aad0214fSJim Cromie * DECLARE_DYNDBG_CLASSMAP - declare classnames known by a module
97aad0214fSJim Cromie * @_var: a struct ddebug_class_map, passed to module_param_cb
98aad0214fSJim Cromie * @_type: enum class_map_type, chooses bits/verbose, numeric/symbolic
99aad0214fSJim Cromie * @_base: offset of 1st class-name. splits .class_id space
100aad0214fSJim Cromie * @classes: class-names used to control class'd prdbgs
101aad0214fSJim Cromie */
102aad0214fSJim Cromie #define DECLARE_DYNDBG_CLASSMAP(_var, _maptype, _base, ...) \
103aad0214fSJim Cromie static const char *_var##_classnames[] = { __VA_ARGS__ }; \
104aad0214fSJim Cromie static struct ddebug_class_map __aligned(8) __used \
105aad0214fSJim Cromie __section("__dyndbg_classes") _var = { \
106aad0214fSJim Cromie .mod = THIS_MODULE, \
107aad0214fSJim Cromie .mod_name = KBUILD_MODNAME, \
108aad0214fSJim Cromie .base = _base, \
109aad0214fSJim Cromie .map_type = _maptype, \
110aad0214fSJim Cromie .length = NUM_TYPE_ARGS(char*, __VA_ARGS__), \
111aad0214fSJim Cromie .class_names = _var##_classnames, \
112aad0214fSJim Cromie }
113aad0214fSJim Cromie #define NUM_TYPE_ARGS(eltype, ...) \
114aad0214fSJim Cromie (sizeof((eltype[]){__VA_ARGS__}) / sizeof(eltype))
115aad0214fSJim Cromie
116b7b4eebdSJim Cromie /* encapsulate linker provided built-in (or module) dyndbg data */
117b7b4eebdSJim Cromie struct _ddebug_info {
118b7b4eebdSJim Cromie struct _ddebug *descs;
11966f4006bSJim Cromie struct ddebug_class_map *classes;
120b7b4eebdSJim Cromie unsigned int num_descs;
12166f4006bSJim Cromie unsigned int num_classes;
122b7b4eebdSJim Cromie };
123e9d376f0SJason Baron
124b9400852SJim Cromie struct ddebug_class_param {
125b9400852SJim Cromie union {
126b9400852SJim Cromie unsigned long *bits;
127b9400852SJim Cromie unsigned int *lvl;
128b9400852SJim Cromie };
129b9400852SJim Cromie char flags[8];
130b9400852SJim Cromie const struct ddebug_class_map *map;
131b9400852SJim Cromie };
132b9400852SJim Cromie
1337ce93729SJason Baron /*
1347ce93729SJason Baron * pr_debug() and friends are globally enabled or modules have selectively
1357ce93729SJason Baron * enabled them.
1367ce93729SJason Baron */
1377ce93729SJason Baron #if defined(CONFIG_DYNAMIC_DEBUG) || \
1387ce93729SJason Baron (defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))
139a2d375edSJim Cromie
140b9075fa9SJoe Perches extern __printf(2, 3)
141906d2015SJoe Perches void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
142e9d376f0SJason Baron
143cbc46635SJoe Perches struct device;
144cbc46635SJoe Perches
145b9075fa9SJoe Perches extern __printf(3, 4)
146906d2015SJoe Perches void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev,
147b9075fa9SJoe Perches const char *fmt, ...);
148cbc46635SJoe Perches
149ffa10cb4SJason Baron struct net_device;
150ffa10cb4SJason Baron
151b9075fa9SJoe Perches extern __printf(3, 4)
152906d2015SJoe Perches void __dynamic_netdev_dbg(struct _ddebug *descriptor,
153ffa10cb4SJason Baron const struct net_device *dev,
154b9075fa9SJoe Perches const char *fmt, ...);
155ffa10cb4SJason Baron
156923abb9dSGal Pressman struct ib_device;
157923abb9dSGal Pressman
158923abb9dSGal Pressman extern __printf(3, 4)
159923abb9dSGal Pressman void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
160923abb9dSGal Pressman const struct ib_device *ibdev,
161923abb9dSGal Pressman const char *fmt, ...);
162923abb9dSGal Pressman
163ca90fca7SJim Cromie #define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt) \
164c0d2af63SJoe Perches static struct _ddebug __aligned(8) \
16533def849SJoe Perches __section("__dyndbg") name = { \
16607613b0bSJason Baron .modname = KBUILD_MODNAME, \
16707613b0bSJason Baron .function = __func__, \
16807613b0bSJason Baron .filename = __FILE__, \
16907613b0bSJason Baron .format = (fmt), \
17007613b0bSJason Baron .lineno = __LINE__, \
17107613b0bSJason Baron .flags = _DPRINTK_FLAGS_DEFAULT, \
172ca90fca7SJim Cromie .class_id = cls, \
1732bdde670SRasmus Villemoes _DPRINTK_KEY_INIT \
174ca90fca7SJim Cromie }; \
175ca90fca7SJim Cromie BUILD_BUG_ON_MSG(cls > _DPRINTK_CLASS_DFLT, \
176ca90fca7SJim Cromie "classid value overflow")
177ca90fca7SJim Cromie
178ca90fca7SJim Cromie #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
179ca90fca7SJim Cromie DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, _DPRINTK_CLASS_DFLT, fmt)
18007613b0bSJason Baron
181e9666d10SMasahiro Yamada #ifdef CONFIG_JUMP_LABEL
1829049fc74SJason Baron
1839049fc74SJason Baron #ifdef DEBUG
1842bdde670SRasmus Villemoes
1852bdde670SRasmus Villemoes #define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)
1869049fc74SJason Baron
1879049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \
1889049fc74SJason Baron static_branch_likely(&descriptor.key.dd_key_true)
1899049fc74SJason Baron #else
1902bdde670SRasmus Villemoes #define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
1919049fc74SJason Baron
1929049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \
1939049fc74SJason Baron static_branch_unlikely(&descriptor.key.dd_key_false)
1949049fc74SJason Baron #endif
1959049fc74SJason Baron
196a2d375edSJim Cromie #else /* !CONFIG_JUMP_LABEL */
1979049fc74SJason Baron
1982bdde670SRasmus Villemoes #define _DPRINTK_KEY_INIT
1999049fc74SJason Baron
2009049fc74SJason Baron #ifdef DEBUG
2019049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \
2029049fc74SJason Baron likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
2039049fc74SJason Baron #else
2049049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \
2059049fc74SJason Baron unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
2069049fc74SJason Baron #endif
2079049fc74SJason Baron
208a2d375edSJim Cromie #endif /* CONFIG_JUMP_LABEL */
2099049fc74SJason Baron
210ca90fca7SJim Cromie /*
211ca90fca7SJim Cromie * Factory macros: ($prefix)dynamic_func_call($suffix)
212ca90fca7SJim Cromie *
213ca90fca7SJim Cromie * Lower layer (with __ prefix) gets the callsite metadata, and wraps
214ca90fca7SJim Cromie * the func inside a debug-branch/static-key construct. Upper layer
215ca90fca7SJim Cromie * (with _ prefix) does the UNIQUE_ID once, so that lower can ref the
216ca90fca7SJim Cromie * name/label multiple times, and tie the elements together.
217ca90fca7SJim Cromie * Multiple flavors:
218ca90fca7SJim Cromie * (|_cls): adds in _DPRINT_CLASS_DFLT as needed
219ca90fca7SJim Cromie * (|_no_desc): former gets callsite descriptor as 1st arg (for prdbgs)
220ca90fca7SJim Cromie */
221ca90fca7SJim Cromie #define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \
222ca90fca7SJim Cromie DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
22347cdd64bSRasmus Villemoes if (DYNAMIC_DEBUG_BRANCH(id)) \
22447cdd64bSRasmus Villemoes func(&id, ##__VA_ARGS__); \
225e9d376f0SJason Baron } while (0)
226ca90fca7SJim Cromie #define __dynamic_func_call(id, fmt, func, ...) \
227ca90fca7SJim Cromie __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt, \
228ca90fca7SJim Cromie func, ##__VA_ARGS__)
229e9d376f0SJason Baron
230ca90fca7SJim Cromie #define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do { \
231ca90fca7SJim Cromie DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
23247cdd64bSRasmus Villemoes if (DYNAMIC_DEBUG_BRANCH(id)) \
23347cdd64bSRasmus Villemoes func(__VA_ARGS__); \
23447cdd64bSRasmus Villemoes } while (0)
235ca90fca7SJim Cromie #define __dynamic_func_call_no_desc(id, fmt, func, ...) \
236ca90fca7SJim Cromie __dynamic_func_call_cls_no_desc(id, _DPRINTK_CLASS_DFLT, \
237ca90fca7SJim Cromie fmt, func, ##__VA_ARGS__)
23847cdd64bSRasmus Villemoes
23947cdd64bSRasmus Villemoes /*
24047cdd64bSRasmus Villemoes * "Factory macro" for generating a call to func, guarded by a
241e5ebffe1SJim Cromie * DYNAMIC_DEBUG_BRANCH. The dynamic debug descriptor will be
24247cdd64bSRasmus Villemoes * initialized using the fmt argument. The function will be called with
24347cdd64bSRasmus Villemoes * the address of the descriptor as first argument, followed by all
24447cdd64bSRasmus Villemoes * the varargs. Note that fmt is repeated in invocations of this
24547cdd64bSRasmus Villemoes * macro.
24647cdd64bSRasmus Villemoes */
247ca90fca7SJim Cromie #define _dynamic_func_call_cls(cls, fmt, func, ...) \
248ca90fca7SJim Cromie __dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, ##__VA_ARGS__)
24947cdd64bSRasmus Villemoes #define _dynamic_func_call(fmt, func, ...) \
250ca90fca7SJim Cromie _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
251ca90fca7SJim Cromie
25247cdd64bSRasmus Villemoes /*
25347cdd64bSRasmus Villemoes * A variant that does the same, except that the descriptor is not
25447cdd64bSRasmus Villemoes * passed as the first argument to the function; it is only called
25547cdd64bSRasmus Villemoes * with precisely the macro's varargs.
25647cdd64bSRasmus Villemoes */
257ca90fca7SJim Cromie #define _dynamic_func_call_cls_no_desc(cls, fmt, func, ...) \
258ca90fca7SJim Cromie __dynamic_func_call_cls_no_desc(__UNIQUE_ID(ddebug), cls, fmt, \
259ca90fca7SJim Cromie func, ##__VA_ARGS__)
26047cdd64bSRasmus Villemoes #define _dynamic_func_call_no_desc(fmt, func, ...) \
261ca90fca7SJim Cromie _dynamic_func_call_cls_no_desc(_DPRINTK_CLASS_DFLT, fmt, \
262ca90fca7SJim Cromie func, ##__VA_ARGS__)
263ca90fca7SJim Cromie
264ca90fca7SJim Cromie #define dynamic_pr_debug_cls(cls, fmt, ...) \
265ca90fca7SJim Cromie _dynamic_func_call_cls(cls, fmt, __dynamic_pr_debug, \
266ca90fca7SJim Cromie pr_fmt(fmt), ##__VA_ARGS__)
26747cdd64bSRasmus Villemoes
26847cdd64bSRasmus Villemoes #define dynamic_pr_debug(fmt, ...) \
26947cdd64bSRasmus Villemoes _dynamic_func_call(fmt, __dynamic_pr_debug, \
27047cdd64bSRasmus Villemoes pr_fmt(fmt), ##__VA_ARGS__)
27147cdd64bSRasmus Villemoes
27207613b0bSJason Baron #define dynamic_dev_dbg(dev, fmt, ...) \
27347cdd64bSRasmus Villemoes _dynamic_func_call(fmt, __dynamic_dev_dbg, \
27447cdd64bSRasmus Villemoes dev, fmt, ##__VA_ARGS__)
275e9d376f0SJason Baron
27607613b0bSJason Baron #define dynamic_netdev_dbg(dev, fmt, ...) \
27747cdd64bSRasmus Villemoes _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
27847cdd64bSRasmus Villemoes dev, fmt, ##__VA_ARGS__)
279ffa10cb4SJason Baron
280923abb9dSGal Pressman #define dynamic_ibdev_dbg(dev, fmt, ...) \
281923abb9dSGal Pressman _dynamic_func_call(fmt, __dynamic_ibdev_dbg, \
282923abb9dSGal Pressman dev, fmt, ##__VA_ARGS__)
283923abb9dSGal Pressman
2847a555613SVladimir Kondratiev #define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
2857a555613SVladimir Kondratiev groupsize, buf, len, ascii) \
28647cdd64bSRasmus Villemoes _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
28747cdd64bSRasmus Villemoes print_hex_dump, \
28847cdd64bSRasmus Villemoes KERN_DEBUG, prefix_str, prefix_type, \
28947cdd64bSRasmus Villemoes rowsize, groupsize, buf, len, ascii)
2907a555613SVladimir Kondratiev
2913fc95d80SJim Cromie /* for test only, generally expect drm.debug style macro wrappers */
2923fc95d80SJim Cromie #define __pr_debug_cls(cls, fmt, ...) do { \
2933fc95d80SJim Cromie BUILD_BUG_ON_MSG(!__builtin_constant_p(cls), \
2943fc95d80SJim Cromie "expecting constant class int/enum"); \
2953fc95d80SJim Cromie dynamic_pr_debug_cls(cls, fmt, ##__VA_ARGS__); \
2963fc95d80SJim Cromie } while (0)
2973fc95d80SJim Cromie
2987ce93729SJason Baron #else /* !(CONFIG_DYNAMIC_DEBUG || (CONFIG_DYNAMIC_DEBUG_CORE && DYNAMIC_DEBUG_MODULE)) */
299e9d376f0SJason Baron
300b48420c1SJim Cromie #include <linux/string.h>
301b48420c1SJim Cromie #include <linux/errno.h>
302a2d375edSJim Cromie #include <linux/printk.h>
303b48420c1SJim Cromie
3047ce93729SJason Baron #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)
3057ce93729SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) false
3067ce93729SJason Baron
3077ce93729SJason Baron #define dynamic_pr_debug(fmt, ...) \
308*0381e588SGeert Uytterhoeven no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
3097ce93729SJason Baron #define dynamic_dev_dbg(dev, fmt, ...) \
310*0381e588SGeert Uytterhoeven dev_no_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__)
3117ce93729SJason Baron #define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
3127ce93729SJason Baron groupsize, buf, len, ascii) \
3137ce93729SJason Baron do { if (0) \
3147ce93729SJason Baron print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, \
3157ce93729SJason Baron rowsize, groupsize, buf, len, ascii); \
3167ce93729SJason Baron } while (0)
3177ce93729SJason Baron
3187ce93729SJason Baron #endif /* CONFIG_DYNAMIC_DEBUG || (CONFIG_DYNAMIC_DEBUG_CORE && DYNAMIC_DEBUG_MODULE) */
3197ce93729SJason Baron
3207ce93729SJason Baron
3217ce93729SJason Baron #ifdef CONFIG_DYNAMIC_DEBUG_CORE
3227ce93729SJason Baron
3237ce93729SJason Baron extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
3247ce93729SJason Baron const char *modname);
3257ce93729SJason Baron struct kernel_param;
3267ce93729SJason Baron int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp);
3277ce93729SJason Baron int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp);
3287ce93729SJason Baron
3297ce93729SJason Baron #else
3307ce93729SJason Baron
ddebug_dyndbg_module_param_cb(char * param,char * val,const char * modname)331b48420c1SJim Cromie static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
332b48420c1SJim Cromie const char *modname)
333b48420c1SJim Cromie {
33485d6b66dSJim Cromie if (!strcmp(param, "dyndbg")) {
335516cf1beSJim Cromie /* avoid pr_warn(), which wants pr_fmt() fully defined */
336516cf1beSJim Cromie printk(KERN_WARNING "dyndbg param is supported only in "
337b48420c1SJim Cromie "CONFIG_DYNAMIC_DEBUG builds\n");
338b48420c1SJim Cromie return 0; /* allow and ignore */
339b48420c1SJim Cromie }
340b48420c1SJim Cromie return -EINVAL;
341b48420c1SJim Cromie }
342b48420c1SJim Cromie
343b9400852SJim Cromie struct kernel_param;
param_set_dyndbg_classes(const char * instr,const struct kernel_param * kp)344b9400852SJim Cromie static inline int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
345b9400852SJim Cromie { return 0; }
param_get_dyndbg_classes(char * buffer,const struct kernel_param * kp)346b9400852SJim Cromie static inline int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
347b9400852SJim Cromie { return 0; }
348b9400852SJim Cromie
3497ce93729SJason Baron #endif
3507ce93729SJason Baron
351e9d376f0SJason Baron
352b9400852SJim Cromie extern const struct kernel_param_ops param_ops_dyndbg_classes;
353b9400852SJim Cromie
3547ce93729SJason Baron #endif /* _DYNAMIC_DEBUG_H */
355