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