pci.c: fix missing newline in acx_log_dump()
[acx-mac80211.git] / log.c
blob0449044065ce209809053019c821d927f4cd0308
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;
60 if (level > ACX_LOG_LEVEL)
61 return;
62 if (!(what & acx_debug))
63 return;
66 * FIXME: this shouldn't be necessary, but I don't rely on luck
68 if (level > MAX_LOG_LEVEL)
69 level = MAX_LOG_LEVEL;
71 printk_level = printk_levels[level];
72 va_start(args, fmt);
74 printk("%sacx: ", printk_level);
75 vprintk(fmt, args);
76 va_end(args);
78 return;
81 /**
82 * acx_log_dump(): logs a message, and dumps a buffer. Basically, this is
83 * acx_log(), and a call to acx_dump_bytes() below.
84 * @level: see acx_log().
85 * @what: see acx_log().
86 * @buf: the buffer to dump.
87 * @buflen: the length of the buffer to dump.
90 void acx_log_dump(int level, int what, const void *buf, ssize_t buflen,
91 const char *fmt, ...)
93 va_list args;
94 const char *printk_level;
96 if (level > ACX_LOG_LEVEL)
97 return;
98 if (!(what & acx_debug))
99 return;
102 * FIXME: this shouldn't be necessary, but I don't rely on luck
104 if (level > MAX_LOG_LEVEL)
105 level = MAX_LOG_LEVEL;
107 printk_level = printk_levels[level];
109 va_start(args, fmt);
110 acx_log(level, what, fmt, args);
111 va_end(args);
113 acx_dump_bytes(printk_level, buf, buflen);
117 * acx_dump_bytes: hex dump of a buffer
118 * @printk_prefix: the KERN_* char constant, passed to this function by
119 * acx_log().
120 * @buf: the buffer to dump.
121 * @buflen: the length of the buffer.
123 * This function is static: it's not supposed to be called from anywhere else
124 * than this file. There is no "acx:" prefix here.
126 static void acx_dump_bytes(const char *printk_prefix, const void *data,
127 ssize_t len)
129 const u8 *ptr = (const u8 *)data;
130 unsigned int size = 0;
132 * buf holds:
133 * - the printk prefix (3 bytes);
134 * - the size printed as "0x%08X" (10 bytes);
135 * - the following semicolon (1 bytes);
136 * - 16 bytes printed as " %02X" (48 bytes);
137 * - the final '\0' (1 byte).
139 char buf[63], *p;
141 printk("%s--- BEGIN DUMP (%d bytes) ---\n", printk_prefix,
142 (int) len);
144 if (len <= 0)
145 return;
147 goto inside;
149 do {
150 p += sprintf(p, " %02X", *ptr);
151 size++, ptr++;
152 if (size % 16)
153 continue;
154 printk("%s\n", buf);
155 inside:
156 p = buf;
157 p += sprintf(p, "%s0x%08X:", printk_prefix, size);
158 } while (size < len);
160 if (size % 16)
161 printk("%s\n", buf);
163 printk("%s--- END DUMP ---\n", printk_prefix);
166 * Only in case of heavy debugging
169 #if ACX_LOG_LEVEL == 2
172 * __function_enter_exit: display entering/exiting of a function
173 * @fname: the function name.
174 * @enter_exit: 0 on enter, 1 on exit, 2 on exit with return value to be
175 * printed.
176 * @retcode: the return code to be printed if enter_exit is 2.
179 #define DEBUG_TSC 0
181 #if DEBUG_TSC
182 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
183 #else
184 #define TIMESTAMP(d) unsigned long d = jiffies
185 #endif
188 * MAX_INDENT is the size of the spaces[] string below.
190 #define MAX_INDENT 10
191 void __function_enter_exit(const char *fname, int enter_exit,
192 int retcode)
194 static int indent = 0;
195 static const char spaces[] = " ";
196 const char *p = spaces + MAX_INDENT;
198 * Note that we MUST "declare" TIMESTAMP last: in case DEBUG_TSC is set,
199 * an rdtscl() is done on the argument, and, well, that's C.
201 TIMESTAMP(stamp);
202 stamp = stamp % 1000000;
204 switch (enter_exit) {
205 case __FUNCTION_ENTER:
206 if (indent < MAX_INDENT)
207 indent++;
208 break;
209 case __FUNCTION_EXIT:
210 case __FUNCTION_EXIT_WITHARG:
211 /* Nothing */
212 break;
213 default: /* Meh? */
214 return;
217 p -= indent;
219 switch (enter_exit) {
220 case __FUNCTION_ENTER:
221 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s-> %s\n",
222 stamp, p, fname);
223 break;
224 case __FUNCTION_EXIT:
225 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s\n",
226 stamp, p, fname);
227 break;
228 case __FUNCTION_EXIT_WITHARG:
229 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s: %08X\n",
230 stamp, p, fname, retcode);
234 * The below test is enough: we already sanitized away illegal values of
235 * enter_exit at the beginning.
237 if (enter_exit != __FUNCTION_ENTER)
238 indent--;
242 #endif /* ACX_LOG_LEVEL == 2 */