xref: /onnv-gate/usr/src/uts/sun4u/ngdr/io/dr_util.c (revision 11311:639e7bc0b42f)
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  */
21*11311SSurya.Prakki@Sun.COM 
220Sstevel@tonic-gate /*
23*11311SSurya.Prakki@Sun.COM  * Copyright 2009 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 *
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
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 {
78*11311SSurya.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
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
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
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 *
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 *
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
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
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) {
1800Sstevel@tonic-gate 		mlist = ml->next;
1810Sstevel@tonic-gate 		FREESTRUCT(ml, struct memlist, 1);
1820Sstevel@tonic-gate 	}
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate int
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 
1930Sstevel@tonic-gate 	aend = al->address + al->size;
1940Sstevel@tonic-gate 	bstart = bl->address;
1950Sstevel@tonic-gate 	bend = bl->address + bl->size;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	while (al && bl) {
1980Sstevel@tonic-gate 		while (al && (aend <= bstart))
1990Sstevel@tonic-gate 			if ((al = al->next) != NULL)
2000Sstevel@tonic-gate 				aend = al->address + al->size;
2010Sstevel@tonic-gate 		if (al == NULL)
2020Sstevel@tonic-gate 			return (0);
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 		if ((astart = al->address) <= bstart)
2050Sstevel@tonic-gate 			return (1);
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 		while (bl && (bend <= astart))
2080Sstevel@tonic-gate 			if ((bl = bl->next) != NULL)
2090Sstevel@tonic-gate 				bend = bl->address + bl->size;
2100Sstevel@tonic-gate 		if (bl == NULL)
2110Sstevel@tonic-gate 			return (0);
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 		if ((bstart = bl->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
2211772Sjl139090 dr_memlist_coalesce(struct memlist *mlist)
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate 	uint64_t	end, nend;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	if ((mlist == NULL) || (mlist->next == NULL))
2260Sstevel@tonic-gate 		return;
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	while (mlist->next) {
2290Sstevel@tonic-gate 		end = mlist->address + mlist->size;
2300Sstevel@tonic-gate 		if (mlist->next->address <= end) {
2310Sstevel@tonic-gate 			struct memlist 	*nl;
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 			nend = mlist->next->address + mlist->next->size;
2340Sstevel@tonic-gate 			if (nend > end)
2350Sstevel@tonic-gate 				mlist->size += (nend - end);
2360Sstevel@tonic-gate 			nl = mlist->next;
2370Sstevel@tonic-gate 			mlist->next = mlist->next->next;
2380Sstevel@tonic-gate 			if (nl) {
2390Sstevel@tonic-gate 				FREESTRUCT(nl, struct memlist, 1);
2400Sstevel@tonic-gate 			}
2410Sstevel@tonic-gate 			if (mlist->next)
2420Sstevel@tonic-gate 				mlist->next->prev = mlist;
2430Sstevel@tonic-gate 		} else {
2440Sstevel@tonic-gate 			mlist = mlist->next;
2450Sstevel@tonic-gate 		}
2460Sstevel@tonic-gate 	}
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate #ifdef DEBUG
2500Sstevel@tonic-gate void
2510Sstevel@tonic-gate memlist_dump(struct memlist *mlist)
2520Sstevel@tonic-gate {
2530Sstevel@tonic-gate 	register struct memlist *ml;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 	if (mlist == NULL)
2560Sstevel@tonic-gate 		printf("memlist> EMPTY\n");
2570Sstevel@tonic-gate 	else for (ml = mlist; ml; ml = ml->next)
258930Smathue 		printf("memlist> 0x%lx, 0x%lx\n", ml->address, ml->size);
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate #endif
2611772Sjl139090 
2621772Sjl139090 struct memlist *
2631772Sjl139090 dr_memlist_dup(struct memlist *mlist)
2641772Sjl139090 {
2651772Sjl139090 	struct memlist *hl = NULL, *tl, **mlp;
2661772Sjl139090 
2671772Sjl139090 	if (mlist == NULL)
2681772Sjl139090 		return (NULL);
2691772Sjl139090 
2701772Sjl139090 	mlp = &hl;
2711772Sjl139090 	tl = *mlp;
2721772Sjl139090 	for (; mlist; mlist = mlist->next) {
2731772Sjl139090 		*mlp = GETSTRUCT(struct memlist, 1);
2741772Sjl139090 		(*mlp)->address = mlist->address;
2751772Sjl139090 		(*mlp)->size = mlist->size;
2761772Sjl139090 		(*mlp)->prev = tl;
2771772Sjl139090 		tl = *mlp;
2781772Sjl139090 		mlp = &((*mlp)->next);
2791772Sjl139090 	}
2801772Sjl139090 	*mlp = NULL;
2811772Sjl139090 
2821772Sjl139090 	return (hl);
2831772Sjl139090 }
2841772Sjl139090 
2851772Sjl139090 struct memlist *
2861772Sjl139090 dr_memlist_add_span(struct memlist *mlist, uint64_t base, uint64_t len)
2871772Sjl139090 {
2881772Sjl139090 	struct memlist	*ml, *tl, *nl;
2891772Sjl139090 
2901772Sjl139090 	if (len == 0ull)
2911772Sjl139090 		return (NULL);
2921772Sjl139090 
2931772Sjl139090 	if (mlist == NULL) {
2941772Sjl139090 		mlist = GETSTRUCT(struct memlist, 1);
2951772Sjl139090 		mlist->address = base;
2961772Sjl139090 		mlist->size = len;
2971772Sjl139090 		mlist->next = mlist->prev = NULL;
2981772Sjl139090 
2991772Sjl139090 		return (mlist);
3001772Sjl139090 	}
3011772Sjl139090 
3021772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = ml->next) {
3031772Sjl139090 		if (base < ml->address) {
3041772Sjl139090 			if ((base + len) < ml->address) {
3051772Sjl139090 				nl = GETSTRUCT(struct memlist, 1);
3061772Sjl139090 				nl->address = base;
3071772Sjl139090 				nl->size = len;
3081772Sjl139090 				nl->next = ml;
3091772Sjl139090 				if ((nl->prev = ml->prev) != NULL)
3101772Sjl139090 					nl->prev->next = nl;
3111772Sjl139090 				ml->prev = nl;
3121772Sjl139090 				if (mlist == ml)
3131772Sjl139090 					mlist = nl;
3141772Sjl139090 			} else {
3151772Sjl139090 				ml->size = MAX((base + len),
316*11311SSurya.Prakki@Sun.COM 				    (ml->address + ml->size)) - base;
3171772Sjl139090 				ml->address = base;
3181772Sjl139090 			}
3191772Sjl139090 			break;
3201772Sjl139090 
3211772Sjl139090 		} else if (base <= (ml->address + ml->size)) {
3221772Sjl139090 			ml->size = MAX((base + len),
323*11311SSurya.Prakki@Sun.COM 			    (ml->address + ml->size)) -
324*11311SSurya.Prakki@Sun.COM 			    MIN(ml->address, base);
3251772Sjl139090 			ml->address = MIN(ml->address, base);
3261772Sjl139090 			break;
3271772Sjl139090 		}
3281772Sjl139090 	}
3291772Sjl139090 	if (ml == NULL) {
3301772Sjl139090 		nl = GETSTRUCT(struct memlist, 1);
3311772Sjl139090 		nl->address = base;
3321772Sjl139090 		nl->size = len;
3331772Sjl139090 		nl->next = NULL;
3341772Sjl139090 		nl->prev = tl;
3351772Sjl139090 		tl->next = nl;
3361772Sjl139090 	}
3371772Sjl139090 
3381772Sjl139090 	dr_memlist_coalesce(mlist);
3391772Sjl139090 
3401772Sjl139090 	return (mlist);
3411772Sjl139090 }
3421772Sjl139090 
3431772Sjl139090 struct memlist *
3441772Sjl139090 dr_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len)
3451772Sjl139090 {
3461772Sjl139090 	uint64_t	end;
3471772Sjl139090 	struct memlist	*ml, *tl, *nlp;
3481772Sjl139090 
3491772Sjl139090 	if (mlist == NULL)
3501772Sjl139090 		return (NULL);
3511772Sjl139090 
3521772Sjl139090 	end = base + len;
3531772Sjl139090 	if ((end <= mlist->address) || (base == end))
3541772Sjl139090 		return (mlist);
3551772Sjl139090 
3561772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = nlp) {
3571772Sjl139090 		uint64_t	mend;
3581772Sjl139090 
3591772Sjl139090 		nlp = ml->next;
3601772Sjl139090 
3611772Sjl139090 		if (end <= ml->address)
3621772Sjl139090 			break;
3631772Sjl139090 
3641772Sjl139090 		mend = ml->address + ml->size;
3651772Sjl139090 		if (base < mend) {
3661772Sjl139090 			if (base <= ml->address) {
3671772Sjl139090 				ml->address = end;
3681772Sjl139090 				if (end >= mend)
3691772Sjl139090 					ml->size = 0ull;
3701772Sjl139090 				else
3711772Sjl139090 					ml->size = mend - ml->address;
3721772Sjl139090 			} else {
3731772Sjl139090 				ml->size = base - ml->address;
3741772Sjl139090 				if (end < mend) {
3751772Sjl139090 					struct memlist	*nl;
3761772Sjl139090 					/*
3771772Sjl139090 					 * splitting an memlist entry.
3781772Sjl139090 					 */
3791772Sjl139090 					nl = GETSTRUCT(struct memlist, 1);
3801772Sjl139090 					nl->address = end;
3811772Sjl139090 					nl->size = mend - nl->address;
3821772Sjl139090 					if ((nl->next = nlp) != NULL)
3831772Sjl139090 						nlp->prev = nl;
3841772Sjl139090 					nl->prev = ml;
3851772Sjl139090 					ml->next = nl;
3861772Sjl139090 					nlp = nl;
3871772Sjl139090 				}
3881772Sjl139090 			}
3891772Sjl139090 			if (ml->size == 0ull) {
3901772Sjl139090 				if (ml == mlist) {
3911772Sjl139090 					if ((mlist = nlp) != NULL)
3921772Sjl139090 						nlp->prev = NULL;
3931772Sjl139090 					FREESTRUCT(ml, struct memlist, 1);
3941772Sjl139090 					if (mlist == NULL)
3951772Sjl139090 						break;
3961772Sjl139090 					ml = nlp;
3971772Sjl139090 				} else {
3981772Sjl139090 					if ((tl->next = nlp) != NULL)
3991772Sjl139090 						nlp->prev = tl;
4001772Sjl139090 					FREESTRUCT(ml, struct memlist, 1);
4011772Sjl139090 					ml = tl;
4021772Sjl139090 				}
4031772Sjl139090 			}
4041772Sjl139090 		}
4051772Sjl139090 	}
4061772Sjl139090 
4071772Sjl139090 	return (mlist);
4081772Sjl139090 }
4091772Sjl139090 
4101772Sjl139090 /*
4111772Sjl139090  * add span without merging
4121772Sjl139090  */
4131772Sjl139090 struct memlist *
4141772Sjl139090 dr_memlist_cat_span(struct memlist *mlist, uint64_t base, uint64_t len)
4151772Sjl139090 {
4161772Sjl139090 	struct memlist	*ml, *tl, *nl;
4171772Sjl139090 
4181772Sjl139090 	if (len == 0ull)
4191772Sjl139090 		return (NULL);
4201772Sjl139090 
4211772Sjl139090 	if (mlist == NULL) {
4221772Sjl139090 		mlist = GETSTRUCT(struct memlist, 1);
4231772Sjl139090 		mlist->address = base;
4241772Sjl139090 		mlist->size = len;
4251772Sjl139090 		mlist->next = mlist->prev = NULL;
4261772Sjl139090 
4271772Sjl139090 		return (mlist);
4281772Sjl139090 	}
4291772Sjl139090 
4301772Sjl139090 	for (tl = ml = mlist; ml; tl = ml, ml = ml->next) {
4311772Sjl139090 		if (base < ml->address) {
4321772Sjl139090 			nl = GETSTRUCT(struct memlist, 1);
4331772Sjl139090 			nl->address = base;
4341772Sjl139090 			nl->size = len;
4351772Sjl139090 			nl->next = ml;
4361772Sjl139090 			if ((nl->prev = ml->prev) != NULL)
4371772Sjl139090 				nl->prev->next = nl;
4381772Sjl139090 			ml->prev = nl;
4391772Sjl139090 			if (mlist == ml)
4401772Sjl139090 				mlist = nl;
4411772Sjl139090 			break;
4421772Sjl139090 		}
4431772Sjl139090 	}
4441772Sjl139090 
4451772Sjl139090 	if (ml == NULL) {
4461772Sjl139090 		nl = GETSTRUCT(struct memlist, 1);
4471772Sjl139090 		nl->address = base;
4481772Sjl139090 		nl->size = len;
4491772Sjl139090 		nl->next = NULL;
4501772Sjl139090 		nl->prev = tl;
4511772Sjl139090 		tl->next = nl;
4521772Sjl139090 	}
4531772Sjl139090 
4541772Sjl139090 	return (mlist);
4551772Sjl139090 }
456