/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include /* for NULL */ #include #include #include #include #include /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */ extern sbd_etab_t sbd_etab[]; extern int sbd_etab_len; sbd_error_t * sbd_err_new(int e_code, char *fmt, va_list args) { sbd_error_t *new; new = GETSTRUCT(sbd_error_t, 1); new->e_code = e_code; if (fmt) (void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args); return (new); } void sbd_err_log(sbd_error_t *ep, int ce) { char buf[32]; char *fmt; char *txt; int i; sbd_etab_t *tp; if (!ep) return; if (ep->e_rsc[0] == '\0') fmt = "%s"; else fmt = "%s: %s"; for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++) if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd) break; if (i < sbd_etab_len) txt = tp->t_text[ep->e_code - tp->t_base]; else { snprintf(buf, sizeof (buf), "error %d", ep->e_code); txt = buf; } cmn_err(ce, fmt, txt, ep->e_rsc); } void sbd_err_clear(sbd_error_t **ep) { FREESTRUCT(*ep, sbd_error_t, 1); *ep = NULL; } void sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...) { sbd_error_t *tmp; va_list args; va_start(args, fmt); tmp = sbd_err_new(e_code, fmt, args); sbd_err_log(tmp, ce); if (*ep == NULL) *ep = tmp; else sbd_err_clear(&tmp); va_end(args); } void sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...) { sbd_error_t *tmp; va_list args; va_start(args, fmt); tmp = sbd_err_new(e_code, fmt, args); sbd_err_log(tmp, ce); *ep = tmp; va_end(args); } sbd_error_t * drerr_new_v(int e_code, char *fmt, va_list args) { return (sbd_err_new(e_code, fmt, args)); } sbd_error_t * drerr_new(int log, int e_code, char *fmt, ...) { sbd_error_t *ep; va_list args; va_start(args, fmt); ep = sbd_err_new(e_code, fmt, args); va_end(args); if (log) sbd_err_log(ep, CE_WARN); return (ep); } void drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...) { sbd_error_t *err; va_list args; va_start(args, fmt); err = sbd_err_new(e_code, fmt, args); va_end(args); if (log) sbd_err_log(err, CE_WARN); if (*ep == NULL) *ep = err; else sbd_err_clear(&err); } /* * Memlist support. */ void memlist_delete(struct memlist *mlist) { register struct memlist *ml; for (ml = mlist; ml; ml = mlist) { mlist = ml->next; FREESTRUCT(ml, struct memlist, 1); } } int memlist_intersect(struct memlist *al, struct memlist *bl) { uint64_t astart, aend, bstart, bend; if ((al == NULL) || (bl == NULL)) return (0); aend = al->address + al->size; bstart = bl->address; bend = bl->address + bl->size; while (al && bl) { while (al && (aend <= bstart)) if ((al = al->next) != NULL) aend = al->address + al->size; if (al == NULL) return (0); if ((astart = al->address) <= bstart) return (1); while (bl && (bend <= astart)) if ((bl = bl->next) != NULL) bend = bl->address + bl->size; if (bl == NULL) return (0); if ((bstart = bl->address) <= astart) return (1); } return (0); } void memlist_coalesce(struct memlist *mlist) { uint64_t end, nend; if ((mlist == NULL) || (mlist->next == NULL)) return; while (mlist->next) { end = mlist->address + mlist->size; if (mlist->next->address <= end) { struct memlist *nl; nend = mlist->next->address + mlist->next->size; if (nend > end) mlist->size += (nend - end); nl = mlist->next; mlist->next = mlist->next->next; if (nl) { FREESTRUCT(nl, struct memlist, 1); } if (mlist->next) mlist->next->prev = mlist; } else { mlist = mlist->next; } } } #ifdef DEBUG void memlist_dump(struct memlist *mlist) { register struct memlist *ml; if (mlist == NULL) printf("memlist> EMPTY\n"); else for (ml = mlist; ml; ml = ml->next) printf("memlist> 0x%lx, 0x%lx\n", ml->address, ml->size); } #endif