1*a3114836SGerry Liu /* 2*a3114836SGerry Liu * CDDL HEADER START 3*a3114836SGerry Liu * 4*a3114836SGerry Liu * The contents of this file are subject to the terms of the 5*a3114836SGerry Liu * Common Development and Distribution License (the "License"). 6*a3114836SGerry Liu * You may not use this file except in compliance with the License. 7*a3114836SGerry Liu * 8*a3114836SGerry Liu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*a3114836SGerry Liu * or http://www.opensolaris.org/os/licensing. 10*a3114836SGerry Liu * See the License for the specific language governing permissions 11*a3114836SGerry Liu * and limitations under the License. 12*a3114836SGerry Liu * 13*a3114836SGerry Liu * When distributing Covered Code, include this CDDL HEADER in each 14*a3114836SGerry Liu * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*a3114836SGerry Liu * If applicable, add the following below this CDDL HEADER, with the 16*a3114836SGerry Liu * fields enclosed by brackets "[]" replaced with your own identifying 17*a3114836SGerry Liu * information: Portions Copyright [yyyy] [name of copyright owner] 18*a3114836SGerry Liu * 19*a3114836SGerry Liu * CDDL HEADER END 20*a3114836SGerry Liu */ 21*a3114836SGerry Liu 22*a3114836SGerry Liu /* 23*a3114836SGerry Liu * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*a3114836SGerry Liu * Use is subject to license terms. 25*a3114836SGerry Liu */ 26*a3114836SGerry Liu 27*a3114836SGerry Liu #include <sys/types.h> 28*a3114836SGerry Liu #include <sys/cmn_err.h> 29*a3114836SGerry Liu #include <sys/param.h> /* for NULL */ 30*a3114836SGerry Liu #include <sys/sbd_ioctl.h> 31*a3114836SGerry Liu #include <sys/dr_util.h> 32*a3114836SGerry Liu #include <sys/varargs.h> 33*a3114836SGerry Liu #include <sys/sysmacros.h> 34*a3114836SGerry Liu #include <sys/systm.h> 35*a3114836SGerry Liu 36*a3114836SGerry Liu /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */ 37*a3114836SGerry Liu extern sbd_etab_t sbd_etab[]; 38*a3114836SGerry Liu extern int sbd_etab_len; 39*a3114836SGerry Liu 40*a3114836SGerry Liu sbd_error_t * 41*a3114836SGerry Liu sbd_err_new(int e_code, char *fmt, va_list args) 42*a3114836SGerry Liu { 43*a3114836SGerry Liu sbd_error_t *new; 44*a3114836SGerry Liu 45*a3114836SGerry Liu new = GETSTRUCT(sbd_error_t, 1); 46*a3114836SGerry Liu new->e_code = e_code; 47*a3114836SGerry Liu 48*a3114836SGerry Liu if (fmt) 49*a3114836SGerry Liu (void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args); 50*a3114836SGerry Liu 51*a3114836SGerry Liu return (new); 52*a3114836SGerry Liu } 53*a3114836SGerry Liu 54*a3114836SGerry Liu void 55*a3114836SGerry Liu sbd_err_log(sbd_error_t *ep, int ce) 56*a3114836SGerry Liu { 57*a3114836SGerry Liu char buf[32]; 58*a3114836SGerry Liu char *fmt; 59*a3114836SGerry Liu char *txt; 60*a3114836SGerry Liu int i; 61*a3114836SGerry Liu sbd_etab_t *tp; 62*a3114836SGerry Liu 63*a3114836SGerry Liu if (!ep) 64*a3114836SGerry Liu return; 65*a3114836SGerry Liu 66*a3114836SGerry Liu if (ep->e_rsc[0] == '\0') 67*a3114836SGerry Liu fmt = "%s"; 68*a3114836SGerry Liu else 69*a3114836SGerry Liu fmt = "%s: %s"; 70*a3114836SGerry Liu 71*a3114836SGerry Liu for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++) 72*a3114836SGerry Liu if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd) 73*a3114836SGerry Liu break; 74*a3114836SGerry Liu 75*a3114836SGerry Liu if (i < sbd_etab_len) 76*a3114836SGerry Liu txt = tp->t_text[ep->e_code - tp->t_base]; 77*a3114836SGerry Liu else { 78*a3114836SGerry Liu (void) snprintf(buf, sizeof (buf), "error %d", ep->e_code); 79*a3114836SGerry Liu txt = buf; 80*a3114836SGerry Liu } 81*a3114836SGerry Liu 82*a3114836SGerry Liu cmn_err(ce, fmt, txt, ep->e_rsc); 83*a3114836SGerry Liu } 84*a3114836SGerry Liu 85*a3114836SGerry Liu void 86*a3114836SGerry Liu sbd_err_clear(sbd_error_t **ep) 87*a3114836SGerry Liu { 88*a3114836SGerry Liu FREESTRUCT(*ep, sbd_error_t, 1); 89*a3114836SGerry Liu *ep = NULL; 90*a3114836SGerry Liu } 91*a3114836SGerry Liu 92*a3114836SGerry Liu void 93*a3114836SGerry Liu sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...) 94*a3114836SGerry Liu { 95*a3114836SGerry Liu sbd_error_t *tmp; 96*a3114836SGerry Liu va_list args; 97*a3114836SGerry Liu 98*a3114836SGerry Liu va_start(args, fmt); 99*a3114836SGerry Liu 100*a3114836SGerry Liu tmp = sbd_err_new(e_code, fmt, args); 101*a3114836SGerry Liu 102*a3114836SGerry Liu sbd_err_log(tmp, ce); 103*a3114836SGerry Liu 104*a3114836SGerry Liu if (*ep == NULL) 105*a3114836SGerry Liu *ep = tmp; 106*a3114836SGerry Liu else 107*a3114836SGerry Liu sbd_err_clear(&tmp); 108*a3114836SGerry Liu 109*a3114836SGerry Liu va_end(args); 110*a3114836SGerry Liu } 111*a3114836SGerry Liu 112*a3114836SGerry Liu void 113*a3114836SGerry Liu sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...) 114*a3114836SGerry Liu { 115*a3114836SGerry Liu sbd_error_t *tmp; 116*a3114836SGerry Liu va_list args; 117*a3114836SGerry Liu 118*a3114836SGerry Liu va_start(args, fmt); 119*a3114836SGerry Liu 120*a3114836SGerry Liu tmp = sbd_err_new(e_code, fmt, args); 121*a3114836SGerry Liu 122*a3114836SGerry Liu sbd_err_log(tmp, ce); 123*a3114836SGerry Liu 124*a3114836SGerry Liu *ep = tmp; 125*a3114836SGerry Liu 126*a3114836SGerry Liu va_end(args); 127*a3114836SGerry Liu } 128*a3114836SGerry Liu 129*a3114836SGerry Liu sbd_error_t * 130*a3114836SGerry Liu drerr_new_v(int e_code, char *fmt, va_list args) 131*a3114836SGerry Liu { 132*a3114836SGerry Liu return (sbd_err_new(e_code, fmt, args)); 133*a3114836SGerry Liu } 134*a3114836SGerry Liu 135*a3114836SGerry Liu sbd_error_t * 136*a3114836SGerry Liu drerr_new(int log, int e_code, char *fmt, ...) 137*a3114836SGerry Liu { 138*a3114836SGerry Liu sbd_error_t *ep; 139*a3114836SGerry Liu va_list args; 140*a3114836SGerry Liu 141*a3114836SGerry Liu va_start(args, fmt); 142*a3114836SGerry Liu ep = sbd_err_new(e_code, fmt, args); 143*a3114836SGerry Liu va_end(args); 144*a3114836SGerry Liu 145*a3114836SGerry Liu if (log) 146*a3114836SGerry Liu sbd_err_log(ep, CE_WARN); 147*a3114836SGerry Liu 148*a3114836SGerry Liu return (ep); 149*a3114836SGerry Liu } 150*a3114836SGerry Liu 151*a3114836SGerry Liu void 152*a3114836SGerry Liu drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...) 153*a3114836SGerry Liu { 154*a3114836SGerry Liu sbd_error_t *err; 155*a3114836SGerry Liu va_list args; 156*a3114836SGerry Liu 157*a3114836SGerry Liu va_start(args, fmt); 158*a3114836SGerry Liu err = sbd_err_new(e_code, fmt, args); 159*a3114836SGerry Liu va_end(args); 160*a3114836SGerry Liu 161*a3114836SGerry Liu if (log) 162*a3114836SGerry Liu sbd_err_log(err, CE_WARN); 163*a3114836SGerry Liu 164*a3114836SGerry Liu if (*ep == NULL) 165*a3114836SGerry Liu *ep = err; 166*a3114836SGerry Liu else 167*a3114836SGerry Liu sbd_err_clear(&err); 168*a3114836SGerry Liu } 169*a3114836SGerry Liu 170*a3114836SGerry Liu 171*a3114836SGerry Liu /* 172*a3114836SGerry Liu * Memlist support. 173*a3114836SGerry Liu */ 174*a3114836SGerry Liu void 175*a3114836SGerry Liu dr_memlist_delete(struct memlist *mlist) 176*a3114836SGerry Liu { 177*a3114836SGerry Liu register struct memlist *ml; 178*a3114836SGerry Liu 179*a3114836SGerry Liu for (ml = mlist; ml; ml = mlist) { 180*a3114836SGerry Liu mlist = ml->ml_next; 181*a3114836SGerry Liu FREESTRUCT(ml, struct memlist, 1); 182*a3114836SGerry Liu } 183*a3114836SGerry Liu } 184*a3114836SGerry Liu 185*a3114836SGerry Liu int 186*a3114836SGerry Liu dr_memlist_intersect(struct memlist *al, struct memlist *bl) 187*a3114836SGerry Liu { 188*a3114836SGerry Liu uint64_t astart, aend, bstart, bend; 189*a3114836SGerry Liu 190*a3114836SGerry Liu if ((al == NULL) || (bl == NULL)) 191*a3114836SGerry Liu return (0); 192*a3114836SGerry Liu 193*a3114836SGerry Liu aend = al->ml_address + al->ml_size; 194*a3114836SGerry Liu bstart = bl->ml_address; 195*a3114836SGerry Liu bend = bl->ml_address + bl->ml_size; 196*a3114836SGerry Liu 197*a3114836SGerry Liu while (al && bl) { 198*a3114836SGerry Liu while (al && (aend <= bstart)) 199*a3114836SGerry Liu if ((al = al->ml_next) != NULL) 200*a3114836SGerry Liu aend = al->ml_address + al->ml_size; 201*a3114836SGerry Liu if (al == NULL) 202*a3114836SGerry Liu return (0); 203*a3114836SGerry Liu 204*a3114836SGerry Liu if ((astart = al->ml_address) <= bstart) 205*a3114836SGerry Liu return (1); 206*a3114836SGerry Liu 207*a3114836SGerry Liu while (bl && (bend <= astart)) 208*a3114836SGerry Liu if ((bl = bl->ml_next) != NULL) 209*a3114836SGerry Liu bend = bl->ml_address + bl->ml_size; 210*a3114836SGerry Liu if (bl == NULL) 211*a3114836SGerry Liu return (0); 212*a3114836SGerry Liu 213*a3114836SGerry Liu if ((bstart = bl->ml_address) <= astart) 214*a3114836SGerry Liu return (1); 215*a3114836SGerry Liu } 216*a3114836SGerry Liu 217*a3114836SGerry Liu return (0); 218*a3114836SGerry Liu } 219*a3114836SGerry Liu 220*a3114836SGerry Liu void 221*a3114836SGerry Liu dr_memlist_coalesce(struct memlist *mlist) 222*a3114836SGerry Liu { 223*a3114836SGerry Liu uint64_t end, nend; 224*a3114836SGerry Liu 225*a3114836SGerry Liu if ((mlist == NULL) || (mlist->ml_next == NULL)) 226*a3114836SGerry Liu return; 227*a3114836SGerry Liu 228*a3114836SGerry Liu while (mlist->ml_next) { 229*a3114836SGerry Liu end = mlist->ml_address + mlist->ml_size; 230*a3114836SGerry Liu if (mlist->ml_next->ml_address <= end) { 231*a3114836SGerry Liu struct memlist *nl; 232*a3114836SGerry Liu 233*a3114836SGerry Liu nend = mlist->ml_next->ml_address + 234*a3114836SGerry Liu mlist->ml_next->ml_size; 235*a3114836SGerry Liu if (nend > end) 236*a3114836SGerry Liu mlist->ml_size += (nend - end); 237*a3114836SGerry Liu nl = mlist->ml_next; 238*a3114836SGerry Liu mlist->ml_next = mlist->ml_next->ml_next; 239*a3114836SGerry Liu if (nl) { 240*a3114836SGerry Liu FREESTRUCT(nl, struct memlist, 1); 241*a3114836SGerry Liu } 242*a3114836SGerry Liu if (mlist->ml_next) 243*a3114836SGerry Liu mlist->ml_next->ml_prev = mlist; 244*a3114836SGerry Liu } else { 245*a3114836SGerry Liu mlist = mlist->ml_next; 246*a3114836SGerry Liu } 247*a3114836SGerry Liu } 248*a3114836SGerry Liu } 249*a3114836SGerry Liu 250*a3114836SGerry Liu #ifdef DEBUG 251*a3114836SGerry Liu void 252*a3114836SGerry Liu memlist_dump(struct memlist *mlist) 253*a3114836SGerry Liu { 254*a3114836SGerry Liu register struct memlist *ml; 255*a3114836SGerry Liu 256*a3114836SGerry Liu if (mlist == NULL) 257*a3114836SGerry Liu printf("memlist> EMPTY\n"); 258*a3114836SGerry Liu else for (ml = mlist; ml; ml = ml->ml_next) 259*a3114836SGerry Liu printf("memlist> 0x%" PRIx64 ", 0x%" PRIx64 "\n", 260*a3114836SGerry Liu ml->ml_address, ml->ml_size); 261*a3114836SGerry Liu } 262*a3114836SGerry Liu #endif 263*a3114836SGerry Liu 264*a3114836SGerry Liu struct memlist * 265*a3114836SGerry Liu dr_memlist_dup(struct memlist *mlist) 266*a3114836SGerry Liu { 267*a3114836SGerry Liu struct memlist *hl = NULL, *tl, **mlp; 268*a3114836SGerry Liu 269*a3114836SGerry Liu if (mlist == NULL) 270*a3114836SGerry Liu return (NULL); 271*a3114836SGerry Liu 272*a3114836SGerry Liu mlp = &hl; 273*a3114836SGerry Liu tl = *mlp; 274*a3114836SGerry Liu for (; mlist; mlist = mlist->ml_next) { 275*a3114836SGerry Liu *mlp = GETSTRUCT(struct memlist, 1); 276*a3114836SGerry Liu (*mlp)->ml_address = mlist->ml_address; 277*a3114836SGerry Liu (*mlp)->ml_size = mlist->ml_size; 278*a3114836SGerry Liu (*mlp)->ml_prev = tl; 279*a3114836SGerry Liu tl = *mlp; 280*a3114836SGerry Liu mlp = &((*mlp)->ml_next); 281*a3114836SGerry Liu } 282*a3114836SGerry Liu *mlp = NULL; 283*a3114836SGerry Liu 284*a3114836SGerry Liu return (hl); 285*a3114836SGerry Liu } 286*a3114836SGerry Liu 287*a3114836SGerry Liu struct memlist * 288*a3114836SGerry Liu dr_memlist_add_span(struct memlist *mlist, uint64_t base, uint64_t len) 289*a3114836SGerry Liu { 290*a3114836SGerry Liu struct memlist *ml, *tl, *nl; 291*a3114836SGerry Liu 292*a3114836SGerry Liu if (len == 0ull) 293*a3114836SGerry Liu return (NULL); 294*a3114836SGerry Liu 295*a3114836SGerry Liu if (mlist == NULL) { 296*a3114836SGerry Liu mlist = GETSTRUCT(struct memlist, 1); 297*a3114836SGerry Liu mlist->ml_address = base; 298*a3114836SGerry Liu mlist->ml_size = len; 299*a3114836SGerry Liu mlist->ml_next = mlist->ml_prev = NULL; 300*a3114836SGerry Liu 301*a3114836SGerry Liu return (mlist); 302*a3114836SGerry Liu } 303*a3114836SGerry Liu 304*a3114836SGerry Liu for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) { 305*a3114836SGerry Liu if (base < ml->ml_address) { 306*a3114836SGerry Liu if ((base + len) < ml->ml_address) { 307*a3114836SGerry Liu nl = GETSTRUCT(struct memlist, 1); 308*a3114836SGerry Liu nl->ml_address = base; 309*a3114836SGerry Liu nl->ml_size = len; 310*a3114836SGerry Liu nl->ml_next = ml; 311*a3114836SGerry Liu if ((nl->ml_prev = ml->ml_prev) != NULL) 312*a3114836SGerry Liu nl->ml_prev->ml_next = nl; 313*a3114836SGerry Liu ml->ml_prev = nl; 314*a3114836SGerry Liu if (mlist == ml) 315*a3114836SGerry Liu mlist = nl; 316*a3114836SGerry Liu } else { 317*a3114836SGerry Liu ml->ml_size = MAX((base + len), 318*a3114836SGerry Liu (ml->ml_address + ml->ml_size)) - base; 319*a3114836SGerry Liu ml->ml_address = base; 320*a3114836SGerry Liu } 321*a3114836SGerry Liu break; 322*a3114836SGerry Liu 323*a3114836SGerry Liu } else if (base <= (ml->ml_address + ml->ml_size)) { 324*a3114836SGerry Liu ml->ml_size = MAX((base + len), 325*a3114836SGerry Liu (ml->ml_address + ml->ml_size)) - 326*a3114836SGerry Liu MIN(ml->ml_address, base); 327*a3114836SGerry Liu ml->ml_address = MIN(ml->ml_address, base); 328*a3114836SGerry Liu break; 329*a3114836SGerry Liu } 330*a3114836SGerry Liu } 331*a3114836SGerry Liu if (ml == NULL) { 332*a3114836SGerry Liu nl = GETSTRUCT(struct memlist, 1); 333*a3114836SGerry Liu nl->ml_address = base; 334*a3114836SGerry Liu nl->ml_size = len; 335*a3114836SGerry Liu nl->ml_next = NULL; 336*a3114836SGerry Liu nl->ml_prev = tl; 337*a3114836SGerry Liu tl->ml_next = nl; 338*a3114836SGerry Liu } 339*a3114836SGerry Liu 340*a3114836SGerry Liu dr_memlist_coalesce(mlist); 341*a3114836SGerry Liu 342*a3114836SGerry Liu return (mlist); 343*a3114836SGerry Liu } 344*a3114836SGerry Liu 345*a3114836SGerry Liu struct memlist * 346*a3114836SGerry Liu dr_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len) 347*a3114836SGerry Liu { 348*a3114836SGerry Liu uint64_t end; 349*a3114836SGerry Liu struct memlist *ml, *tl, *nlp; 350*a3114836SGerry Liu 351*a3114836SGerry Liu if (mlist == NULL) 352*a3114836SGerry Liu return (NULL); 353*a3114836SGerry Liu 354*a3114836SGerry Liu end = base + len; 355*a3114836SGerry Liu if ((end <= mlist->ml_address) || (base == end)) 356*a3114836SGerry Liu return (mlist); 357*a3114836SGerry Liu 358*a3114836SGerry Liu for (tl = ml = mlist; ml; tl = ml, ml = nlp) { 359*a3114836SGerry Liu uint64_t mend; 360*a3114836SGerry Liu 361*a3114836SGerry Liu nlp = ml->ml_next; 362*a3114836SGerry Liu 363*a3114836SGerry Liu if (end <= ml->ml_address) 364*a3114836SGerry Liu break; 365*a3114836SGerry Liu 366*a3114836SGerry Liu mend = ml->ml_address + ml->ml_size; 367*a3114836SGerry Liu if (base < mend) { 368*a3114836SGerry Liu if (base <= ml->ml_address) { 369*a3114836SGerry Liu ml->ml_address = end; 370*a3114836SGerry Liu if (end >= mend) 371*a3114836SGerry Liu ml->ml_size = 0ull; 372*a3114836SGerry Liu else 373*a3114836SGerry Liu ml->ml_size = mend - ml->ml_address; 374*a3114836SGerry Liu } else { 375*a3114836SGerry Liu ml->ml_size = base - ml->ml_address; 376*a3114836SGerry Liu if (end < mend) { 377*a3114836SGerry Liu struct memlist *nl; 378*a3114836SGerry Liu /* 379*a3114836SGerry Liu * splitting an memlist entry. 380*a3114836SGerry Liu */ 381*a3114836SGerry Liu nl = GETSTRUCT(struct memlist, 1); 382*a3114836SGerry Liu nl->ml_address = end; 383*a3114836SGerry Liu nl->ml_size = mend - nl->ml_address; 384*a3114836SGerry Liu if ((nl->ml_next = nlp) != NULL) 385*a3114836SGerry Liu nlp->ml_prev = nl; 386*a3114836SGerry Liu nl->ml_prev = ml; 387*a3114836SGerry Liu ml->ml_next = nl; 388*a3114836SGerry Liu nlp = nl; 389*a3114836SGerry Liu } 390*a3114836SGerry Liu } 391*a3114836SGerry Liu if (ml->ml_size == 0ull) { 392*a3114836SGerry Liu if (ml == mlist) { 393*a3114836SGerry Liu if ((mlist = nlp) != NULL) 394*a3114836SGerry Liu nlp->ml_prev = NULL; 395*a3114836SGerry Liu FREESTRUCT(ml, struct memlist, 1); 396*a3114836SGerry Liu if (mlist == NULL) 397*a3114836SGerry Liu break; 398*a3114836SGerry Liu ml = nlp; 399*a3114836SGerry Liu } else { 400*a3114836SGerry Liu if ((tl->ml_next = nlp) != NULL) 401*a3114836SGerry Liu nlp->ml_prev = tl; 402*a3114836SGerry Liu FREESTRUCT(ml, struct memlist, 1); 403*a3114836SGerry Liu ml = tl; 404*a3114836SGerry Liu } 405*a3114836SGerry Liu } 406*a3114836SGerry Liu } 407*a3114836SGerry Liu } 408*a3114836SGerry Liu 409*a3114836SGerry Liu return (mlist); 410*a3114836SGerry Liu } 411*a3114836SGerry Liu 412*a3114836SGerry Liu /* 413*a3114836SGerry Liu * add span without merging 414*a3114836SGerry Liu */ 415*a3114836SGerry Liu struct memlist * 416*a3114836SGerry Liu dr_memlist_cat_span(struct memlist *mlist, uint64_t base, uint64_t len) 417*a3114836SGerry Liu { 418*a3114836SGerry Liu struct memlist *ml, *tl, *nl; 419*a3114836SGerry Liu 420*a3114836SGerry Liu if (len == 0ull) 421*a3114836SGerry Liu return (NULL); 422*a3114836SGerry Liu 423*a3114836SGerry Liu if (mlist == NULL) { 424*a3114836SGerry Liu mlist = GETSTRUCT(struct memlist, 1); 425*a3114836SGerry Liu mlist->ml_address = base; 426*a3114836SGerry Liu mlist->ml_size = len; 427*a3114836SGerry Liu mlist->ml_next = mlist->ml_prev = NULL; 428*a3114836SGerry Liu 429*a3114836SGerry Liu return (mlist); 430*a3114836SGerry Liu } 431*a3114836SGerry Liu 432*a3114836SGerry Liu for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) { 433*a3114836SGerry Liu if (base < ml->ml_address) { 434*a3114836SGerry Liu nl = GETSTRUCT(struct memlist, 1); 435*a3114836SGerry Liu nl->ml_address = base; 436*a3114836SGerry Liu nl->ml_size = len; 437*a3114836SGerry Liu nl->ml_next = ml; 438*a3114836SGerry Liu if ((nl->ml_prev = ml->ml_prev) != NULL) 439*a3114836SGerry Liu nl->ml_prev->ml_next = nl; 440*a3114836SGerry Liu ml->ml_prev = nl; 441*a3114836SGerry Liu if (mlist == ml) 442*a3114836SGerry Liu mlist = nl; 443*a3114836SGerry Liu break; 444*a3114836SGerry Liu } 445*a3114836SGerry Liu } 446*a3114836SGerry Liu 447*a3114836SGerry Liu if (ml == NULL) { 448*a3114836SGerry Liu nl = GETSTRUCT(struct memlist, 1); 449*a3114836SGerry Liu nl->ml_address = base; 450*a3114836SGerry Liu nl->ml_size = len; 451*a3114836SGerry Liu nl->ml_next = NULL; 452*a3114836SGerry Liu nl->ml_prev = tl; 453*a3114836SGerry Liu tl->ml_next = nl; 454*a3114836SGerry Liu } 455*a3114836SGerry Liu 456*a3114836SGerry Liu return (mlist); 457*a3114836SGerry Liu } 458