xref: /onnv-gate/usr/src/uts/sun4u/ngdr/io/dr_util.c (revision 11474:857f9db4ef05)
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
51772Sjl139090  * Common Development and Distribution License (the "License").
61772Sjl139090  * 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  */
2111311SSurya.Prakki@Sun.COM 
220Sstevel@tonic-gate /*
23*11474SJonathan.Adams@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24930Smathue  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include <sys/types.h>
280Sstevel@tonic-gate #include <sys/cmn_err.h>
290Sstevel@tonic-gate #include <sys/param.h>		/* for NULL */
300Sstevel@tonic-gate #include <sys/sbd_ioctl.h>
310Sstevel@tonic-gate #include <sys/dr_util.h>
320Sstevel@tonic-gate #include <sys/varargs.h>
330Sstevel@tonic-gate #include <sys/sysmacros.h>
340Sstevel@tonic-gate #include <sys/systm.h>
350Sstevel@tonic-gate 
360Sstevel@tonic-gate /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */
370Sstevel@tonic-gate extern sbd_etab_t sbd_etab[];
380Sstevel@tonic-gate extern int sbd_etab_len;
390Sstevel@tonic-gate 
400Sstevel@tonic-gate sbd_error_t *
sbd_err_new(int e_code,char * fmt,va_list args)410Sstevel@tonic-gate sbd_err_new(int e_code, char *fmt, va_list args)
420Sstevel@tonic-gate {
430Sstevel@tonic-gate 	sbd_error_t	*new;
440Sstevel@tonic-gate 
450Sstevel@tonic-gate 	new = GETSTRUCT(sbd_error_t, 1);
460Sstevel@tonic-gate 	new->e_code = e_code;
470Sstevel@tonic-gate 
480Sstevel@tonic-gate 	if (fmt)
490Sstevel@tonic-gate 		(void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args);
500Sstevel@tonic-gate 
510Sstevel@tonic-gate 	return (new);
520Sstevel@tonic-gate }
530Sstevel@tonic-gate 
540Sstevel@tonic-gate void
sbd_err_log(sbd_error_t * ep,int ce)550Sstevel@tonic-gate sbd_err_log(sbd_error_t *ep, int ce)
560Sstevel@tonic-gate {
570Sstevel@tonic-gate 	char		 buf[32];
580Sstevel@tonic-gate 	char		*fmt;
590Sstevel@tonic-gate 	char		*txt;
600Sstevel@tonic-gate 	int		 i;
610Sstevel@tonic-gate 	sbd_etab_t	*tp;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	if (!ep)
640Sstevel@tonic-gate 		return;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	if (ep->e_rsc[0] == '\0')
670Sstevel@tonic-gate 		fmt = "%s";
680Sstevel@tonic-gate 	else
690Sstevel@tonic-gate 		fmt = "%s: %s";
700Sstevel@tonic-gate 
710Sstevel@tonic-gate 	for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++)
720Sstevel@tonic-gate 		if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd)
730Sstevel@tonic-gate 			break;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	if (i < sbd_etab_len)
760Sstevel@tonic-gate 		txt = tp->t_text[ep->e_code - tp->t_base];
770Sstevel@tonic-gate 	else {
7811311SSurya.Prakki@Sun.COM 		(void) snprintf(buf, sizeof (buf), "error %d", ep->e_code);
790Sstevel@tonic-gate 		txt = buf;
800Sstevel@tonic-gate 	}
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	cmn_err(ce, fmt, txt, ep->e_rsc);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate 
850Sstevel@tonic-gate void
sbd_err_clear(sbd_error_t ** ep)860Sstevel@tonic-gate sbd_err_clear(sbd_error_t **ep)
870Sstevel@tonic-gate {
880Sstevel@tonic-gate 	FREESTRUCT(*ep, sbd_error_t, 1);
890Sstevel@tonic-gate 	*ep = NULL;
900Sstevel@tonic-gate }
910Sstevel@tonic-gate 
920Sstevel@tonic-gate void
sbd_err_set_c(sbd_error_t ** ep,int ce,int e_code,char * fmt,...)930Sstevel@tonic-gate sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	sbd_error_t	*tmp;
960Sstevel@tonic-gate 	va_list		args;
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	va_start(args, fmt);
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	tmp = sbd_err_new(e_code, fmt, args);
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	sbd_err_log(tmp, ce);
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	if (*ep == NULL)
1050Sstevel@tonic-gate 		*ep = tmp;
1060Sstevel@tonic-gate 	else
1070Sstevel@tonic-gate 		sbd_err_clear(&tmp);
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	va_end(args);
1100Sstevel@tonic-gate }
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate void
sbd_err_set(sbd_error_t ** ep,int ce,int e_code,char * fmt,...)1130Sstevel@tonic-gate sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate 	sbd_error_t	*tmp;
1160Sstevel@tonic-gate 	va_list		args;
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 	va_start(args, fmt);
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	tmp = sbd_err_new(e_code, fmt, args);
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	sbd_err_log(tmp, ce);
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	*ep = tmp;
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	va_end(args);
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate sbd_error_t *
drerr_new_v(int e_code,char * fmt,va_list args)1300Sstevel@tonic-gate drerr_new_v(int e_code, char *fmt, va_list args)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate 	return (sbd_err_new(e_code, fmt, args));
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate sbd_error_t *
drerr_new(int log,int e_code,char * fmt,...)1360Sstevel@tonic-gate drerr_new(int log, int e_code, char *fmt, ...)
1370Sstevel@tonic-gate {
1380Sstevel@tonic-gate 	sbd_error_t	*ep;
1390Sstevel@tonic-gate 	va_list		 args;
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	va_start(args, fmt);
1420Sstevel@tonic-gate 	ep = sbd_err_new(e_code, fmt, args);
1430Sstevel@tonic-gate 	va_end(args);
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	if (log)
1460Sstevel@tonic-gate 		sbd_err_log(ep, CE_WARN);
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	return (ep);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate void
drerr_set_c(int log,sbd_error_t ** ep,int e_code,char * fmt,...)1520Sstevel@tonic-gate drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...)
1530Sstevel@tonic-gate {
1540Sstevel@tonic-gate 	sbd_error_t	*err;
1550Sstevel@tonic-gate 	va_list		 args;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	va_start(args, fmt);
1580Sstevel@tonic-gate 	err = sbd_err_new(e_code, fmt, args);
1590Sstevel@tonic-gate 	va_end(args);
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	if (log)
1620Sstevel@tonic-gate 		sbd_err_log(err, CE_WARN);
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	if (*ep == NULL)
1650Sstevel@tonic-gate 		*ep = err;
1660Sstevel@tonic-gate 	else
1670Sstevel@tonic-gate 		sbd_err_clear(&err);
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate /*
1720Sstevel@tonic-gate  * Memlist support.
1730Sstevel@tonic-gate  */
1740Sstevel@tonic-gate void
dr_memlist_delete(struct memlist * mlist)1751772Sjl139090 dr_memlist_delete(struct memlist *mlist)
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate 	register struct memlist	*ml;
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	for (ml = mlist; ml; ml = mlist) {
180*11474SJonathan.Adams@Sun.COM 		mlist = ml->ml_next;
1810Sstevel@tonic-gate 		FREESTRUCT(ml, struct memlist, 1);
1820Sstevel@tonic-gate 	}
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate int
dr_memlist_intersect(struct memlist * al,struct memlist * bl)1861772Sjl139090 dr_memlist_intersect(struct memlist *al, struct memlist *bl)
1870Sstevel@tonic-gate {
1880Sstevel@tonic-gate 	uint64_t	astart, aend, bstart, bend;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 	if ((al == NULL) || (bl == NULL))
1910Sstevel@tonic-gate 		return (0);
1920Sstevel@tonic-gate 
193*11474SJonathan.Adams@Sun.COM 	aend = al->ml_address + al->ml_size;
194*11474SJonathan.Adams@Sun.COM 	bstart = bl->ml_address;
195*11474SJonathan.Adams@Sun.COM 	bend = bl->ml_address + bl->ml_size;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	while (al && bl) {
1980Sstevel@tonic-gate 		while (al && (aend <= bstart))
199*11474SJonathan.Adams@Sun.COM 			if ((al = al->ml_next) != NULL)
200*11474SJonathan.Adams@Sun.COM 				aend = al->ml_address + al->ml_size;
2010Sstevel@tonic-gate 		if (al == NULL)
2020Sstevel@tonic-gate 			return (0);
2030Sstevel@tonic-gate 
204*11474SJonathan.Adams@Sun.COM 		if ((astart = al->ml_address) <= bstart)
2050Sstevel@tonic-gate 			return (1);
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 		while (bl && (bend <= astart))
208*11474SJonathan.Adams@Sun.COM 			if ((bl = bl->ml_next) != NULL)
209*11474SJonathan.Adams@Sun.COM 				bend = bl->ml_address + bl->ml_size;
2100Sstevel@tonic-gate 		if (bl == NULL)
2110Sstevel@tonic-gate 			return (0);
2120Sstevel@tonic-gate 
213*11474SJonathan.Adams@Sun.COM 		if ((bstart = bl->ml_address) <= astart)
2140Sstevel@tonic-gate 			return (1);
2150Sstevel@tonic-gate 	}
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	return (0);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate void
dr_memlist_coalesce(struct memlist * mlist)2211772Sjl139090 dr_memlist_coalesce(struct memlist *mlist)
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate 	uint64_t	end, nend;
2240Sstevel@tonic-gate 
225*11474SJonathan.Adams@Sun.COM 	if ((mlist == NULL) || (mlist->ml_next == NULL))
2260Sstevel@tonic-gate 		return;
2270Sstevel@tonic-gate 
228*11474SJonathan.Adams@Sun.COM 	while (mlist->ml_next) {
229*11474SJonathan.Adams@Sun.COM 		end = mlist->ml_address + mlist->ml_size;
230*11474SJonathan.Adams@Sun.COM 		if (mlist->ml_next->ml_address <= end) {
2310Sstevel@tonic-gate 			struct memlist 	*nl;
2320Sstevel@tonic-gate 
233*11474SJonathan.Adams@Sun.COM 			nend = mlist->ml_next->ml_address +
234*11474SJonathan.Adams@Sun.COM 			    mlist->ml_next->ml_size;
2350Sstevel@tonic-gate 			if (nend > end)
236*11474SJonathan.Adams@Sun.COM 				mlist->ml_size += (nend - end);
237*11474SJonathan.Adams@Sun.COM 			nl = mlist->ml_next;
238*11474SJonathan.Adams@Sun.COM 			mlist->ml_next = mlist->ml_next->ml_next;
2390Sstevel@tonic-gate 			if (nl) {
2400Sstevel@tonic-gate 				FREESTRUCT(nl, struct memlist, 1);
2410Sstevel@tonic-gate 			}
242*11474SJonathan.Adams@Sun.COM 			if (mlist->ml_next)
243*11474SJonathan.Adams@Sun.COM 				mlist->ml_next->ml_prev = mlist;
2440Sstevel@tonic-gate 		} else {
245*11474SJonathan.Adams@Sun.COM 			mlist = mlist->ml_next;
2460Sstevel@tonic-gate 		}
2470Sstevel@tonic-gate 	}
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate #ifdef DEBUG
2510Sstevel@tonic-gate void
memlist_dump(struct memlist * mlist)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");
258*11474SJonathan.Adams@Sun.COM 	else for (ml = mlist; ml; ml = ml->ml_next)
259*11474SJonathan.Adams@Sun.COM 		printf("memlist> 0x%lx, 0x%lx\n", ml->ml_address, ml->ml_size);
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate #endif
2621772Sjl139090 
2631772Sjl139090 struct memlist *
dr_memlist_dup(struct memlist * mlist)2641772Sjl139090 dr_memlist_dup(struct memlist *mlist)
2651772Sjl139090 {
2661772Sjl139090 	struct memlist *hl = NULL, *tl, **mlp;
2671772Sjl139090 
2681772Sjl139090 	if (mlist == NULL)
2691772Sjl139090 		return (NULL);
2701772Sjl139090 
2711772Sjl139090 	mlp = &hl;
2721772Sjl139090 	tl = *mlp;
273*11474SJonathan.Adams@Sun.COM 	for (; mlist; mlist = mlist->ml_next) {
2741772Sjl139090 		*mlp = GETSTRUCT(struct memlist, 1);
275*11474SJonathan.Adams@Sun.COM 		(*mlp)->ml_address = mlist->ml_address;
276*11474SJonathan.Adams@Sun.COM 		(*mlp)->ml_size = mlist->ml_size;
277*11474SJonathan.Adams@Sun.COM 		(*mlp)->ml_prev = tl;
2781772Sjl139090 		tl = *mlp;
279*11474SJonathan.Adams@Sun.COM 		mlp = &((*mlp)->ml_next);
2801772Sjl139090 	}
2811772Sjl139090 	*mlp = NULL;
2821772Sjl139090 
2831772Sjl139090 	return (hl);
2841772Sjl139090 }
2851772Sjl139090 
2861772Sjl139090 struct memlist *
dr_memlist_add_span(struct memlist * mlist,uint64_t base,uint64_t len)2871772Sjl139090 dr_memlist_add_span(struct memlist *mlist, uint64_t base, uint64_t len)
2881772Sjl139090 {
2891772Sjl139090 	struct memlist	*ml, *tl, *nl;
2901772Sjl139090 
2911772Sjl139090 	if (len == 0ull)
2921772Sjl139090 		return (NULL);
2931772Sjl139090 
2941772Sjl139090 	if (mlist == NULL) {
2951772Sjl139090 		mlist = GETSTRUCT(struct memlist, 1);
296*11474SJonathan.Adams@Sun.COM 		mlist->ml_address = base;
297*11474SJonathan.Adams@Sun.COM 		mlist->ml_size = len;
298*11474SJonathan.Adams@Sun.COM 		mlist->ml_next = mlist->ml_prev = NULL;
2991772Sjl139090 
3001772Sjl139090 		return (mlist);
3011772Sjl139090 	}
3021772Sjl139090 
303*11474SJonathan.Adams@Sun.COM 	for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) {
304*11474SJonathan.Adams@Sun.COM 		if (base < ml->ml_address) {
305*11474SJonathan.Adams@Sun.COM 			if ((base + len) < ml->ml_address) {
3061772Sjl139090 				nl = GETSTRUCT(struct memlist, 1);
307*11474SJonathan.Adams@Sun.COM 				nl->ml_address = base;
308*11474SJonathan.Adams@Sun.COM 				nl->ml_size = len;
309*11474SJonathan.Adams@Sun.COM 				nl->ml_next = ml;
310*11474SJonathan.Adams@Sun.COM 				if ((nl->ml_prev = ml->ml_prev) != NULL)
311*11474SJonathan.Adams@Sun.COM 					nl->ml_prev->ml_next = nl;
312*11474SJonathan.Adams@Sun.COM 				ml->ml_prev = nl;
3131772Sjl139090 				if (mlist == ml)
3141772Sjl139090 					mlist = nl;
3151772Sjl139090 			} else {
316*11474SJonathan.Adams@Sun.COM 				ml->ml_size = MAX((base + len),
317*11474SJonathan.Adams@Sun.COM 				    (ml->ml_address + ml->ml_size)) - base;
318*11474SJonathan.Adams@Sun.COM 				ml->ml_address = base;
3191772Sjl139090 			}
3201772Sjl139090 			break;
3211772Sjl139090 
322*11474SJonathan.Adams@Sun.COM 		} else if (base <= (ml->ml_address + ml->ml_size)) {
323*11474SJonathan.Adams@Sun.COM 			ml->ml_size = MAX((base + len),
324*11474SJonathan.Adams@Sun.COM 			    (ml->ml_address + ml->ml_size)) -
325*11474SJonathan.Adams@Sun.COM 			    MIN(ml->ml_address, base);
326*11474SJonathan.Adams@Sun.COM 			ml->ml_address = MIN(ml->ml_address, base);
3271772Sjl139090 			break;
3281772Sjl139090 		}
3291772Sjl139090 	}
3301772Sjl139090 	if (ml == NULL) {
3311772Sjl139090 		nl = GETSTRUCT(struct memlist, 1);
332*11474SJonathan.Adams@Sun.COM 		nl->ml_address = base;
333*11474SJonathan.Adams@Sun.COM 		nl->ml_size = len;
334*11474SJonathan.Adams@Sun.COM 		nl->ml_next = NULL;
335*11474SJonathan.Adams@Sun.COM 		nl->ml_prev = tl;
336*11474SJonathan.Adams@Sun.COM 		tl->ml_next = nl;
3371772Sjl139090 	}
3381772Sjl139090 
3391772Sjl139090 	dr_memlist_coalesce(mlist);
3401772Sjl139090 
3411772Sjl139090 	return (mlist);
3421772Sjl139090 }
3431772Sjl139090 
3441772Sjl139090 struct memlist *
dr_memlist_del_span(struct memlist * mlist,uint64_t base,uint64_t len)3451772Sjl139090 dr_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len)
3461772Sjl139090 {
3471772Sjl139090 	uint64_t	end;
3481772Sjl139090 	struct memlist	*ml, *tl, *nlp;
3491772Sjl139090 
3501772Sjl139090 	if (mlist == NULL)
3511772Sjl139090 		return (NULL);
3521772Sjl139090 
3531772Sjl139090 	end = base + len;
354*11474SJonathan.Adams@Sun.COM 	if ((end <= mlist->ml_address) || (base == end))
3551772Sjl139090 		return (mlist);
3561772Sjl139090 
3571772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = nlp) {
3581772Sjl139090 		uint64_t	mend;
3591772Sjl139090 
360*11474SJonathan.Adams@Sun.COM 		nlp = ml->ml_next;
3611772Sjl139090 
362*11474SJonathan.Adams@Sun.COM 		if (end <= ml->ml_address)
3631772Sjl139090 			break;
3641772Sjl139090 
365*11474SJonathan.Adams@Sun.COM 		mend = ml->ml_address + ml->ml_size;
3661772Sjl139090 		if (base < mend) {
367*11474SJonathan.Adams@Sun.COM 			if (base <= ml->ml_address) {
368*11474SJonathan.Adams@Sun.COM 				ml->ml_address = end;
3691772Sjl139090 				if (end >= mend)
370*11474SJonathan.Adams@Sun.COM 					ml->ml_size = 0ull;
3711772Sjl139090 				else
372*11474SJonathan.Adams@Sun.COM 					ml->ml_size = mend - ml->ml_address;
3731772Sjl139090 			} else {
374*11474SJonathan.Adams@Sun.COM 				ml->ml_size = base - ml->ml_address;
3751772Sjl139090 				if (end < mend) {
3761772Sjl139090 					struct memlist	*nl;
3771772Sjl139090 					/*
3781772Sjl139090 					 * splitting an memlist entry.
3791772Sjl139090 					 */
3801772Sjl139090 					nl = GETSTRUCT(struct memlist, 1);
381*11474SJonathan.Adams@Sun.COM 					nl->ml_address = end;
382*11474SJonathan.Adams@Sun.COM 					nl->ml_size = mend - nl->ml_address;
383*11474SJonathan.Adams@Sun.COM 					if ((nl->ml_next = nlp) != NULL)
384*11474SJonathan.Adams@Sun.COM 						nlp->ml_prev = nl;
385*11474SJonathan.Adams@Sun.COM 					nl->ml_prev = ml;
386*11474SJonathan.Adams@Sun.COM 					ml->ml_next = nl;
3871772Sjl139090 					nlp = nl;
3881772Sjl139090 				}
3891772Sjl139090 			}
390*11474SJonathan.Adams@Sun.COM 			if (ml->ml_size == 0ull) {
3911772Sjl139090 				if (ml == mlist) {
3921772Sjl139090 					if ((mlist = nlp) != NULL)
393*11474SJonathan.Adams@Sun.COM 						nlp->ml_prev = NULL;
3941772Sjl139090 					FREESTRUCT(ml, struct memlist, 1);
3951772Sjl139090 					if (mlist == NULL)
3961772Sjl139090 						break;
3971772Sjl139090 					ml = nlp;
3981772Sjl139090 				} else {
399*11474SJonathan.Adams@Sun.COM 					if ((tl->ml_next = nlp) != NULL)
400*11474SJonathan.Adams@Sun.COM 						nlp->ml_prev = tl;
4011772Sjl139090 					FREESTRUCT(ml, struct memlist, 1);
4021772Sjl139090 					ml = tl;
4031772Sjl139090 				}
4041772Sjl139090 			}
4051772Sjl139090 		}
4061772Sjl139090 	}
4071772Sjl139090 
4081772Sjl139090 	return (mlist);
4091772Sjl139090 }
4101772Sjl139090 
4111772Sjl139090 /*
4121772Sjl139090  * add span without merging
4131772Sjl139090  */
4141772Sjl139090 struct memlist *
dr_memlist_cat_span(struct memlist * mlist,uint64_t base,uint64_t len)4151772Sjl139090 dr_memlist_cat_span(struct memlist *mlist, uint64_t base, uint64_t len)
4161772Sjl139090 {
4171772Sjl139090 	struct memlist	*ml, *tl, *nl;
4181772Sjl139090 
4191772Sjl139090 	if (len == 0ull)
4201772Sjl139090 		return (NULL);
4211772Sjl139090 
4221772Sjl139090 	if (mlist == NULL) {
4231772Sjl139090 		mlist = GETSTRUCT(struct memlist, 1);
424*11474SJonathan.Adams@Sun.COM 		mlist->ml_address = base;
425*11474SJonathan.Adams@Sun.COM 		mlist->ml_size = len;
426*11474SJonathan.Adams@Sun.COM 		mlist->ml_next = mlist->ml_prev = NULL;
4271772Sjl139090 
4281772Sjl139090 		return (mlist);
4291772Sjl139090 	}
4301772Sjl139090 
431*11474SJonathan.Adams@Sun.COM 	for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) {
432*11474SJonathan.Adams@Sun.COM 		if (base < ml->ml_address) {
4331772Sjl139090 			nl = GETSTRUCT(struct memlist, 1);
434*11474SJonathan.Adams@Sun.COM 			nl->ml_address = base;
435*11474SJonathan.Adams@Sun.COM 			nl->ml_size = len;
436*11474SJonathan.Adams@Sun.COM 			nl->ml_next = ml;
437*11474SJonathan.Adams@Sun.COM 			if ((nl->ml_prev = ml->ml_prev) != NULL)
438*11474SJonathan.Adams@Sun.COM 				nl->ml_prev->ml_next = nl;
439*11474SJonathan.Adams@Sun.COM 			ml->ml_prev = nl;
4401772Sjl139090 			if (mlist == ml)
4411772Sjl139090 				mlist = nl;
4421772Sjl139090 			break;
4431772Sjl139090 		}
4441772Sjl139090 	}
4451772Sjl139090 
4461772Sjl139090 	if (ml == NULL) {
4471772Sjl139090 		nl = GETSTRUCT(struct memlist, 1);
448*11474SJonathan.Adams@Sun.COM 		nl->ml_address = base;
449*11474SJonathan.Adams@Sun.COM 		nl->ml_size = len;
450*11474SJonathan.Adams@Sun.COM 		nl->ml_next = NULL;
451*11474SJonathan.Adams@Sun.COM 		nl->ml_prev = tl;
452*11474SJonathan.Adams@Sun.COM 		tl->ml_next = nl;
4531772Sjl139090 	}
4541772Sjl139090 
4551772Sjl139090 	return (mlist);
4561772Sjl139090 }
457