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 *
sbd_err_new(int e_code,char * fmt,va_list args)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
sbd_err_log(sbd_error_t * ep,int ce)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
sbd_err_clear(sbd_error_t ** ep)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
sbd_err_set_c(sbd_error_t ** ep,int ce,int e_code,char * fmt,...)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
sbd_err_set(sbd_error_t ** ep,int ce,int e_code,char * fmt,...)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 *
drerr_new_v(int e_code,char * fmt,va_list args)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 *
drerr_new(int log,int e_code,char * fmt,...)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
drerr_set_c(int log,sbd_error_t ** ep,int e_code,char * fmt,...)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
dr_memlist_delete(struct memlist * mlist)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
dr_memlist_intersect(struct memlist * al,struct memlist * bl)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
dr_memlist_coalesce(struct memlist * mlist)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
memlist_dump(struct memlist * mlist)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 *
dr_memlist_dup(struct memlist * mlist)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 *
dr_memlist_add_span(struct memlist * mlist,uint64_t base,uint64_t len)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 *
dr_memlist_del_span(struct memlist * mlist,uint64_t base,uint64_t len)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 *
dr_memlist_cat_span(struct memlist * mlist,uint64_t base,uint64_t len)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