xref: /linux-6.15/include/linux/dynamic_debug.h (revision 0381e588)
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