Reverted refactoring of 'interrogate' cmds to 'query'
[acx-mac80211.git] / log.c
blob42cdf54afdccee029550d9a236317851b5fcac42
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/jiffies.h>
14 #include <linux/module.h> /* Needed for MODULE_* */
16 #include "acx_config.h"
17 #include "acx_log.h"
20 * Forward declarations
23 static void acx_dump_bytes(const char *prefix, const void *data,
24 ssize_t len);
26 static const char *const printk_levels[MAX_LOG_LEVEL + 1] = {
27 KERN_WARNING,
28 KERN_INFO,
29 KERN_DEBUG
33 * "debug" module parameter, only if ACX_DEBUG is set.
35 * If not set, statically define it to ACX_DEFAULT_MSG.
37 #if ACX_DEBUG
38 unsigned int acx_debug = ACX_DEFAULT_MSG;
39 /* parameter is 'debug', corresponding var is acx_debug */
40 module_param_named(debug, acx_debug, uint, 0);
41 MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
42 #else
43 static unsigned int acx_debug = ACX_DEFAULT_MSG;
44 #endif
47 /**
48 * acx_log: the logging function
49 * @level: what level to log (LOG_WARNING, LOG_INFO or LOG_DEBUG).
50 * @what: what channel to log (any of the L_* values defined in acx_log.h).
51 * @fmt: the format string, and its arguments if any.
55 void acx_log(int level, int what, const char *fmt, ...)
57 va_list args;
58 const char *printk_level;
59 char fmt_end;
61 if (level > ACX_LOG_LEVEL)
62 return;
63 if (!(what & acx_debug))
64 return;
67 * FIXME: this shouldn't be necessary, but I don't rely on luck
69 if (level > MAX_LOG_LEVEL)
70 level = MAX_LOG_LEVEL;
72 fmt_end = fmt[strlen(fmt) - 1];
74 printk_level = printk_levels[level];
75 va_start(args, fmt);
77 printk("%sacx: ", printk_level);
78 vprintk(fmt, args);
79 va_end(args);
81 if (fmt_end != '\n') {
82 printk("\n");
83 printk(KERN_WARNING "MISSING NEWLINE, please fix\n");
85 return;
88 /**
89 * acx_log_dump(): logs a message, and dumps a buffer. Basically, this is
90 * acx_log(), and a call to acx_dump_bytes() below.
91 * @level: see acx_log().
92 * @what: see acx_log().
93 * @buf: the buffer to dump.
94 * @buflen: the length of the buffer to dump.
97 void acx_log_dump(int level, int what, const void *buf, ssize_t buflen,
98 const char *fmt, ...)
100 va_list args;
101 const char *printk_level;
103 if (level > ACX_LOG_LEVEL)
104 return;
105 if (!(what & acx_debug))
106 return;
109 * FIXME: this shouldn't be necessary, but I don't rely on luck
111 if (level > MAX_LOG_LEVEL)
112 level = MAX_LOG_LEVEL;
114 printk_level = printk_levels[level];
116 va_start(args, fmt);
117 acx_log(level, what, fmt, args);
118 va_end(args);
120 acx_dump_bytes(printk_level, buf, buflen);
124 * acx_dump_bytes: hex dump of a buffer
125 * @printk_prefix: the KERN_* char constant, passed to this function by
126 * acx_log().
127 * @buf: the buffer to dump.
128 * @buflen: the length of the buffer.
130 * This function is static: it's not supposed to be called from anywhere else
131 * than this file. There is no "acx:" prefix here.
133 static void acx_dump_bytes(const char *printk_prefix, const void *data,
134 ssize_t len)
136 const u8 *ptr = (const u8 *)data;
137 unsigned int size = 0;
139 * buf holds:
140 * - the printk prefix (3 bytes);
141 * - the size printed as "0x%08X" (10 bytes);
142 * - the following semicolon (1 bytes);
143 * - 16 bytes printed as " %02X" (48 bytes);
144 * - the final '\0' (1 byte).
146 char buf[63], *p;
148 printk("%s--- BEGIN DUMP (%d bytes) ---\n", printk_prefix,
149 (int) len);
151 if (len <= 0)
152 return;
154 goto inside;
156 do {
157 p += sprintf(p, " %02X", *ptr);
158 size++, ptr++;
159 if (size % 16)
160 continue;
161 printk("%s\n", buf);
162 inside:
163 p = buf;
164 p += sprintf(p, "%s0x%08X:", printk_prefix, size);
165 } while (size < len);
167 if (size % 16)
168 printk("%s\n", buf);
170 printk("%s--- END DUMP ---\n", printk_prefix);
173 * Only in case of heavy debugging
176 #if ACX_LOG_LEVEL == 2
179 * __function_enter_exit: display entering/exiting of a function
180 * @fname: the function name.
181 * @enter_exit: 0 on enter, 1 on exit, 2 on exit with return value to be
182 * printed.
183 * @retcode: the return code to be printed if enter_exit is 2.
186 #define DEBUG_TSC 0
188 #if DEBUG_TSC
189 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
190 #else
191 #define TIMESTAMP(d) unsigned long d = jiffies
192 #endif
195 * MAX_INDENT is the size of the spaces[] string below.
197 #define MAX_INDENT 10
198 void __function_enter_exit(const char *fname, int enter_exit,
199 int retcode)
201 static int indent = 0;
202 static const char spaces[] = " ";
203 const char *p = spaces + MAX_INDENT;
205 * Note that we MUST "declare" TIMESTAMP last: in case DEBUG_TSC is set,
206 * an rdtscl() is done on the argument, and, well, that's C.
208 TIMESTAMP(stamp);
209 stamp = stamp % 1000000;
211 switch (enter_exit) {
212 case __FUNCTION_ENTER:
213 if (indent < MAX_INDENT)
214 indent++;
215 break;
216 case __FUNCTION_EXIT:
217 case __FUNCTION_EXIT_WITHARG:
218 /* Nothing */
219 break;
220 default: /* Meh? */
221 return;
224 p -= indent;
226 switch (enter_exit) {
227 case __FUNCTION_ENTER:
228 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s-> %s\n",
229 stamp, p, fname);
230 break;
231 case __FUNCTION_EXIT:
232 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s\n",
233 stamp, p, fname);
234 break;
235 case __FUNCTION_EXIT_WITHARG:
236 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s: %08X\n",
237 stamp, p, fname, retcode);
241 * The below test is enough: we already sanitized away illegal values of
242 * enter_exit at the beginning.
244 if (enter_exit != __FUNCTION_ENTER)
245 indent--;
249 #endif /* ACX_LOG_LEVEL == 2 */