xref: /onnv-gate/usr/src/uts/sun4u/ngdr/io/dr_util.c (revision 930:1b624a2ec4bc)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*930Smathue  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*930Smathue  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/cmn_err.h>
310Sstevel@tonic-gate #include <sys/param.h>		/* for NULL */
320Sstevel@tonic-gate #include <sys/sbd_ioctl.h>
330Sstevel@tonic-gate #include <sys/dr_util.h>
340Sstevel@tonic-gate #include <sys/varargs.h>
350Sstevel@tonic-gate #include <sys/sysmacros.h>
360Sstevel@tonic-gate #include <sys/systm.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */
390Sstevel@tonic-gate extern sbd_etab_t sbd_etab[];
400Sstevel@tonic-gate extern int sbd_etab_len;
410Sstevel@tonic-gate 
420Sstevel@tonic-gate sbd_error_t *
430Sstevel@tonic-gate sbd_err_new(int e_code, char *fmt, va_list args)
440Sstevel@tonic-gate {
450Sstevel@tonic-gate 	sbd_error_t	*new;
460Sstevel@tonic-gate 
470Sstevel@tonic-gate 	new = GETSTRUCT(sbd_error_t, 1);
480Sstevel@tonic-gate 	new->e_code = e_code;
490Sstevel@tonic-gate 
500Sstevel@tonic-gate 	if (fmt)
510Sstevel@tonic-gate 		(void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args);
520Sstevel@tonic-gate 
530Sstevel@tonic-gate 	return (new);
540Sstevel@tonic-gate }
550Sstevel@tonic-gate 
560Sstevel@tonic-gate void
570Sstevel@tonic-gate sbd_err_log(sbd_error_t *ep, int ce)
580Sstevel@tonic-gate {
590Sstevel@tonic-gate 	char		 buf[32];
600Sstevel@tonic-gate 	char		*fmt;
610Sstevel@tonic-gate 	char		*txt;
620Sstevel@tonic-gate 	int		 i;
630Sstevel@tonic-gate 	sbd_etab_t	*tp;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	if (!ep)
660Sstevel@tonic-gate 		return;
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	if (ep->e_rsc[0] == '\0')
690Sstevel@tonic-gate 		fmt = "%s";
700Sstevel@tonic-gate 	else
710Sstevel@tonic-gate 		fmt = "%s: %s";
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 	for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++)
740Sstevel@tonic-gate 		if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd)
750Sstevel@tonic-gate 			break;
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	if (i < sbd_etab_len)
780Sstevel@tonic-gate 		txt = tp->t_text[ep->e_code - tp->t_base];
790Sstevel@tonic-gate 	else {
800Sstevel@tonic-gate 		snprintf(buf, sizeof (buf), "error %d", ep->e_code);
810Sstevel@tonic-gate 		txt = buf;
820Sstevel@tonic-gate 	}
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	cmn_err(ce, fmt, txt, ep->e_rsc);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
870Sstevel@tonic-gate void
880Sstevel@tonic-gate sbd_err_clear(sbd_error_t **ep)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	FREESTRUCT(*ep, sbd_error_t, 1);
910Sstevel@tonic-gate 	*ep = NULL;
920Sstevel@tonic-gate }
930Sstevel@tonic-gate 
940Sstevel@tonic-gate void
950Sstevel@tonic-gate sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
960Sstevel@tonic-gate {
970Sstevel@tonic-gate 	sbd_error_t	*tmp;
980Sstevel@tonic-gate 	va_list		args;
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	va_start(args, fmt);
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	tmp = sbd_err_new(e_code, fmt, args);
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	sbd_err_log(tmp, ce);
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	if (*ep == NULL)
1070Sstevel@tonic-gate 		*ep = tmp;
1080Sstevel@tonic-gate 	else
1090Sstevel@tonic-gate 		sbd_err_clear(&tmp);
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate 	va_end(args);
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate void
1150Sstevel@tonic-gate sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate 	sbd_error_t	*tmp;
1180Sstevel@tonic-gate 	va_list		args;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	va_start(args, fmt);
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	tmp = sbd_err_new(e_code, fmt, args);
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	sbd_err_log(tmp, ce);
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	*ep = tmp;
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate 	va_end(args);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate sbd_error_t *
1320Sstevel@tonic-gate drerr_new_v(int e_code, char *fmt, va_list args)
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate 	return (sbd_err_new(e_code, fmt, args));
1350Sstevel@tonic-gate }
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate sbd_error_t *
1380Sstevel@tonic-gate drerr_new(int log, int e_code, char *fmt, ...)
1390Sstevel@tonic-gate {
1400Sstevel@tonic-gate 	sbd_error_t	*ep;
1410Sstevel@tonic-gate 	va_list		 args;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	va_start(args, fmt);
1440Sstevel@tonic-gate 	ep = sbd_err_new(e_code, fmt, args);
1450Sstevel@tonic-gate 	va_end(args);
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	if (log)
1480Sstevel@tonic-gate 		sbd_err_log(ep, CE_WARN);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	return (ep);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate void
1540Sstevel@tonic-gate drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...)
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate 	sbd_error_t	*err;
1570Sstevel@tonic-gate 	va_list		 args;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	va_start(args, fmt);
1600Sstevel@tonic-gate 	err = sbd_err_new(e_code, fmt, args);
1610Sstevel@tonic-gate 	va_end(args);
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	if (log)
1640Sstevel@tonic-gate 		sbd_err_log(err, CE_WARN);
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	if (*ep == NULL)
1670Sstevel@tonic-gate 		*ep = err;
1680Sstevel@tonic-gate 	else
1690Sstevel@tonic-gate 		sbd_err_clear(&err);
1700Sstevel@tonic-gate }
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate /*
1740Sstevel@tonic-gate  * Memlist support.
1750Sstevel@tonic-gate  */
1760Sstevel@tonic-gate void
1770Sstevel@tonic-gate memlist_delete(struct memlist *mlist)
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate 	register struct memlist	*ml;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	for (ml = mlist; ml; ml = mlist) {
1820Sstevel@tonic-gate 		mlist = ml->next;
1830Sstevel@tonic-gate 		FREESTRUCT(ml, struct memlist, 1);
1840Sstevel@tonic-gate 	}
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate int
1880Sstevel@tonic-gate memlist_intersect(struct memlist *al, struct memlist *bl)
1890Sstevel@tonic-gate {
1900Sstevel@tonic-gate 	uint64_t	astart, aend, bstart, bend;
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate 	if ((al == NULL) || (bl == NULL))
1930Sstevel@tonic-gate 		return (0);
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	aend = al->address + al->size;
1960Sstevel@tonic-gate 	bstart = bl->address;
1970Sstevel@tonic-gate 	bend = bl->address + bl->size;
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 	while (al && bl) {
2000Sstevel@tonic-gate 		while (al && (aend <= bstart))
2010Sstevel@tonic-gate 			if ((al = al->next) != NULL)
2020Sstevel@tonic-gate 				aend = al->address + al->size;
2030Sstevel@tonic-gate 		if (al == NULL)
2040Sstevel@tonic-gate 			return (0);
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 		if ((astart = al->address) <= bstart)
2070Sstevel@tonic-gate 			return (1);
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 		while (bl && (bend <= astart))
2100Sstevel@tonic-gate 			if ((bl = bl->next) != NULL)
2110Sstevel@tonic-gate 				bend = bl->address + bl->size;
2120Sstevel@tonic-gate 		if (bl == NULL)
2130Sstevel@tonic-gate 			return (0);
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		if ((bstart = bl->address) <= astart)
2160Sstevel@tonic-gate 			return (1);
2170Sstevel@tonic-gate 	}
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	return (0);
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate void
2230Sstevel@tonic-gate memlist_coalesce(struct memlist *mlist)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate 	uint64_t	end, nend;
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	if ((mlist == NULL) || (mlist->next == NULL))
2280Sstevel@tonic-gate 		return;
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	while (mlist->next) {
2310Sstevel@tonic-gate 		end = mlist->address + mlist->size;
2320Sstevel@tonic-gate 		if (mlist->next->address <= end) {
2330Sstevel@tonic-gate 			struct memlist 	*nl;
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 			nend = mlist->next->address + mlist->next->size;
2360Sstevel@tonic-gate 			if (nend > end)
2370Sstevel@tonic-gate 				mlist->size += (nend - end);
2380Sstevel@tonic-gate 			nl = mlist->next;
2390Sstevel@tonic-gate 			mlist->next = mlist->next->next;
2400Sstevel@tonic-gate 			if (nl) {
2410Sstevel@tonic-gate 				FREESTRUCT(nl, struct memlist, 1);
2420Sstevel@tonic-gate 			}
2430Sstevel@tonic-gate 			if (mlist->next)
2440Sstevel@tonic-gate 				mlist->next->prev = mlist;
2450Sstevel@tonic-gate 		} else {
2460Sstevel@tonic-gate 			mlist = mlist->next;
2470Sstevel@tonic-gate 		}
2480Sstevel@tonic-gate 	}
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate #ifdef DEBUG
2520Sstevel@tonic-gate void
2530Sstevel@tonic-gate memlist_dump(struct memlist *mlist)
2540Sstevel@tonic-gate {
2550Sstevel@tonic-gate 	register struct memlist *ml;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	if (mlist == NULL)
2580Sstevel@tonic-gate 		printf("memlist> EMPTY\n");
2590Sstevel@tonic-gate 	else for (ml = mlist; ml; ml = ml->next)
260*930Smathue 		printf("memlist> 0x%lx, 0x%lx\n", ml->address, ml->size);
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate #endif
263