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