xref: /illumos-gate/usr/src/uts/common/io/ib/clients/eoib/eib_log.c (revision b494511a9cf72b1fc4eb13a0e593f55c624ab829)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/kmem.h>
28 #include <sys/cmn_err.h>
29 #include <sys/conf.h>
30 #include <sys/ddi.h>
31 #include <sys/sunddi.h>
32 #include <sys/ksynch.h>
33 #include <sys/varargs.h>
34 
35 #include <sys/ib/clients/eoib/eib_impl.h>
36 
37 /*
38  * Defaults
39  */
40 uint_t eib_log_size = EIB_LOGSZ_DEFAULT;
41 int eib_log_level = EIB_MSGS_DEFAULT | EIB_MSGS_DEBUG;
42 int eib_log_timestamps = 0;
43 
44 /*
45  * Debug variables, should not be tunables so allocated debug buffer
46  * and its size remain consistent.
47  */
48 static kmutex_t eib_debug_buf_lock;
49 static uint8_t *eib_debug_buf;
50 static uint32_t eib_debug_buf_ndx;
51 static uint_t eib_debug_buf_sz = 0;
52 
53 /*
54  * Local declarations
55  */
56 static void eib_log(char *);
57 
58 void
59 eib_debug_init(void)
60 {
61 	eib_debug_buf_ndx = 0;
62 	eib_debug_buf_sz = eib_log_size;
63 	eib_debug_buf = kmem_zalloc(eib_debug_buf_sz, KM_SLEEP);
64 
65 	mutex_init(&eib_debug_buf_lock, NULL, MUTEX_DRIVER, NULL);
66 }
67 
68 void
69 eib_debug_fini(void)
70 {
71 	mutex_destroy(&eib_debug_buf_lock);
72 
73 	if (eib_debug_buf && eib_debug_buf_sz) {
74 		kmem_free(eib_debug_buf, eib_debug_buf_sz);
75 		eib_debug_buf = NULL;
76 	}
77 	eib_debug_buf_sz = 0;
78 	eib_debug_buf_ndx = 0;
79 }
80 
81 void
82 eib_log(char *msg)
83 {
84 	uint32_t off;
85 	int msglen;
86 	char msgbuf[EIB_MAX_LINE];
87 
88 	if (eib_debug_buf == NULL)
89 		return;
90 
91 	if (eib_log_timestamps) {
92 		msglen = snprintf(msgbuf, EIB_MAX_LINE, "%llx: %s",
93 		    (unsigned long long)ddi_get_lbolt64(), msg);
94 	} else {
95 		msglen = snprintf(msgbuf, EIB_MAX_LINE, "%s", msg);
96 	}
97 
98 	if (msglen < 0)
99 		return;
100 	else if (msglen >= EIB_MAX_LINE)
101 		msglen = EIB_MAX_LINE - 1;
102 
103 	mutex_enter(&eib_debug_buf_lock);
104 	if ((eib_debug_buf_ndx == 0) ||
105 	    (eib_debug_buf[eib_debug_buf_ndx-1] != '\n')) {
106 		eib_debug_buf[eib_debug_buf_ndx] = '\n';
107 		eib_debug_buf_ndx++;
108 	}
109 
110 	off = eib_debug_buf_ndx;	/* current msg should go here */
111 
112 	eib_debug_buf_ndx += msglen;	/* next msg should start here */
113 	eib_debug_buf[eib_debug_buf_ndx] = 0;	/* terminate current msg */
114 
115 	if (eib_debug_buf_ndx >= (eib_debug_buf_sz - 2 * EIB_MAX_LINE))
116 		eib_debug_buf_ndx = 0;
117 
118 	mutex_exit(&eib_debug_buf_lock);
119 
120 	bcopy(msgbuf, eib_debug_buf+off, msglen);    /* no lock needed */
121 }
122 
123 #ifdef EIB_DEBUG
124 void
125 eib_dprintf_verbose(int inst, const char *fmt, ...)
126 {
127 	va_list ap;
128 	int msglen;
129 	char msgbuf[EIB_MAX_LINE];
130 	char newfmt[EIB_MAX_LINE];
131 
132 	if ((eib_log_level & EIB_MSGS_VERBOSE) != EIB_MSGS_VERBOSE)
133 		return;
134 
135 	(void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt);
136 
137 	va_start(ap, fmt);
138 	msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap);
139 	va_end(ap);
140 
141 	if (msglen > 0) {
142 		eib_log(msgbuf);
143 	}
144 }
145 
146 void
147 eib_dprintf_pkt(int inst, uint8_t *pkt, uint_t sz)
148 {
149 	char msgbuf[EIB_MAX_LINE];
150 	char *bufp;
151 	uint8_t *p = pkt;
152 	uint_t len;
153 	uint_t i;
154 
155 	if ((eib_log_level & EIB_MSGS_PKT) != EIB_MSGS_PKT)
156 		return;
157 
158 	while (sz >= 16) {
159 		(void) snprintf(msgbuf, EIB_MAX_LINE,
160 		    "eoib%02d__%02x %02x %02x %02x %02x %02x %02x %02x "
161 		    "%02x %02x %02x %02x %02x %02x %02x %02x\n", inst,
162 		    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
163 		    p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
164 
165 		eib_log(msgbuf);
166 
167 		p += 16;
168 		sz -= 16;
169 	}
170 
171 	len = EIB_MAX_LINE;
172 	bufp = msgbuf;
173 	for (i = 0; i < sz; i++) {
174 		if (i == 0) {
175 			(void) snprintf(bufp, len, "eoib%02d__%02x ",
176 			    inst, p[i]);
177 			len -= 11;
178 			bufp += 11;
179 		} else if (i < (sz - 1)) {
180 			(void) snprintf(bufp, len, "%02x ", p[i]);
181 			len -= 3;
182 			bufp += 3;
183 		} else {
184 			(void) snprintf(bufp, len, "%02x\n", p[i]);
185 			len -= 3;
186 			bufp += 3;
187 		}
188 	}
189 
190 	eib_log(msgbuf);
191 }
192 
193 void
194 eib_dprintf_args(int inst, const char *fmt, ...)
195 {
196 	va_list ap;
197 	int msglen;
198 	char msgbuf[EIB_MAX_LINE];
199 	char newfmt[EIB_MAX_LINE];
200 
201 	if ((eib_log_level & EIB_MSGS_ARGS) != EIB_MSGS_ARGS)
202 		return;
203 
204 	(void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt);
205 
206 	va_start(ap, fmt);
207 	msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap);
208 	va_end(ap);
209 
210 	if (msglen > 0) {
211 		eib_log(msgbuf);
212 	}
213 }
214 
215 void
216 eib_dprintf_debug(int inst, const char *fmt, ...)
217 {
218 	va_list ap;
219 	int msglen;
220 	char msgbuf[EIB_MAX_LINE];
221 	char newfmt[EIB_MAX_LINE];
222 
223 	if ((eib_log_level & EIB_MSGS_DEBUG) != EIB_MSGS_DEBUG)
224 		return;
225 
226 	(void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt);
227 
228 	va_start(ap, fmt);
229 	msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap);
230 	va_end(ap);
231 
232 	if (msglen > 0) {
233 		eib_log(msgbuf);
234 	}
235 }
236 #endif
237 
238 void
239 eib_dprintf_warn(int inst, const char *fmt, ...)
240 {
241 	va_list ap;
242 	int msglen;
243 	char msgbuf[EIB_MAX_LINE];
244 	char newfmt[EIB_MAX_LINE];
245 
246 	if ((eib_log_level & EIB_MSGS_WARN) != EIB_MSGS_WARN)
247 		return;
248 
249 	(void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt);
250 
251 	va_start(ap, fmt);
252 	msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap);
253 	va_end(ap);
254 
255 	if (msglen > 0) {
256 		eib_log(msgbuf);
257 	}
258 }
259 
260 void
261 eib_dprintf_err(int inst, const char *fmt, ...)
262 {
263 	va_list ap;
264 	int msglen;
265 	char msgbuf[EIB_MAX_LINE];
266 	char newfmt[EIB_MAX_LINE];
267 
268 	if ((eib_log_level & EIB_MSGS_ERR) != EIB_MSGS_ERR)
269 		return;
270 
271 	(void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt);
272 
273 	va_start(ap, fmt);
274 	msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap);
275 	va_end(ap);
276 
277 	if (msglen > 0) {
278 		eib_log(msgbuf);
279 		cmn_err(CE_WARN, "!%s\n", msgbuf);
280 	}
281 }
282 
283 void
284 eib_dprintf_crit(int inst, const char *fmt, ...)
285 {
286 	va_list ap;
287 	int msglen;
288 	char msgbuf[EIB_MAX_LINE];
289 	char newfmt[EIB_MAX_LINE];
290 
291 	if ((eib_log_level & EIB_MSGS_CRIT) != EIB_MSGS_CRIT)
292 		return;
293 
294 	(void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt);
295 
296 	va_start(ap, fmt);
297 	msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap);
298 	va_end(ap);
299 
300 	if (msglen > 0) {
301 		eib_log(msgbuf);
302 		cmn_err(CE_PANIC, "!%s\n", msgbuf);
303 	}
304 }
305