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 525cf1a30Sjl139090 * Common Development and Distribution License (the "License"). 625cf1a30Sjl139090 * 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 */ 2107d06da5SSurya Prakki 227c478bd9Sstevel@tonic-gate /* 23*56f33205SJonathan Adams * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2404580fdfSmathue * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 287c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 297c478bd9Sstevel@tonic-gate #include <sys/param.h> /* for NULL */ 307c478bd9Sstevel@tonic-gate #include <sys/sbd_ioctl.h> 317c478bd9Sstevel@tonic-gate #include <sys/dr_util.h> 327c478bd9Sstevel@tonic-gate #include <sys/varargs.h> 337c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 347c478bd9Sstevel@tonic-gate #include <sys/systm.h> 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */ 377c478bd9Sstevel@tonic-gate extern sbd_etab_t sbd_etab[]; 387c478bd9Sstevel@tonic-gate extern int sbd_etab_len; 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate sbd_error_t * 417c478bd9Sstevel@tonic-gate sbd_err_new(int e_code, char *fmt, va_list args) 427c478bd9Sstevel@tonic-gate { 437c478bd9Sstevel@tonic-gate sbd_error_t *new; 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate new = GETSTRUCT(sbd_error_t, 1); 467c478bd9Sstevel@tonic-gate new->e_code = e_code; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate if (fmt) 497c478bd9Sstevel@tonic-gate (void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args); 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate return (new); 527c478bd9Sstevel@tonic-gate } 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate void 557c478bd9Sstevel@tonic-gate sbd_err_log(sbd_error_t *ep, int ce) 567c478bd9Sstevel@tonic-gate { 577c478bd9Sstevel@tonic-gate char buf[32]; 587c478bd9Sstevel@tonic-gate char *fmt; 597c478bd9Sstevel@tonic-gate char *txt; 607c478bd9Sstevel@tonic-gate int i; 617c478bd9Sstevel@tonic-gate sbd_etab_t *tp; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate if (!ep) 647c478bd9Sstevel@tonic-gate return; 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate if (ep->e_rsc[0] == '\0') 677c478bd9Sstevel@tonic-gate fmt = "%s"; 687c478bd9Sstevel@tonic-gate else 697c478bd9Sstevel@tonic-gate fmt = "%s: %s"; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++) 727c478bd9Sstevel@tonic-gate if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd) 737c478bd9Sstevel@tonic-gate break; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate if (i < sbd_etab_len) 767c478bd9Sstevel@tonic-gate txt = tp->t_text[ep->e_code - tp->t_base]; 777c478bd9Sstevel@tonic-gate else { 7807d06da5SSurya Prakki (void) snprintf(buf, sizeof (buf), "error %d", ep->e_code); 797c478bd9Sstevel@tonic-gate txt = buf; 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate cmn_err(ce, fmt, txt, ep->e_rsc); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate void 867c478bd9Sstevel@tonic-gate sbd_err_clear(sbd_error_t **ep) 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate FREESTRUCT(*ep, sbd_error_t, 1); 897c478bd9Sstevel@tonic-gate *ep = NULL; 907c478bd9Sstevel@tonic-gate } 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate void 937c478bd9Sstevel@tonic-gate sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...) 947c478bd9Sstevel@tonic-gate { 957c478bd9Sstevel@tonic-gate sbd_error_t *tmp; 967c478bd9Sstevel@tonic-gate va_list args; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate va_start(args, fmt); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate tmp = sbd_err_new(e_code, fmt, args); 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate sbd_err_log(tmp, ce); 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate if (*ep == NULL) 1057c478bd9Sstevel@tonic-gate *ep = tmp; 1067c478bd9Sstevel@tonic-gate else 1077c478bd9Sstevel@tonic-gate sbd_err_clear(&tmp); 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate va_end(args); 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate void 1137c478bd9Sstevel@tonic-gate sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...) 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate sbd_error_t *tmp; 1167c478bd9Sstevel@tonic-gate va_list args; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate va_start(args, fmt); 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate tmp = sbd_err_new(e_code, fmt, args); 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate sbd_err_log(tmp, ce); 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate *ep = tmp; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate va_end(args); 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate sbd_error_t * 1307c478bd9Sstevel@tonic-gate drerr_new_v(int e_code, char *fmt, va_list args) 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate return (sbd_err_new(e_code, fmt, args)); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate sbd_error_t * 1367c478bd9Sstevel@tonic-gate drerr_new(int log, int e_code, char *fmt, ...) 1377c478bd9Sstevel@tonic-gate { 1387c478bd9Sstevel@tonic-gate sbd_error_t *ep; 1397c478bd9Sstevel@tonic-gate va_list args; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate va_start(args, fmt); 1427c478bd9Sstevel@tonic-gate ep = sbd_err_new(e_code, fmt, args); 1437c478bd9Sstevel@tonic-gate va_end(args); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if (log) 1467c478bd9Sstevel@tonic-gate sbd_err_log(ep, CE_WARN); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate return (ep); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate void 1527c478bd9Sstevel@tonic-gate drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate sbd_error_t *err; 1557c478bd9Sstevel@tonic-gate va_list args; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate va_start(args, fmt); 1587c478bd9Sstevel@tonic-gate err = sbd_err_new(e_code, fmt, args); 1597c478bd9Sstevel@tonic-gate va_end(args); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate if (log) 1627c478bd9Sstevel@tonic-gate sbd_err_log(err, CE_WARN); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate if (*ep == NULL) 1657c478bd9Sstevel@tonic-gate *ep = err; 1667c478bd9Sstevel@tonic-gate else 1677c478bd9Sstevel@tonic-gate sbd_err_clear(&err); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * Memlist support. 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate void 17525cf1a30Sjl139090 dr_memlist_delete(struct memlist *mlist) 1767c478bd9Sstevel@tonic-gate { 1777c478bd9Sstevel@tonic-gate register struct memlist *ml; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate for (ml = mlist; ml; ml = mlist) { 180*56f33205SJonathan Adams mlist = ml->ml_next; 1817c478bd9Sstevel@tonic-gate FREESTRUCT(ml, struct memlist, 1); 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate int 18625cf1a30Sjl139090 dr_memlist_intersect(struct memlist *al, struct memlist *bl) 1877c478bd9Sstevel@tonic-gate { 1887c478bd9Sstevel@tonic-gate uint64_t astart, aend, bstart, bend; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate if ((al == NULL) || (bl == NULL)) 1917c478bd9Sstevel@tonic-gate return (0); 1927c478bd9Sstevel@tonic-gate 193*56f33205SJonathan Adams aend = al->ml_address + al->ml_size; 194*56f33205SJonathan Adams bstart = bl->ml_address; 195*56f33205SJonathan Adams bend = bl->ml_address + bl->ml_size; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate while (al && bl) { 1987c478bd9Sstevel@tonic-gate while (al && (aend <= bstart)) 199*56f33205SJonathan Adams if ((al = al->ml_next) != NULL) 200*56f33205SJonathan Adams aend = al->ml_address + al->ml_size; 2017c478bd9Sstevel@tonic-gate if (al == NULL) 2027c478bd9Sstevel@tonic-gate return (0); 2037c478bd9Sstevel@tonic-gate 204*56f33205SJonathan Adams if ((astart = al->ml_address) <= bstart) 2057c478bd9Sstevel@tonic-gate return (1); 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate while (bl && (bend <= astart)) 208*56f33205SJonathan Adams if ((bl = bl->ml_next) != NULL) 209*56f33205SJonathan Adams bend = bl->ml_address + bl->ml_size; 2107c478bd9Sstevel@tonic-gate if (bl == NULL) 2117c478bd9Sstevel@tonic-gate return (0); 2127c478bd9Sstevel@tonic-gate 213*56f33205SJonathan Adams if ((bstart = bl->ml_address) <= astart) 2147c478bd9Sstevel@tonic-gate return (1); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate return (0); 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate void 22125cf1a30Sjl139090 dr_memlist_coalesce(struct memlist *mlist) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate uint64_t end, nend; 2247c478bd9Sstevel@tonic-gate 225*56f33205SJonathan Adams if ((mlist == NULL) || (mlist->ml_next == NULL)) 2267c478bd9Sstevel@tonic-gate return; 2277c478bd9Sstevel@tonic-gate 228*56f33205SJonathan Adams while (mlist->ml_next) { 229*56f33205SJonathan Adams end = mlist->ml_address + mlist->ml_size; 230*56f33205SJonathan Adams if (mlist->ml_next->ml_address <= end) { 2317c478bd9Sstevel@tonic-gate struct memlist *nl; 2327c478bd9Sstevel@tonic-gate 233*56f33205SJonathan Adams nend = mlist->ml_next->ml_address + 234*56f33205SJonathan Adams mlist->ml_next->ml_size; 2357c478bd9Sstevel@tonic-gate if (nend > end) 236*56f33205SJonathan Adams mlist->ml_size += (nend - end); 237*56f33205SJonathan Adams nl = mlist->ml_next; 238*56f33205SJonathan Adams mlist->ml_next = mlist->ml_next->ml_next; 2397c478bd9Sstevel@tonic-gate if (nl) { 2407c478bd9Sstevel@tonic-gate FREESTRUCT(nl, struct memlist, 1); 2417c478bd9Sstevel@tonic-gate } 242*56f33205SJonathan Adams if (mlist->ml_next) 243*56f33205SJonathan Adams mlist->ml_next->ml_prev = mlist; 2447c478bd9Sstevel@tonic-gate } else { 245*56f33205SJonathan Adams mlist = mlist->ml_next; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate #ifdef DEBUG 2517c478bd9Sstevel@tonic-gate void 2527c478bd9Sstevel@tonic-gate memlist_dump(struct memlist *mlist) 2537c478bd9Sstevel@tonic-gate { 2547c478bd9Sstevel@tonic-gate register struct memlist *ml; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate if (mlist == NULL) 2577c478bd9Sstevel@tonic-gate printf("memlist> EMPTY\n"); 258*56f33205SJonathan Adams else for (ml = mlist; ml; ml = ml->ml_next) 259*56f33205SJonathan Adams printf("memlist> 0x%lx, 0x%lx\n", ml->ml_address, ml->ml_size); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate #endif 26225cf1a30Sjl139090 26325cf1a30Sjl139090 struct memlist * 26425cf1a30Sjl139090 dr_memlist_dup(struct memlist *mlist) 26525cf1a30Sjl139090 { 26625cf1a30Sjl139090 struct memlist *hl = NULL, *tl, **mlp; 26725cf1a30Sjl139090 26825cf1a30Sjl139090 if (mlist == NULL) 26925cf1a30Sjl139090 return (NULL); 27025cf1a30Sjl139090 27125cf1a30Sjl139090 mlp = &hl; 27225cf1a30Sjl139090 tl = *mlp; 273*56f33205SJonathan Adams for (; mlist; mlist = mlist->ml_next) { 27425cf1a30Sjl139090 *mlp = GETSTRUCT(struct memlist, 1); 275*56f33205SJonathan Adams (*mlp)->ml_address = mlist->ml_address; 276*56f33205SJonathan Adams (*mlp)->ml_size = mlist->ml_size; 277*56f33205SJonathan Adams (*mlp)->ml_prev = tl; 27825cf1a30Sjl139090 tl = *mlp; 279*56f33205SJonathan Adams mlp = &((*mlp)->ml_next); 28025cf1a30Sjl139090 } 28125cf1a30Sjl139090 *mlp = NULL; 28225cf1a30Sjl139090 28325cf1a30Sjl139090 return (hl); 28425cf1a30Sjl139090 } 28525cf1a30Sjl139090 28625cf1a30Sjl139090 struct memlist * 28725cf1a30Sjl139090 dr_memlist_add_span(struct memlist *mlist, uint64_t base, uint64_t len) 28825cf1a30Sjl139090 { 28925cf1a30Sjl139090 struct memlist *ml, *tl, *nl; 29025cf1a30Sjl139090 29125cf1a30Sjl139090 if (len == 0ull) 29225cf1a30Sjl139090 return (NULL); 29325cf1a30Sjl139090 29425cf1a30Sjl139090 if (mlist == NULL) { 29525cf1a30Sjl139090 mlist = GETSTRUCT(struct memlist, 1); 296*56f33205SJonathan Adams mlist->ml_address = base; 297*56f33205SJonathan Adams mlist->ml_size = len; 298*56f33205SJonathan Adams mlist->ml_next = mlist->ml_prev = NULL; 29925cf1a30Sjl139090 30025cf1a30Sjl139090 return (mlist); 30125cf1a30Sjl139090 } 30225cf1a30Sjl139090 303*56f33205SJonathan Adams for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) { 304*56f33205SJonathan Adams if (base < ml->ml_address) { 305*56f33205SJonathan Adams if ((base + len) < ml->ml_address) { 30625cf1a30Sjl139090 nl = GETSTRUCT(struct memlist, 1); 307*56f33205SJonathan Adams nl->ml_address = base; 308*56f33205SJonathan Adams nl->ml_size = len; 309*56f33205SJonathan Adams nl->ml_next = ml; 310*56f33205SJonathan Adams if ((nl->ml_prev = ml->ml_prev) != NULL) 311*56f33205SJonathan Adams nl->ml_prev->ml_next = nl; 312*56f33205SJonathan Adams ml->ml_prev = nl; 31325cf1a30Sjl139090 if (mlist == ml) 31425cf1a30Sjl139090 mlist = nl; 31525cf1a30Sjl139090 } else { 316*56f33205SJonathan Adams ml->ml_size = MAX((base + len), 317*56f33205SJonathan Adams (ml->ml_address + ml->ml_size)) - base; 318*56f33205SJonathan Adams ml->ml_address = base; 31925cf1a30Sjl139090 } 32025cf1a30Sjl139090 break; 32125cf1a30Sjl139090 322*56f33205SJonathan Adams } else if (base <= (ml->ml_address + ml->ml_size)) { 323*56f33205SJonathan Adams ml->ml_size = MAX((base + len), 324*56f33205SJonathan Adams (ml->ml_address + ml->ml_size)) - 325*56f33205SJonathan Adams MIN(ml->ml_address, base); 326*56f33205SJonathan Adams ml->ml_address = MIN(ml->ml_address, base); 32725cf1a30Sjl139090 break; 32825cf1a30Sjl139090 } 32925cf1a30Sjl139090 } 33025cf1a30Sjl139090 if (ml == NULL) { 33125cf1a30Sjl139090 nl = GETSTRUCT(struct memlist, 1); 332*56f33205SJonathan Adams nl->ml_address = base; 333*56f33205SJonathan Adams nl->ml_size = len; 334*56f33205SJonathan Adams nl->ml_next = NULL; 335*56f33205SJonathan Adams nl->ml_prev = tl; 336*56f33205SJonathan Adams tl->ml_next = nl; 33725cf1a30Sjl139090 } 33825cf1a30Sjl139090 33925cf1a30Sjl139090 dr_memlist_coalesce(mlist); 34025cf1a30Sjl139090 34125cf1a30Sjl139090 return (mlist); 34225cf1a30Sjl139090 } 34325cf1a30Sjl139090 34425cf1a30Sjl139090 struct memlist * 34525cf1a30Sjl139090 dr_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len) 34625cf1a30Sjl139090 { 34725cf1a30Sjl139090 uint64_t end; 34825cf1a30Sjl139090 struct memlist *ml, *tl, *nlp; 34925cf1a30Sjl139090 35025cf1a30Sjl139090 if (mlist == NULL) 35125cf1a30Sjl139090 return (NULL); 35225cf1a30Sjl139090 35325cf1a30Sjl139090 end = base + len; 354*56f33205SJonathan Adams if ((end <= mlist->ml_address) || (base == end)) 35525cf1a30Sjl139090 return (mlist); 35625cf1a30Sjl139090 35725cf1a30Sjl139090 for (tl = ml = mlist; ml; tl = ml, ml = nlp) { 35825cf1a30Sjl139090 uint64_t mend; 35925cf1a30Sjl139090 360*56f33205SJonathan Adams nlp = ml->ml_next; 36125cf1a30Sjl139090 362*56f33205SJonathan Adams if (end <= ml->ml_address) 36325cf1a30Sjl139090 break; 36425cf1a30Sjl139090 365*56f33205SJonathan Adams mend = ml->ml_address + ml->ml_size; 36625cf1a30Sjl139090 if (base < mend) { 367*56f33205SJonathan Adams if (base <= ml->ml_address) { 368*56f33205SJonathan Adams ml->ml_address = end; 36925cf1a30Sjl139090 if (end >= mend) 370*56f33205SJonathan Adams ml->ml_size = 0ull; 37125cf1a30Sjl139090 else 372*56f33205SJonathan Adams ml->ml_size = mend - ml->ml_address; 37325cf1a30Sjl139090 } else { 374*56f33205SJonathan Adams ml->ml_size = base - ml->ml_address; 37525cf1a30Sjl139090 if (end < mend) { 37625cf1a30Sjl139090 struct memlist *nl; 37725cf1a30Sjl139090 /* 37825cf1a30Sjl139090 * splitting an memlist entry. 37925cf1a30Sjl139090 */ 38025cf1a30Sjl139090 nl = GETSTRUCT(struct memlist, 1); 381*56f33205SJonathan Adams nl->ml_address = end; 382*56f33205SJonathan Adams nl->ml_size = mend - nl->ml_address; 383*56f33205SJonathan Adams if ((nl->ml_next = nlp) != NULL) 384*56f33205SJonathan Adams nlp->ml_prev = nl; 385*56f33205SJonathan Adams nl->ml_prev = ml; 386*56f33205SJonathan Adams ml->ml_next = nl; 38725cf1a30Sjl139090 nlp = nl; 38825cf1a30Sjl139090 } 38925cf1a30Sjl139090 } 390*56f33205SJonathan Adams if (ml->ml_size == 0ull) { 39125cf1a30Sjl139090 if (ml == mlist) { 39225cf1a30Sjl139090 if ((mlist = nlp) != NULL) 393*56f33205SJonathan Adams nlp->ml_prev = NULL; 39425cf1a30Sjl139090 FREESTRUCT(ml, struct memlist, 1); 39525cf1a30Sjl139090 if (mlist == NULL) 39625cf1a30Sjl139090 break; 39725cf1a30Sjl139090 ml = nlp; 39825cf1a30Sjl139090 } else { 399*56f33205SJonathan Adams if ((tl->ml_next = nlp) != NULL) 400*56f33205SJonathan Adams nlp->ml_prev = tl; 40125cf1a30Sjl139090 FREESTRUCT(ml, struct memlist, 1); 40225cf1a30Sjl139090 ml = tl; 40325cf1a30Sjl139090 } 40425cf1a30Sjl139090 } 40525cf1a30Sjl139090 } 40625cf1a30Sjl139090 } 40725cf1a30Sjl139090 40825cf1a30Sjl139090 return (mlist); 40925cf1a30Sjl139090 } 41025cf1a30Sjl139090 41125cf1a30Sjl139090 /* 41225cf1a30Sjl139090 * add span without merging 41325cf1a30Sjl139090 */ 41425cf1a30Sjl139090 struct memlist * 41525cf1a30Sjl139090 dr_memlist_cat_span(struct memlist *mlist, uint64_t base, uint64_t len) 41625cf1a30Sjl139090 { 41725cf1a30Sjl139090 struct memlist *ml, *tl, *nl; 41825cf1a30Sjl139090 41925cf1a30Sjl139090 if (len == 0ull) 42025cf1a30Sjl139090 return (NULL); 42125cf1a30Sjl139090 42225cf1a30Sjl139090 if (mlist == NULL) { 42325cf1a30Sjl139090 mlist = GETSTRUCT(struct memlist, 1); 424*56f33205SJonathan Adams mlist->ml_address = base; 425*56f33205SJonathan Adams mlist->ml_size = len; 426*56f33205SJonathan Adams mlist->ml_next = mlist->ml_prev = NULL; 42725cf1a30Sjl139090 42825cf1a30Sjl139090 return (mlist); 42925cf1a30Sjl139090 } 43025cf1a30Sjl139090 431*56f33205SJonathan Adams for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) { 432*56f33205SJonathan Adams if (base < ml->ml_address) { 43325cf1a30Sjl139090 nl = GETSTRUCT(struct memlist, 1); 434*56f33205SJonathan Adams nl->ml_address = base; 435*56f33205SJonathan Adams nl->ml_size = len; 436*56f33205SJonathan Adams nl->ml_next = ml; 437*56f33205SJonathan Adams if ((nl->ml_prev = ml->ml_prev) != NULL) 438*56f33205SJonathan Adams nl->ml_prev->ml_next = nl; 439*56f33205SJonathan Adams ml->ml_prev = nl; 44025cf1a30Sjl139090 if (mlist == ml) 44125cf1a30Sjl139090 mlist = nl; 44225cf1a30Sjl139090 break; 44325cf1a30Sjl139090 } 44425cf1a30Sjl139090 } 44525cf1a30Sjl139090 44625cf1a30Sjl139090 if (ml == NULL) { 44725cf1a30Sjl139090 nl = GETSTRUCT(struct memlist, 1); 448*56f33205SJonathan Adams nl->ml_address = base; 449*56f33205SJonathan Adams nl->ml_size = len; 450*56f33205SJonathan Adams nl->ml_next = NULL; 451*56f33205SJonathan Adams nl->ml_prev = tl; 452*56f33205SJonathan Adams tl->ml_next = nl; 45325cf1a30Sjl139090 } 45425cf1a30Sjl139090 45525cf1a30Sjl139090 return (mlist); 45625cf1a30Sjl139090 } 457