pci.c: spin_lock_init(&adev->irqlock) even though it's unused, yet
[acx-mac80211.git] / log.c
blobca8918183f8ea5d8e51dd145b21f82f1c79423c1
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>
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
31 /**
32 * acx_log: the logging function
33 * @level: what level to log (LOG_WARNING, LOG_INFO or LOG_DEBUG).
34 * @what: what channel to log (any of the L_* values defined in acx_log.h).
35 * @fmt: the format string, and its arguments if any.
39 void acx_log(int level, int what, const char *fmt, ...)
41 va_list args;
42 const char *printk_level;
44 if (level > ACX_LOG_LEVEL)
45 return;
46 if (!(what & ACX_DEFAULT_MSG))
47 return;
50 * FIXME: this shouldn't be necessary, but I don't rely on luck
52 if (level > MAX_LOG_LEVEL)
53 level = MAX_LOG_LEVEL;
55 printk_level = printk_levels[level];
56 va_start(args, fmt);
58 printk("%sacx: ", printk_level);
59 vprintk(fmt, args);
60 va_end(args);
62 return;
65 /**
66 * acx_log_dump(): logs a message, and dumps a buffer. Basically, this is
67 * acx_log(), and a call to acx_dump_bytes() below.
68 * @level: see acx_log().
69 * @what: see acx_log().
70 * @buf: the buffer to dump.
71 * @buflen: the length of the buffer to dump.
74 void acx_log_dump(int level, int what, const void *buf, ssize_t buflen,
75 const char *fmt, ...)
77 va_list args;
78 const char *printk_level;
80 if (level > ACX_LOG_LEVEL)
81 return;
82 if (!(what & ACX_DEFAULT_MSG))
83 return;
86 * FIXME: this shouldn't be necessary, but I don't rely on luck
88 if (level > MAX_LOG_LEVEL)
89 level = MAX_LOG_LEVEL;
91 printk_level = printk_levels[level];
92 va_start(args, fmt);
94 acx_log(level, what, fmt, args);
95 acx_dump_bytes(printk_level, buf, buflen);
97 /**
98 * acx_log_ratelimited: like acx_log(), but rate limited via printk_ratelimit().
100 void acx_log_ratelimited(int level, int what, const char *fmt, ...)
102 va_list args;
104 if (printk_ratelimit())
105 return;
107 va_start(args, fmt);
108 acx_log(level, what, fmt, args);
109 va_end(args);
113 * acx_dump_bytes: hex dump of a buffer
114 * @printk_prefix: the KERN_* char constant, passed to this function by
115 * acx_log().
116 * @buf: the buffer to dump.
117 * @buflen: the length of the buffer.
119 * This function is static: it's not supposed to be called from anywhere else
120 * than this file. There is no "acx:" prefix here.
122 static void acx_dump_bytes(const char *printk_prefix, const void *data,
123 ssize_t len)
125 const u8 *ptr = (const u8 *)data;
126 unsigned int size = 0;
128 * buf holds:
129 * - the printk prefix (3 bytes);
130 * - the size printed as "0x%08X" (10 bytes);
131 * - the following semicolon (1 bytes);
132 * - 16 bytes printed as " %02X" (48 bytes);
133 * - the final '\0' (1 byte).
135 char buf[63], *p;
137 printk("%s--- BEGIN DUMP (%d bytes) ---\n", printk_prefix,
138 (int) len);
140 if (len <= 0)
141 return;
143 goto inside;
145 do {
146 p += sprintf(p, " %02X", *ptr);
147 size++, ptr++;
148 if (size % 16)
149 continue;
150 printk("%s\n", buf);
151 inside:
152 p = buf;
153 p += sprintf(p, "%s0x%08X:", printk_prefix, size);
154 } while (size < len);
156 if (size % 16)
157 printk("%s\n", buf);
159 printk("%s--- END DUMP ---\n", printk_prefix);
162 * Only in case of heavy debugging
165 #if ACX_LOG_LEVEL == 2
168 * __function_enter_exit: display entering/exiting of a function
169 * @fname: the function name.
170 * @enter_exit: 0 on enter, 1 on exit, 2 on exit with return value to be
171 * printed.
172 * @retcode: the return code to be printed if enter_exit is 2.
175 #define DEBUG_TSC 0
177 #if DEBUG_TSC
178 #define TIMESTAMP(d) unsigned long d; rdtscl(d)
179 #else
180 #define TIMESTAMP(d) unsigned long d = jiffies
181 #endif
184 * MAX_INDENT is the size of the spaces[] string below.
186 #define MAX_INDENT 10
187 void __function_enter_exit(const char *fname, int enter_exit,
188 int retcode)
190 static int indent = 0;
191 static const char spaces[] = " ";
192 const char *p = spaces + MAX_INDENT;
194 * Note that we MUST "declare" TIMESTAMP last: in case DEBUG_TSC is set,
195 * an rdtscl() is done on the argument, and, well, that's C.
197 TIMESTAMP(stamp);
198 stamp = stamp % 1000000;
200 switch (enter_exit) {
201 case __FUNCTION_ENTER:
202 if (indent < MAX_INDENT)
203 indent++;
204 break;
205 case __FUNCTION_EXIT:
206 case __FUNCTION_EXIT_WITHARG:
207 /* Nothing */
208 break;
209 default: /* Meh? */
210 return;
213 p -= indent;
215 switch (enter_exit) {
216 case __FUNCTION_ENTER:
217 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s-> %s\n",
218 stamp, p, fname);
219 break;
220 case __FUNCTION_EXIT:
221 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s\n",
222 stamp, p, fname);
223 break;
224 case __FUNCTION_EXIT_WITHARG:
225 acx_log(LOG_DEBUG, L_FUNC, "%08ld %s<- %s: %08X\n",
226 stamp, p, fname, retcode);
230 * The below test is enough: we already sanitized away illegal values of
231 * enter_exit at the beginning.
233 if (enter_exit != __FUNCTION_ENTER)
234 indent--;
238 #endif /* ACX_LOG_LEVEL == 2 */