xref: /onnv-gate/usr/src/uts/sun4u/ngdr/io/dr_util.c (revision 1772:78cca3d2cc4b)
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
5*1772Sjl139090  * Common Development and Distribution License (the "License").
6*1772Sjl139090  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*1772Sjl139090  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23930Smathue  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/types.h>
290Sstevel@tonic-gate #include <sys/cmn_err.h>
300Sstevel@tonic-gate #include <sys/param.h>		/* for NULL */
310Sstevel@tonic-gate #include <sys/sbd_ioctl.h>
320Sstevel@tonic-gate #include <sys/dr_util.h>
330Sstevel@tonic-gate #include <sys/varargs.h>
340Sstevel@tonic-gate #include <sys/sysmacros.h>
350Sstevel@tonic-gate #include <sys/systm.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */
380Sstevel@tonic-gate extern sbd_etab_t sbd_etab[];
390Sstevel@tonic-gate extern int sbd_etab_len;
400Sstevel@tonic-gate 
410Sstevel@tonic-gate sbd_error_t *
420Sstevel@tonic-gate sbd_err_new(int e_code, char *fmt, va_list args)
430Sstevel@tonic-gate {
440Sstevel@tonic-gate 	sbd_error_t	*new;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate 	new = GETSTRUCT(sbd_error_t, 1);
470Sstevel@tonic-gate 	new->e_code = e_code;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate 	if (fmt)
500Sstevel@tonic-gate 		(void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args);
510Sstevel@tonic-gate 
520Sstevel@tonic-gate 	return (new);
530Sstevel@tonic-gate }
540Sstevel@tonic-gate 
550Sstevel@tonic-gate void
560Sstevel@tonic-gate sbd_err_log(sbd_error_t *ep, int ce)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate 	char		 buf[32];
590Sstevel@tonic-gate 	char		*fmt;
600Sstevel@tonic-gate 	char		*txt;
610Sstevel@tonic-gate 	int		 i;
620Sstevel@tonic-gate 	sbd_etab_t	*tp;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	if (!ep)
650Sstevel@tonic-gate 		return;
660Sstevel@tonic-gate 
670Sstevel@tonic-gate 	if (ep->e_rsc[0] == '\0')
680Sstevel@tonic-gate 		fmt = "%s";
690Sstevel@tonic-gate 	else
700Sstevel@tonic-gate 		fmt = "%s: %s";
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++)
730Sstevel@tonic-gate 		if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd)
740Sstevel@tonic-gate 			break;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	if (i < sbd_etab_len)
770Sstevel@tonic-gate 		txt = tp->t_text[ep->e_code - tp->t_base];
780Sstevel@tonic-gate 	else {
790Sstevel@tonic-gate 		snprintf(buf, sizeof (buf), "error %d", ep->e_code);
800Sstevel@tonic-gate 		txt = buf;
810Sstevel@tonic-gate 	}
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	cmn_err(ce, fmt, txt, ep->e_rsc);
840Sstevel@tonic-gate }
850Sstevel@tonic-gate 
860Sstevel@tonic-gate void
870Sstevel@tonic-gate sbd_err_clear(sbd_error_t **ep)
880Sstevel@tonic-gate {
890Sstevel@tonic-gate 	FREESTRUCT(*ep, sbd_error_t, 1);
900Sstevel@tonic-gate 	*ep = NULL;
910Sstevel@tonic-gate }
920Sstevel@tonic-gate 
930Sstevel@tonic-gate void
940Sstevel@tonic-gate sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
950Sstevel@tonic-gate {
960Sstevel@tonic-gate 	sbd_error_t	*tmp;
970Sstevel@tonic-gate 	va_list		args;
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	va_start(args, fmt);
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	tmp = sbd_err_new(e_code, fmt, args);
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	sbd_err_log(tmp, ce);
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 	if (*ep == NULL)
1060Sstevel@tonic-gate 		*ep = tmp;
1070Sstevel@tonic-gate 	else
1080Sstevel@tonic-gate 		sbd_err_clear(&tmp);
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	va_end(args);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate void
1140Sstevel@tonic-gate sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
1150Sstevel@tonic-gate {
1160Sstevel@tonic-gate 	sbd_error_t	*tmp;
1170Sstevel@tonic-gate 	va_list		args;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	va_start(args, fmt);
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	tmp = sbd_err_new(e_code, fmt, args);
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	sbd_err_log(tmp, ce);
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	*ep = tmp;
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	va_end(args);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate sbd_error_t *
1310Sstevel@tonic-gate drerr_new_v(int e_code, char *fmt, va_list args)
1320Sstevel@tonic-gate {
1330Sstevel@tonic-gate 	return (sbd_err_new(e_code, fmt, args));
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate sbd_error_t *
1370Sstevel@tonic-gate drerr_new(int log, int e_code, char *fmt, ...)
1380Sstevel@tonic-gate {
1390Sstevel@tonic-gate 	sbd_error_t	*ep;
1400Sstevel@tonic-gate 	va_list		 args;
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	va_start(args, fmt);
1430Sstevel@tonic-gate 	ep = sbd_err_new(e_code, fmt, args);
1440Sstevel@tonic-gate 	va_end(args);
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	if (log)
1470Sstevel@tonic-gate 		sbd_err_log(ep, CE_WARN);
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	return (ep);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate void
1530Sstevel@tonic-gate drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate 	sbd_error_t	*err;
1560Sstevel@tonic-gate 	va_list		 args;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	va_start(args, fmt);
1590Sstevel@tonic-gate 	err = sbd_err_new(e_code, fmt, args);
1600Sstevel@tonic-gate 	va_end(args);
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	if (log)
1630Sstevel@tonic-gate 		sbd_err_log(err, CE_WARN);
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	if (*ep == NULL)
1660Sstevel@tonic-gate 		*ep = err;
1670Sstevel@tonic-gate 	else
1680Sstevel@tonic-gate 		sbd_err_clear(&err);
1690Sstevel@tonic-gate }
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate /*
1730Sstevel@tonic-gate  * Memlist support.
1740Sstevel@tonic-gate  */
1750Sstevel@tonic-gate void
176*1772Sjl139090 dr_memlist_delete(struct memlist *mlist)
1770Sstevel@tonic-gate {
1780Sstevel@tonic-gate 	register struct memlist	*ml;
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 	for (ml = mlist; ml; ml = mlist) {
1810Sstevel@tonic-gate 		mlist = ml->next;
1820Sstevel@tonic-gate 		FREESTRUCT(ml, struct memlist, 1);
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate int
187*1772Sjl139090 dr_memlist_intersect(struct memlist *al, struct memlist *bl)
1880Sstevel@tonic-gate {
1890Sstevel@tonic-gate 	uint64_t	astart, aend, bstart, bend;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	if ((al == NULL) || (bl == NULL))
1920Sstevel@tonic-gate 		return (0);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	aend = al->address + al->size;
1950Sstevel@tonic-gate 	bstart = bl->address;
1960Sstevel@tonic-gate 	bend = bl->address + bl->size;
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	while (al && bl) {
1990Sstevel@tonic-gate 		while (al && (aend <= bstart))
2000Sstevel@tonic-gate 			if ((al = al->next) != NULL)
2010Sstevel@tonic-gate 				aend = al->address + al->size;
2020Sstevel@tonic-gate 		if (al == NULL)
2030Sstevel@tonic-gate 			return (0);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 		if ((astart = al->address) <= bstart)
2060Sstevel@tonic-gate 			return (1);
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 		while (bl && (bend <= astart))
2090Sstevel@tonic-gate 			if ((bl = bl->next) != NULL)
2100Sstevel@tonic-gate 				bend = bl->address + bl->size;
2110Sstevel@tonic-gate 		if (bl == NULL)
2120Sstevel@tonic-gate 			return (0);
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 		if ((bstart = bl->address) <= astart)
2150Sstevel@tonic-gate 			return (1);
2160Sstevel@tonic-gate 	}
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 	return (0);
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate void
222*1772Sjl139090 dr_memlist_coalesce(struct memlist *mlist)
2230Sstevel@tonic-gate {
2240Sstevel@tonic-gate 	uint64_t	end, nend;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	if ((mlist == NULL) || (mlist->next == NULL))
2270Sstevel@tonic-gate 		return;
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	while (mlist->next) {
2300Sstevel@tonic-gate 		end = mlist->address + mlist->size;
2310Sstevel@tonic-gate 		if (mlist->next->address <= end) {
2320Sstevel@tonic-gate 			struct memlist 	*nl;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 			nend = mlist->next->address + mlist->next->size;
2350Sstevel@tonic-gate 			if (nend > end)
2360Sstevel@tonic-gate 				mlist->size += (nend - end);
2370Sstevel@tonic-gate 			nl = mlist->next;
2380Sstevel@tonic-gate 			mlist->next = mlist->next->next;
2390Sstevel@tonic-gate 			if (nl) {
2400Sstevel@tonic-gate 				FREESTRUCT(nl, struct memlist, 1);
2410Sstevel@tonic-gate 			}
2420Sstevel@tonic-gate 			if (mlist->next)
2430Sstevel@tonic-gate 				mlist->next->prev = mlist;
2440Sstevel@tonic-gate 		} else {
2450Sstevel@tonic-gate 			mlist = mlist->next;
2460Sstevel@tonic-gate 		}
2470Sstevel@tonic-gate 	}
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate #ifdef DEBUG
2510Sstevel@tonic-gate void
2520Sstevel@tonic-gate memlist_dump(struct memlist *mlist)
2530Sstevel@tonic-gate {
2540Sstevel@tonic-gate 	register struct memlist *ml;
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	if (mlist == NULL)
2570Sstevel@tonic-gate 		printf("memlist> EMPTY\n");
2580Sstevel@tonic-gate 	else for (ml = mlist; ml; ml = ml->next)
259930Smathue 		printf("memlist> 0x%lx, 0x%lx\n", ml->address, ml->size);
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate #endif
262*1772Sjl139090 
263*1772Sjl139090 struct memlist *
264*1772Sjl139090 dr_memlist_dup(struct memlist *mlist)
265*1772Sjl139090 {
266*1772Sjl139090 	struct memlist *hl = NULL, *tl, **mlp;
267*1772Sjl139090 
268*1772Sjl139090 	if (mlist == NULL)
269*1772Sjl139090 		return (NULL);
270*1772Sjl139090 
271*1772Sjl139090 	mlp = &hl;
272*1772Sjl139090 	tl = *mlp;
273*1772Sjl139090 	for (; mlist; mlist = mlist->next) {
274*1772Sjl139090 		*mlp = GETSTRUCT(struct memlist, 1);
275*1772Sjl139090 		(*mlp)->address = mlist->address;
276*1772Sjl139090 		(*mlp)->size = mlist->size;
277*1772Sjl139090 		(*mlp)->prev = tl;
278*1772Sjl139090 		tl = *mlp;
279*1772Sjl139090 		mlp = &((*mlp)->next);
280*1772Sjl139090 	}
281*1772Sjl139090 	*mlp = NULL;
282*1772Sjl139090 
283*1772Sjl139090 	return (hl);
284*1772Sjl139090 }
285*1772Sjl139090 
286*1772Sjl139090 struct memlist *
287*1772Sjl139090 dr_memlist_add_span(struct memlist *mlist, uint64_t base, uint64_t len)
288*1772Sjl139090 {
289*1772Sjl139090 	struct memlist	*ml, *tl, *nl;
290*1772Sjl139090 
291*1772Sjl139090 	if (len == 0ull)
292*1772Sjl139090 		return (NULL);
293*1772Sjl139090 
294*1772Sjl139090 	if (mlist == NULL) {
295*1772Sjl139090 		mlist = GETSTRUCT(struct memlist, 1);
296*1772Sjl139090 		mlist->address = base;
297*1772Sjl139090 		mlist->size = len;
298*1772Sjl139090 		mlist->next = mlist->prev = NULL;
299*1772Sjl139090 
300*1772Sjl139090 		return (mlist);
301*1772Sjl139090 	}
302*1772Sjl139090 
303*1772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = ml->next) {
304*1772Sjl139090 		if (base < ml->address) {
305*1772Sjl139090 			if ((base + len) < ml->address) {
306*1772Sjl139090 				nl = GETSTRUCT(struct memlist, 1);
307*1772Sjl139090 				nl->address = base;
308*1772Sjl139090 				nl->size = len;
309*1772Sjl139090 				nl->next = ml;
310*1772Sjl139090 				if ((nl->prev = ml->prev) != NULL)
311*1772Sjl139090 					nl->prev->next = nl;
312*1772Sjl139090 				ml->prev = nl;
313*1772Sjl139090 				if (mlist == ml)
314*1772Sjl139090 					mlist = nl;
315*1772Sjl139090 			} else {
316*1772Sjl139090 				ml->size = MAX((base + len),
317*1772Sjl139090 					(ml->address + ml->size)) -
318*1772Sjl139090 					base;
319*1772Sjl139090 				ml->address = base;
320*1772Sjl139090 			}
321*1772Sjl139090 			break;
322*1772Sjl139090 
323*1772Sjl139090 		} else if (base <= (ml->address + ml->size)) {
324*1772Sjl139090 			ml->size = MAX((base + len),
325*1772Sjl139090 				(ml->address + ml->size)) -
326*1772Sjl139090 				MIN(ml->address, base);
327*1772Sjl139090 			ml->address = MIN(ml->address, base);
328*1772Sjl139090 			break;
329*1772Sjl139090 		}
330*1772Sjl139090 	}
331*1772Sjl139090 	if (ml == NULL) {
332*1772Sjl139090 		nl = GETSTRUCT(struct memlist, 1);
333*1772Sjl139090 		nl->address = base;
334*1772Sjl139090 		nl->size = len;
335*1772Sjl139090 		nl->next = NULL;
336*1772Sjl139090 		nl->prev = tl;
337*1772Sjl139090 		tl->next = nl;
338*1772Sjl139090 	}
339*1772Sjl139090 
340*1772Sjl139090 	dr_memlist_coalesce(mlist);
341*1772Sjl139090 
342*1772Sjl139090 	return (mlist);
343*1772Sjl139090 }
344*1772Sjl139090 
345*1772Sjl139090 struct memlist *
346*1772Sjl139090 dr_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len)
347*1772Sjl139090 {
348*1772Sjl139090 	uint64_t	end;
349*1772Sjl139090 	struct memlist	*ml, *tl, *nlp;
350*1772Sjl139090 
351*1772Sjl139090 	if (mlist == NULL)
352*1772Sjl139090 		return (NULL);
353*1772Sjl139090 
354*1772Sjl139090 	end = base + len;
355*1772Sjl139090 	if ((end <= mlist->address) || (base == end))
356*1772Sjl139090 		return (mlist);
357*1772Sjl139090 
358*1772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = nlp) {
359*1772Sjl139090 		uint64_t	mend;
360*1772Sjl139090 
361*1772Sjl139090 		nlp = ml->next;
362*1772Sjl139090 
363*1772Sjl139090 		if (end <= ml->address)
364*1772Sjl139090 			break;
365*1772Sjl139090 
366*1772Sjl139090 		mend = ml->address + ml->size;
367*1772Sjl139090 		if (base < mend) {
368*1772Sjl139090 			if (base <= ml->address) {
369*1772Sjl139090 				ml->address = end;
370*1772Sjl139090 				if (end >= mend)
371*1772Sjl139090 					ml->size = 0ull;
372*1772Sjl139090 				else
373*1772Sjl139090 					ml->size = mend - ml->address;
374*1772Sjl139090 			} else {
375*1772Sjl139090 				ml->size = base - ml->address;
376*1772Sjl139090 				if (end < mend) {
377*1772Sjl139090 					struct memlist	*nl;
378*1772Sjl139090 					/*
379*1772Sjl139090 					 * splitting an memlist entry.
380*1772Sjl139090 					 */
381*1772Sjl139090 					nl = GETSTRUCT(struct memlist, 1);
382*1772Sjl139090 					nl->address = end;
383*1772Sjl139090 					nl->size = mend - nl->address;
384*1772Sjl139090 					if ((nl->next = nlp) != NULL)
385*1772Sjl139090 						nlp->prev = nl;
386*1772Sjl139090 					nl->prev = ml;
387*1772Sjl139090 					ml->next = nl;
388*1772Sjl139090 					nlp = nl;
389*1772Sjl139090 				}
390*1772Sjl139090 			}
391*1772Sjl139090 			if (ml->size == 0ull) {
392*1772Sjl139090 				if (ml == mlist) {
393*1772Sjl139090 					if ((mlist = nlp) != NULL)
394*1772Sjl139090 						nlp->prev = NULL;
395*1772Sjl139090 					FREESTRUCT(ml, struct memlist, 1);
396*1772Sjl139090 					if (mlist == NULL)
397*1772Sjl139090 						break;
398*1772Sjl139090 					ml = nlp;
399*1772Sjl139090 				} else {
400*1772Sjl139090 					if ((tl->next = nlp) != NULL)
401*1772Sjl139090 						nlp->prev = tl;
402*1772Sjl139090 					FREESTRUCT(ml, struct memlist, 1);
403*1772Sjl139090 					ml = tl;
404*1772Sjl139090 				}
405*1772Sjl139090 			}
406*1772Sjl139090 		}
407*1772Sjl139090 	}
408*1772Sjl139090 
409*1772Sjl139090 	return (mlist);
410*1772Sjl139090 }
411*1772Sjl139090 
412*1772Sjl139090 /*
413*1772Sjl139090  * add span without merging
414*1772Sjl139090  */
415*1772Sjl139090 struct memlist *
416*1772Sjl139090 dr_memlist_cat_span(struct memlist *mlist, uint64_t base, uint64_t len)
417*1772Sjl139090 {
418*1772Sjl139090 	struct memlist	*ml, *tl, *nl;
419*1772Sjl139090 
420*1772Sjl139090 	if (len == 0ull)
421*1772Sjl139090 		return (NULL);
422*1772Sjl139090 
423*1772Sjl139090 	if (mlist == NULL) {
424*1772Sjl139090 		mlist = GETSTRUCT(struct memlist, 1);
425*1772Sjl139090 		mlist->address = base;
426*1772Sjl139090 		mlist->size = len;
427*1772Sjl139090 		mlist->next = mlist->prev = NULL;
428*1772Sjl139090 
429*1772Sjl139090 		return (mlist);
430*1772Sjl139090 	}
431*1772Sjl139090 
432*1772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = ml->next) {
433*1772Sjl139090 		if (base < ml->address) {
434*1772Sjl139090 			nl = GETSTRUCT(struct memlist, 1);
435*1772Sjl139090 			nl->address = base;
436*1772Sjl139090 			nl->size = len;
437*1772Sjl139090 			nl->next = ml;
438*1772Sjl139090 			if ((nl->prev = ml->prev) != NULL)
439*1772Sjl139090 				nl->prev->next = nl;
440*1772Sjl139090 			ml->prev = nl;
441*1772Sjl139090 			if (mlist == ml)
442*1772Sjl139090 				mlist = nl;
443*1772Sjl139090 			break;
444*1772Sjl139090 		}
445*1772Sjl139090 	}
446*1772Sjl139090 
447*1772Sjl139090 	if (ml == NULL) {
448*1772Sjl139090 		nl = GETSTRUCT(struct memlist, 1);
449*1772Sjl139090 		nl->address = base;
450*1772Sjl139090 		nl->size = len;
451*1772Sjl139090 		nl->next = NULL;
452*1772Sjl139090 		nl->prev = tl;
453*1772Sjl139090 		tl->next = nl;
454*1772Sjl139090 	}
455*1772Sjl139090 
456*1772Sjl139090 	return (mlist);
457*1772Sjl139090 }
458