Logging: re-enable "debug" module parameter
[acx-mac80211.git] / log.c
blobd690a8afb358f6700c9c8f9bb4d7d3843f37ba4c
1 /*
2 * log.c: logging framework.
4 * This file should disappear some day, when the driver is known to work
5 * reliably. Until then, this will contain all logging routines used everywhere
6 * in the code.
8 * Copyright (c) 2008, Francis Galiegue <fgaliegue@gmail.com> for the ACX100
9 * driver project.
11 * This file is licensed under the GPL version 2.
13 #include <linux/module.h> /* Needed for MODULE_* */
15 #include "acx_config.h"
16 #include "acx_log.h"
19 * Forward declarations
22 static void acx_dump_bytes(const char *prefix, const void *data,
23 ssize_t len);
25 static const char *const printk_levels[MAX_LOG_LEVEL + 1] = {
26 KERN_WARNING,
27 KERN_INFO,
28 KERN_DEBUG
32 * "debug" module parameter, only if ACX_DEBUG is set.
34 * If not set, statically define it to ACX_DEFAULT_MSG.
36 #if ACX_DEBUG
37 unsigned int acx_debug = ACX_DEFAULT_MSG;
38 /* parameter is 'debug', corresponding var is acx_debug */
39 module_param_named(debug, acx_debug, uint, 0);
40 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
41 #else
42 static unsigned int acx_debug = ACX_DEFAULT_MSG;
43 #endif
46 /**
47 * acx_log: the logging function
48 * @level: what level to log (LOG_WARNING, LOG_INFO or LOG_DEBUG).
49 * @what: what channel to log (any of the L_* values defined in acx_log.h).
50 * @fmt: the format string, and its arguments if any.
54 void acx_log(int level, int what, const char *fmt, ...)
56 va_list args;
57 const char *printk_level;
59 if (level > ACX_LOG_LEVEL)
60 return;
61 if (!(what & acx_debug))
62 return;
65 * FIXME: this shouldn't be necessary, but I don't rely on luck
67 if (level > MAX_LOG_LEVEL)
68 level = MAX_LOG_LEVEL;
70 printk_level = printk_levels[level];
71 va_start(args, fmt);
73 printk("%sacx: ", printk_level);
74 vprintk(fmt, args);
75 va_end(args);
77 return;
80 /**
81 * acx_log_dump(): logs a message, and dumps a buffer. Basically, this is
82 * acx_log(), and a call to acx_dump_bytes() below.
83 * @level: see acx_log().
84 * @what: see acx_log().
85 * @buf: the buffer to dump.
86 * @buflen: the length of the buffer to dump.
89 void acx_log_dump(int level, int what, const void *buf, ssize_t buflen,
90 const char *fmt, ...)
92 va_list args;
93 const char *printk_level;
95 if (level > ACX_LOG_LEVEL)
96 return;
97 if (!(what & acx_debug))
98 return;
101 * FIXME: this shouldn't be necessary, but I don't rely on luck
103 if (level > MAX_LOG_LEVEL)
104 level = MAX_LOG_LEVEL;
106 printk_level = printk_levels[level];
107 va_start(args, fmt);
109 acx_log(level, what, fmt, args);
110 acx_dump_bytes(printk_level, buf, buflen);
113 * acx_log_ratelimited: like acx_log(), but rate limited via printk_ratelimit().
115 void acx_log_ratelimited(int level, int what, const char *fmt, ...)
117 va_list args;
119 if (printk_ratelimit())
120 return;
122 va_start(args, fmt);
123 acx_log(level, what, fmt, args);
124 va_end(args);
128 * acx_dump_bytes: hex dump of a buffer
129 * @printk_prefix: the KERN_* char constant, passed to this function by
130 * acx_log().
131 * @buf: the buffer to dump.
132 * @buflen: the length of the buffer.
134 * This function is static: it's not supposed to be called from anywhere else
135 * than this file. There is no "acx:" prefix here.
137 static void acx_dump_bytes(const char *printk_prefix, const void *data,
138 ssize_t len)
140 const u8 *ptr = (const u8 *)data;
141 unsigned int size = 0;
143 * buf holds:
144 * - the printk prefix (3 bytes);
145 * - the size printed as "0x%08X" (10 bytes);
146 * - the following semicolon (1 bytes);
147 * - 16 bytes printed as " %02X" (48 bytes);
148 * - the final '\0' (1 byte).
150 char buf[63], *p;
152 printk("%s--- BEGIN DUMP (%d bytes) ---\n", printk_prefix,
153 (int) len);
155 if (len <= 0)
156 return;
158 goto inside;
160 do {
161 p += sprintf(p, " %02X", *ptr);
162 size++, ptr++;
163 if (size % 16)
164 continue;
165 printk("%s\n", buf);
166 inside:
167 p = buf;
168 p += sprintf(p, "%s0x%08X:", printk_prefix, size);
169 } while (size < len);
171 if (size % 16)
172 printk("%s\n", buf);
174 printk("%s--- END DUMP ---\n", printk_prefix);
177 * Only in case of heavy debugging
180 #if ACX_LOG_LEVEL == 2
183 * __function_enter_exit: display entering/exiting of a function
184 * @fname: the function name.
185 * @enter_exit: 0 on enter, 1 on exit, 2 on exit with return value to be
186 * printed.
187 * @retcode: the return code to be printed if enter_exit is 2.
190 #define DEBUG_TSC 0
192 #if DEBUG_TSC
193 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
194 #else
195 #define TIMESTAMP(d) unsigned long d = jiffies
196 #endif
199 * MAX_INDENT is the size of the spaces[] string below.
201 #define MAX_INDENT 10
202 void __function_enter_exit(const char *fname, int enter_exit,
203 int retcode)
205 static int indent = 0;
206 static const char spaces[] = " ";
207 const char *p = spaces + MAX_INDENT;
209 * Note that we MUST "declare" TIMESTAMP last: in case DEBUG_TSC is set,
210 * an rdtscl() is done on the argument, and, well, that's C.
212 TIMESTAMP(stamp);
213 stamp = stamp % 1000000;
215 switch (enter_exit) {
216 case __FUNCTION_ENTER:
217 if (indent < MAX_INDENT)
218 indent++;
219 break;
220 case __FUNCTION_EXIT:
221 case __FUNCTION_EXIT_WITHARG:
222 /* Nothing */
223 break;
224 default: /* Meh? */
225 return;
228 p -= indent;
230 switch (enter_exit) {
231 case __FUNCTION_ENTER:
232 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s-> %s\n",
233 stamp, p, fname);
234 break;
235 case __FUNCTION_EXIT:
236 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s\n",
237 stamp, p, fname);
238 break;
239 case __FUNCTION_EXIT_WITHARG:
240 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s: %08X\n",
241 stamp, p, fname, retcode);
245 * The below test is enough: we already sanitized away illegal values of
246 * enter_exit at the beginning.
248 if (enter_exit != __FUNCTION_ENTER)
249 indent--;
253 #endif /* ACX_LOG_LEVEL == 2 */