xref: /illumos-gate/usr/src/uts/common/io/ib/ibtl/ibtl_util.c (revision 276df1e91366009d02eabe9e2c9a6f0b9dab2bba)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*276df1e9SBill Taylor  * Common Development and Distribution License (the "License").
6*276df1e9SBill Taylor  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*276df1e9SBill Taylor  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * ibtf_util.c
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * This file contains the IBTF module's helper/utility functions.
307c478bd9Sstevel@tonic-gate  * - IBTF logging support
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/ib/ibtl/impl/ibtl.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate static char ibtf_util[] = "ibtl_util";
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate /* Function Prototypes */
387c478bd9Sstevel@tonic-gate static void	ibtf_clear_print_buf();
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * Print Buffer protected by mutex for debug stuff. The mutex also
427c478bd9Sstevel@tonic-gate  * ensures serializing debug messages.
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate static kmutex_t	ibtf_print_mutex;
457c478bd9Sstevel@tonic-gate static char	ibtf_print_buf[IBTL_PRINT_BUF_LEN];
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * Debug Stuff.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate uint_t	ibtf_errlevel = IBTF_LOG_L5;
517c478bd9Sstevel@tonic-gate uint_t	ibgen_errlevel = IBTF_LOG_L2;
527c478bd9Sstevel@tonic-gate uint_t	ibtl_errlevel = IBTF_LOG_L2;
537c478bd9Sstevel@tonic-gate uint_t	ibcm_errlevel = IBTF_LOG_L2;
547c478bd9Sstevel@tonic-gate uint_t	ibdm_errlevel = IBTF_LOG_L2;
557c478bd9Sstevel@tonic-gate uint_t	ibnex_errlevel = IBTF_LOG_L2;
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #define	IBTF_DEBUG_SIZE_EXTRA_ALLOC	8
587c478bd9Sstevel@tonic-gate #define	IBTF_MIN_DEBUG_BUF_SIZE		0x1000
597c478bd9Sstevel@tonic-gate #ifdef	DEBUG
607c478bd9Sstevel@tonic-gate #define	IBTF_DEBUG_BUF_SIZE		0x10000
617c478bd9Sstevel@tonic-gate #else
627c478bd9Sstevel@tonic-gate #define	IBTF_DEBUG_BUF_SIZE		0x2000
637c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate int	ibtf_suppress_dprintf;		/* Suppress debug printing */
667c478bd9Sstevel@tonic-gate int	ibtf_buffer_dprintf = 1;	/* Use a debug print buffer */
677c478bd9Sstevel@tonic-gate int	ibtf_debug_buf_size = IBTF_DEBUG_BUF_SIZE; /* Sz of Debug buf */
687c478bd9Sstevel@tonic-gate int	ibtf_allow_intr_msgs = 0;	/* log "intr" messages */
697c478bd9Sstevel@tonic-gate char	*ibtf_debug_buf = NULL;		/* The Debug Buf */
707c478bd9Sstevel@tonic-gate char	*ibtf_buf_sptr, *ibtf_buf_eptr;	/* debug buffer temp pointer */
717c478bd9Sstevel@tonic-gate int	ibtf_clear_debug_buf_flag = 0;	/* Clear debug buffer */
727c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", ibtf_debug_buf_size))
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate longlong_t ibtl_ib2usec_tbl[64];	/* time conversion table */
757c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", ibtl_ib2usec_tbl))
767c478bd9Sstevel@tonic-gate 
_NOTE(MUTEX_PROTECTS_DATA (ibtf_print_mutex,ibtf_buf_sptr ibtf_buf_eptr))777c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibtf_print_mutex, ibtf_buf_sptr ibtf_buf_eptr))
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * Function:
817c478bd9Sstevel@tonic-gate  *	ibtl_ib2usec_init
827c478bd9Sstevel@tonic-gate  * Input:
837c478bd9Sstevel@tonic-gate  *	none
847c478bd9Sstevel@tonic-gate  * Output:
857c478bd9Sstevel@tonic-gate  *	none
867c478bd9Sstevel@tonic-gate  * Returns:
877c478bd9Sstevel@tonic-gate  *	none
887c478bd9Sstevel@tonic-gate  * Description:
897c478bd9Sstevel@tonic-gate  *	Initialize ibtl_ib2usec_tbl[64] for use by ibt_usec2ib and ibt_ib2usec.
907c478bd9Sstevel@tonic-gate  */
917c478bd9Sstevel@tonic-gate void
927c478bd9Sstevel@tonic-gate ibtl_ib2usec_init(void)
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate 	int i;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	for (i = 0; i < 64; i++) {
977c478bd9Sstevel@tonic-gate 		if (i < 51) {		/* shift first to avoid underflow */
987c478bd9Sstevel@tonic-gate 			ibtl_ib2usec_tbl[i] = ((1LL << i) << 12LL) / 1000LL;
997c478bd9Sstevel@tonic-gate 		} else if (i < 61) {	/* divide first to avoid overflow */
1007c478bd9Sstevel@tonic-gate 			ibtl_ib2usec_tbl[i] = ((1LL << i) / 1000LL) << 12LL;
1017c478bd9Sstevel@tonic-gate 		} else {		/* max'ed out, so use MAX LONGLONG */
1027c478bd9Sstevel@tonic-gate 			ibtl_ib2usec_tbl[i] = 0x7FFFFFFFFFFFFFFFLL;
1037c478bd9Sstevel@tonic-gate 		}
1047c478bd9Sstevel@tonic-gate #if !defined(_LP64)
1057c478bd9Sstevel@tonic-gate 		if (ibtl_ib2usec_tbl[i] > LONG_MAX)
1067c478bd9Sstevel@tonic-gate 			ibtl_ib2usec_tbl[i] = LONG_MAX;
1077c478bd9Sstevel@tonic-gate #endif
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate /*
1127c478bd9Sstevel@tonic-gate  * Function:
1137c478bd9Sstevel@tonic-gate  *      ibt_usec2ib
1147c478bd9Sstevel@tonic-gate  * Input:
1157c478bd9Sstevel@tonic-gate  *      time_val - Time in microsecs.
1167c478bd9Sstevel@tonic-gate  * Output:
1177c478bd9Sstevel@tonic-gate  *      none
1187c478bd9Sstevel@tonic-gate  * Returns:
1197c478bd9Sstevel@tonic-gate  *      Nearest IB Timeout Exponent value.
1207c478bd9Sstevel@tonic-gate  * Description:
1217c478bd9Sstevel@tonic-gate  *      This function converts the standard input time in microseconds to
1227c478bd9Sstevel@tonic-gate  *      IB's 6 bits of timeout exponent, calculated based on
1237c478bd9Sstevel@tonic-gate  *      time = 4.096us * 2 ^ exp.  This is done by searching through
1247c478bd9Sstevel@tonic-gate  *	the ibtl_ib2usec_tbl for the closest value >= time_val.
1257c478bd9Sstevel@tonic-gate  */
1267c478bd9Sstevel@tonic-gate ib_time_t
ibt_usec2ib(clock_t time_val)1277c478bd9Sstevel@tonic-gate ibt_usec2ib(clock_t time_val)
1287c478bd9Sstevel@tonic-gate {
1297c478bd9Sstevel@tonic-gate 	int i;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_util, "ibt_usec2ib(%ld)", time_val);
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	/* First, leap through the table by 4 entries at a time */
134*276df1e9SBill Taylor 	for (i = 0; (i + 4) < 64 && ibtl_ib2usec_tbl[i + 4] < time_val; i += 4)
135*276df1e9SBill Taylor 		;
1367c478bd9Sstevel@tonic-gate 	/* Find the return value; it's now between i and i + 4, inclusive */
1377c478bd9Sstevel@tonic-gate 	while (ibtl_ib2usec_tbl[i] < time_val)
1387c478bd9Sstevel@tonic-gate 		i++;
1397c478bd9Sstevel@tonic-gate 	return (i);
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate  * Function:
1457c478bd9Sstevel@tonic-gate  *      ibt_ib2usec
1467c478bd9Sstevel@tonic-gate  * Input:
1477c478bd9Sstevel@tonic-gate  *      ib_time    - IB Timeout Exponent value.
1487c478bd9Sstevel@tonic-gate  * Output:
1497c478bd9Sstevel@tonic-gate  *      none
1507c478bd9Sstevel@tonic-gate  * Returns:
1517c478bd9Sstevel@tonic-gate  *      Standard Time is microseconds.
1527c478bd9Sstevel@tonic-gate  * Description:
1537c478bd9Sstevel@tonic-gate  *      This function converts the input IB timeout exponent (6 bits) to
1547c478bd9Sstevel@tonic-gate  *      standard time in microseconds, calculated based on
1557c478bd9Sstevel@tonic-gate  *	time = 4.096us * 2 ^ exp.
1567c478bd9Sstevel@tonic-gate  *	This is implemented as a simple index into ibtl_ib2usec_tbl[].
1577c478bd9Sstevel@tonic-gate  */
1587c478bd9Sstevel@tonic-gate clock_t
ibt_ib2usec(ib_time_t ib_time)1597c478bd9Sstevel@tonic-gate ibt_ib2usec(ib_time_t ib_time)
1607c478bd9Sstevel@tonic-gate {
1617c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_util, "ibt_ib2usec(%d)", ib_time);
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	return ((clock_t)ibtl_ib2usec_tbl[ib_time & IB_TIME_EXP_MASK]);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate /* IBTF logging init */
1687c478bd9Sstevel@tonic-gate void
ibtl_logging_initialization()1697c478bd9Sstevel@tonic-gate ibtl_logging_initialization()
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate 	boolean_t flag = B_FALSE;
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_util, "ibtl_logging_initialization:");
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	mutex_init(&ibtf_print_mutex, NULL, MUTEX_DRIVER, NULL);
1767c478bd9Sstevel@tonic-gate 	mutex_enter(&ibtf_print_mutex);
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	if (ibtf_debug_buf_size <= IBTF_DEBUG_SIZE_EXTRA_ALLOC) {
1797c478bd9Sstevel@tonic-gate 		ibtf_debug_buf_size = IBTF_MIN_DEBUG_BUF_SIZE;
1807c478bd9Sstevel@tonic-gate 		flag = B_TRUE;
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	/* if it is less that IBTF_MIN_DEBUG_BUF_SIZE, adjust it */
1847c478bd9Sstevel@tonic-gate 	ibtf_debug_buf_size = max(IBTF_MIN_DEBUG_BUF_SIZE,
1857c478bd9Sstevel@tonic-gate 	    ibtf_debug_buf_size);
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	ibtf_debug_buf = (char *)kmem_alloc(ibtf_debug_buf_size, KM_SLEEP);
1887c478bd9Sstevel@tonic-gate 	ibtf_clear_print_buf();
1897c478bd9Sstevel@tonic-gate 	mutex_exit(&ibtf_print_mutex);
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	if (flag == B_TRUE) {
1927c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_util, "ibtf_debug_buf_size was too small "
1937c478bd9Sstevel@tonic-gate 		    "%x, adjusted to %x", ibtf_debug_buf_size,
1947c478bd9Sstevel@tonic-gate 		    IBTF_MIN_DEBUG_BUF_SIZE);
1957c478bd9Sstevel@tonic-gate 	}
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate /* IBTF logging destroy */
2007c478bd9Sstevel@tonic-gate void
ibtl_logging_destroy()2017c478bd9Sstevel@tonic-gate ibtl_logging_destroy()
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_util, "ibtl_logging_destroy");
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	mutex_enter(&ibtf_print_mutex);
2067c478bd9Sstevel@tonic-gate 	if (ibtf_debug_buf) {
2077c478bd9Sstevel@tonic-gate 		kmem_free(ibtf_debug_buf, ibtf_debug_buf_size);
2087c478bd9Sstevel@tonic-gate 		ibtf_debug_buf = NULL;
2097c478bd9Sstevel@tonic-gate 	}
2107c478bd9Sstevel@tonic-gate 	mutex_exit(&ibtf_print_mutex);
2117c478bd9Sstevel@tonic-gate 	mutex_destroy(&ibtf_print_mutex);
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate /*
2167c478bd9Sstevel@tonic-gate  * debug, log, and console message handling
2177c478bd9Sstevel@tonic-gate  */
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate  * clear the IBTF trace buffer
2217c478bd9Sstevel@tonic-gate  */
2227c478bd9Sstevel@tonic-gate static void
ibtf_clear_print_buf()2237c478bd9Sstevel@tonic-gate ibtf_clear_print_buf()
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&ibtf_print_mutex));
2267c478bd9Sstevel@tonic-gate 	if (ibtf_debug_buf) {
2277c478bd9Sstevel@tonic-gate 		ibtf_buf_sptr = ibtf_debug_buf;
2287c478bd9Sstevel@tonic-gate 		ibtf_buf_eptr = ibtf_debug_buf + ibtf_debug_buf_size -
2297c478bd9Sstevel@tonic-gate 		    IBTF_DEBUG_SIZE_EXTRA_ALLOC;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 		bzero(ibtf_debug_buf, ibtf_debug_buf_size);
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate static void
ibtf_vlog(char * name,uint_t level,char * fmt,va_list ap)2377c478bd9Sstevel@tonic-gate ibtf_vlog(char *name, uint_t level, char *fmt, va_list ap)
2387c478bd9Sstevel@tonic-gate {
2397c478bd9Sstevel@tonic-gate 	char	*label = (name == NULL) ? "ibtl" : name;
2407c478bd9Sstevel@tonic-gate 	char	*msg_ptr;
2417c478bd9Sstevel@tonic-gate 	size_t	len;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	mutex_enter(&ibtf_print_mutex);
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	/* if not using logging scheme; quit */
2467c478bd9Sstevel@tonic-gate 	if (ibtf_suppress_dprintf || (ibtf_debug_buf == NULL)) {
2477c478bd9Sstevel@tonic-gate 		mutex_exit(&ibtf_print_mutex);
2487c478bd9Sstevel@tonic-gate 		return;
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	/* if level doesn't match, we are done */
2527c478bd9Sstevel@tonic-gate 	if ((level < IBTF_LOG_L0) || (level > IBTF_LOG_LINTR)) {
2537c478bd9Sstevel@tonic-gate 		mutex_exit(&ibtf_print_mutex);
2547c478bd9Sstevel@tonic-gate 		return;
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	/* If user requests to clear debug buffer, go ahead */
2587c478bd9Sstevel@tonic-gate 	if (ibtf_clear_debug_buf_flag != 0) {
2597c478bd9Sstevel@tonic-gate 		ibtf_clear_print_buf();
2607c478bd9Sstevel@tonic-gate 		ibtf_clear_debug_buf_flag = 0;
2617c478bd9Sstevel@tonic-gate 	}
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	/*
2647c478bd9Sstevel@tonic-gate 	 * Check if we have a valid buf size?
2657c478bd9Sstevel@tonic-gate 	 * Suppress logging to ibtf_buffer if so.
2667c478bd9Sstevel@tonic-gate 	 */
2677c478bd9Sstevel@tonic-gate 	if (ibtf_debug_buf_size <= 0) {
2687c478bd9Sstevel@tonic-gate 		ibtf_buffer_dprintf = 0;
2697c478bd9Sstevel@tonic-gate 	}
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	/*
2727c478bd9Sstevel@tonic-gate 	 * put "label" into the buffer
2737c478bd9Sstevel@tonic-gate 	 */
2747c478bd9Sstevel@tonic-gate 	len = snprintf(ibtf_print_buf, IBTL_DRVNAME_LEN, "%s:\t", label);
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	msg_ptr = ibtf_print_buf + len;
2777c478bd9Sstevel@tonic-gate 	len += vsnprintf(msg_ptr, IBTL_PRINT_BUF_LEN - len - 2, fmt, ap);
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	len = min(len, IBTL_PRINT_BUF_LEN - 2);
2807c478bd9Sstevel@tonic-gate 	ASSERT(len == strlen(ibtf_print_buf));
2817c478bd9Sstevel@tonic-gate 	ibtf_print_buf[len++] = '\n';
2827c478bd9Sstevel@tonic-gate 	ibtf_print_buf[len] = '\0';
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	/*
2857c478bd9Sstevel@tonic-gate 	 * stuff the message in the debug buf
2867c478bd9Sstevel@tonic-gate 	 */
2877c478bd9Sstevel@tonic-gate 	if (ibtf_buffer_dprintf) {
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 		/*
2907c478bd9Sstevel@tonic-gate 		 * overwrite >>>> that might be over the end of the
2917c478bd9Sstevel@tonic-gate 		 * the buffer
2927c478bd9Sstevel@tonic-gate 		 */
2937c478bd9Sstevel@tonic-gate 		*ibtf_buf_sptr = '\0';
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 		if (ibtf_buf_sptr + len > ibtf_buf_eptr) {
2967c478bd9Sstevel@tonic-gate 			size_t left = ibtf_buf_eptr - ibtf_buf_sptr;
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 			bcopy((caddr_t)ibtf_print_buf,
2997c478bd9Sstevel@tonic-gate 			    (caddr_t)ibtf_buf_sptr, left);
3007c478bd9Sstevel@tonic-gate 			bcopy((caddr_t)ibtf_print_buf + left,
3017c478bd9Sstevel@tonic-gate 			    (caddr_t)ibtf_debug_buf, len - left);
3027c478bd9Sstevel@tonic-gate 			ibtf_buf_sptr = ibtf_debug_buf + len - left;
3037c478bd9Sstevel@tonic-gate 		} else {
3047c478bd9Sstevel@tonic-gate 			bcopy((caddr_t)ibtf_print_buf, ibtf_buf_sptr, len);
3057c478bd9Sstevel@tonic-gate 			ibtf_buf_sptr += len;
3067c478bd9Sstevel@tonic-gate 		}
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 		/* add marker */
3097c478bd9Sstevel@tonic-gate 		(void) sprintf(ibtf_buf_sptr, ">>>>");
3107c478bd9Sstevel@tonic-gate 	}
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	/*
3137c478bd9Sstevel@tonic-gate 	 * LINTR, L5-L2 message may go to the ibtf_debug_buf
3147c478bd9Sstevel@tonic-gate 	 * L1 messages will go to the log buf in non-debug kernels and
3157c478bd9Sstevel@tonic-gate 	 * to console and log buf in debug kernels
3167c478bd9Sstevel@tonic-gate 	 * L0 messages are warnings and will go to console and log buf
3177c478bd9Sstevel@tonic-gate 	 */
3187c478bd9Sstevel@tonic-gate 	switch (level) {
3197c478bd9Sstevel@tonic-gate 	case IBTF_LOG_LINTR:
3207c478bd9Sstevel@tonic-gate 	case IBTF_LOG_L5:
3217c478bd9Sstevel@tonic-gate 	case IBTF_LOG_L4:
3227c478bd9Sstevel@tonic-gate 	case IBTF_LOG_L3:
3237c478bd9Sstevel@tonic-gate 	case IBTF_LOG_L2:
3247c478bd9Sstevel@tonic-gate 		if (!ibtf_buffer_dprintf) {
3257c478bd9Sstevel@tonic-gate 			cmn_err(CE_CONT, "^%s", ibtf_print_buf);
3267c478bd9Sstevel@tonic-gate 		}
3277c478bd9Sstevel@tonic-gate 		break;
3287c478bd9Sstevel@tonic-gate 	case IBTF_LOG_L1:
3297c478bd9Sstevel@tonic-gate #ifdef DEBUG
3307c478bd9Sstevel@tonic-gate 		cmn_err(CE_CONT, "%s", ibtf_print_buf);
3317c478bd9Sstevel@tonic-gate #else
3327c478bd9Sstevel@tonic-gate 		if (!ibtf_buffer_dprintf) {
3337c478bd9Sstevel@tonic-gate 			cmn_err(CE_CONT, "^%s", ibtf_print_buf);
3347c478bd9Sstevel@tonic-gate 		}
3357c478bd9Sstevel@tonic-gate #endif
3367c478bd9Sstevel@tonic-gate 		break;
3377c478bd9Sstevel@tonic-gate 	case IBTF_LOG_L0:
3387c478bd9Sstevel@tonic-gate 		/* Strip the "\n" added earlier */
3397c478bd9Sstevel@tonic-gate 		if (ibtf_print_buf[len - 1] == '\n') {
3407c478bd9Sstevel@tonic-gate 			ibtf_print_buf[len - 1] = '\0';
3417c478bd9Sstevel@tonic-gate 		}
3427c478bd9Sstevel@tonic-gate 		if (msg_ptr[len - 1] == '\n') {
3437c478bd9Sstevel@tonic-gate 			msg_ptr[len - 1] = '\0';
3447c478bd9Sstevel@tonic-gate 		}
3457c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, ibtf_print_buf);
3467c478bd9Sstevel@tonic-gate 		break;
3477c478bd9Sstevel@tonic-gate 	}
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	mutex_exit(&ibtf_print_mutex);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate void
ibtl_dprintf_intr(char * name,char * fmt,...)3547c478bd9Sstevel@tonic-gate ibtl_dprintf_intr(char *name, char *fmt, ...)
3557c478bd9Sstevel@tonic-gate {
3567c478bd9Sstevel@tonic-gate 	va_list ap;
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	/* only log messages if "ibtf_allow_intr_msgs" is set */
3597c478bd9Sstevel@tonic-gate 	if (!ibtf_allow_intr_msgs)
3607c478bd9Sstevel@tonic-gate 		return;
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
3637c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_LINTR, fmt, ap);
3647c478bd9Sstevel@tonic-gate 	va_end(ap);
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate /*
3697c478bd9Sstevel@tonic-gate  * Check individual subsystem err levels
3707c478bd9Sstevel@tonic-gate  */
3717c478bd9Sstevel@tonic-gate #define	IBTL_CHECK_ERR_LEVEL(level)			\
3727c478bd9Sstevel@tonic-gate 	if (strncmp(name, "ibgen", 5) == 0) {		\
3737c478bd9Sstevel@tonic-gate 		if (ibgen_errlevel < level)		\
3747c478bd9Sstevel@tonic-gate 			return;				\
3757c478bd9Sstevel@tonic-gate 	} else if (strncmp(name, "ibtl", 4) == 0) {	\
3767c478bd9Sstevel@tonic-gate 		if (ibtl_errlevel < level)		\
3777c478bd9Sstevel@tonic-gate 			return;				\
3787c478bd9Sstevel@tonic-gate 	} else if (strncmp(name, "ibcm", 4) == 0) {	\
3797c478bd9Sstevel@tonic-gate 		if (ibcm_errlevel < level)		\
3807c478bd9Sstevel@tonic-gate 			return;				\
3817c478bd9Sstevel@tonic-gate 	} else if (strncmp(name, "ibdm", 4) == 0) {	\
3827c478bd9Sstevel@tonic-gate 		if (ibdm_errlevel < level)		\
3837c478bd9Sstevel@tonic-gate 			return;				\
3847c478bd9Sstevel@tonic-gate 	} else if (strncmp(name, "ibnex", 5) == 0) {	\
3857c478bd9Sstevel@tonic-gate 		if (ibnex_errlevel < level)		\
3867c478bd9Sstevel@tonic-gate 			return;				\
3877c478bd9Sstevel@tonic-gate 	}
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate void
ibtl_dprintf5(char * name,char * fmt,...)3907c478bd9Sstevel@tonic-gate ibtl_dprintf5(char *name, char *fmt, ...)
3917c478bd9Sstevel@tonic-gate {
3927c478bd9Sstevel@tonic-gate 	va_list ap;
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 	/* check if global errlevel matches or not */
3957c478bd9Sstevel@tonic-gate 	if (ibtf_errlevel < IBTF_LOG_L5)
3967c478bd9Sstevel@tonic-gate 		return;
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 	IBTL_CHECK_ERR_LEVEL(IBTF_LOG_L5);
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
4017c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_L5, fmt, ap);
4027c478bd9Sstevel@tonic-gate 	va_end(ap);
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate void
ibtl_dprintf4(char * name,char * fmt,...)4067c478bd9Sstevel@tonic-gate ibtl_dprintf4(char *name, char *fmt, ...)
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate 	va_list ap;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	/* check if global errlevel matches or not */
4117c478bd9Sstevel@tonic-gate 	if (ibtf_errlevel < IBTF_LOG_L4)
4127c478bd9Sstevel@tonic-gate 		return;
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	IBTL_CHECK_ERR_LEVEL(IBTF_LOG_L4);
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
4177c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_L4, fmt, ap);
4187c478bd9Sstevel@tonic-gate 	va_end(ap);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate void
ibtl_dprintf3(char * name,char * fmt,...)4237c478bd9Sstevel@tonic-gate ibtl_dprintf3(char *name, char *fmt, ...)
4247c478bd9Sstevel@tonic-gate {
4257c478bd9Sstevel@tonic-gate 	va_list ap;
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	/* check if global errlevel matches or not */
4287c478bd9Sstevel@tonic-gate 	if (ibtf_errlevel < IBTF_LOG_L3)
4297c478bd9Sstevel@tonic-gate 		return;
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 	IBTL_CHECK_ERR_LEVEL(IBTF_LOG_L3);
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
4347c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_L3, fmt, ap);
4357c478bd9Sstevel@tonic-gate 	va_end(ap);
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate void
ibtl_dprintf2(char * name,char * fmt,...)4407c478bd9Sstevel@tonic-gate ibtl_dprintf2(char *name, char *fmt, ...)
4417c478bd9Sstevel@tonic-gate {
4427c478bd9Sstevel@tonic-gate 	va_list ap;
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	/* check if global errlevel matches or not */
4457c478bd9Sstevel@tonic-gate 	if (ibtf_errlevel < IBTF_LOG_L2)
4467c478bd9Sstevel@tonic-gate 		return;
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	IBTL_CHECK_ERR_LEVEL(IBTF_LOG_L2);
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
4517c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_L2, fmt, ap);
4527c478bd9Sstevel@tonic-gate 	va_end(ap);
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate void
ibtl_dprintf1(char * name,char * fmt,...)4577c478bd9Sstevel@tonic-gate ibtl_dprintf1(char *name, char *fmt, ...)
4587c478bd9Sstevel@tonic-gate {
4597c478bd9Sstevel@tonic-gate 	va_list ap;
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	/* check if global errlevel matches or not */
4627c478bd9Sstevel@tonic-gate 	if (ibtf_errlevel < IBTF_LOG_L1)
4637c478bd9Sstevel@tonic-gate 		return;
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
4667c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_L1, fmt, ap);
4677c478bd9Sstevel@tonic-gate 	va_end(ap);
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate /*
4727c478bd9Sstevel@tonic-gate  * Function:
4737c478bd9Sstevel@tonic-gate  *      ibtf_dprintf0
4747c478bd9Sstevel@tonic-gate  * Input:
4757c478bd9Sstevel@tonic-gate  *      name	- Name of the subsystem generating the debug message
4767c478bd9Sstevel@tonic-gate  *  	fmt	- The message to be displayed.
4777c478bd9Sstevel@tonic-gate  * Output:
4787c478bd9Sstevel@tonic-gate  *      none
4797c478bd9Sstevel@tonic-gate  * Returns:
4807c478bd9Sstevel@tonic-gate  *      none
4817c478bd9Sstevel@tonic-gate  * Description:
4827c478bd9Sstevel@tonic-gate  *  	A generic log function to display IBTF debug messages.
4837c478bd9Sstevel@tonic-gate  */
4847c478bd9Sstevel@tonic-gate void
ibtl_dprintf0(char * name,char * fmt,...)4857c478bd9Sstevel@tonic-gate ibtl_dprintf0(char *name, char *fmt, ...)
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate 	va_list ap;
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	/* check if global errlevel matches or not */
4907c478bd9Sstevel@tonic-gate 	if (ibtf_errlevel < IBTF_LOG_L0)
4917c478bd9Sstevel@tonic-gate 		return;
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
4947c478bd9Sstevel@tonic-gate 	ibtf_vlog(name, IBTF_LOG_L0, fmt, ap);
4957c478bd9Sstevel@tonic-gate 	va_end(ap);
4967c478bd9Sstevel@tonic-gate }
497