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