1*12004Sjiang.liu@intel.com /*
2*12004Sjiang.liu@intel.com * CDDL HEADER START
3*12004Sjiang.liu@intel.com *
4*12004Sjiang.liu@intel.com * The contents of this file are subject to the terms of the
5*12004Sjiang.liu@intel.com * Common Development and Distribution License (the "License").
6*12004Sjiang.liu@intel.com * You may not use this file except in compliance with the License.
7*12004Sjiang.liu@intel.com *
8*12004Sjiang.liu@intel.com * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12004Sjiang.liu@intel.com * or http://www.opensolaris.org/os/licensing.
10*12004Sjiang.liu@intel.com * See the License for the specific language governing permissions
11*12004Sjiang.liu@intel.com * and limitations under the License.
12*12004Sjiang.liu@intel.com *
13*12004Sjiang.liu@intel.com * When distributing Covered Code, include this CDDL HEADER in each
14*12004Sjiang.liu@intel.com * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12004Sjiang.liu@intel.com * If applicable, add the following below this CDDL HEADER, with the
16*12004Sjiang.liu@intel.com * fields enclosed by brackets "[]" replaced with your own identifying
17*12004Sjiang.liu@intel.com * information: Portions Copyright [yyyy] [name of copyright owner]
18*12004Sjiang.liu@intel.com *
19*12004Sjiang.liu@intel.com * CDDL HEADER END
20*12004Sjiang.liu@intel.com */
21*12004Sjiang.liu@intel.com
22*12004Sjiang.liu@intel.com /*
23*12004Sjiang.liu@intel.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24*12004Sjiang.liu@intel.com * Use is subject to license terms.
25*12004Sjiang.liu@intel.com */
26*12004Sjiang.liu@intel.com
27*12004Sjiang.liu@intel.com #include <sys/types.h>
28*12004Sjiang.liu@intel.com #include <sys/cmn_err.h>
29*12004Sjiang.liu@intel.com #include <sys/param.h> /* for NULL */
30*12004Sjiang.liu@intel.com #include <sys/sbd_ioctl.h>
31*12004Sjiang.liu@intel.com #include <sys/dr_util.h>
32*12004Sjiang.liu@intel.com #include <sys/varargs.h>
33*12004Sjiang.liu@intel.com #include <sys/sysmacros.h>
34*12004Sjiang.liu@intel.com #include <sys/systm.h>
35*12004Sjiang.liu@intel.com
36*12004Sjiang.liu@intel.com /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */
37*12004Sjiang.liu@intel.com extern sbd_etab_t sbd_etab[];
38*12004Sjiang.liu@intel.com extern int sbd_etab_len;
39*12004Sjiang.liu@intel.com
40*12004Sjiang.liu@intel.com sbd_error_t *
sbd_err_new(int e_code,char * fmt,va_list args)41*12004Sjiang.liu@intel.com sbd_err_new(int e_code, char *fmt, va_list args)
42*12004Sjiang.liu@intel.com {
43*12004Sjiang.liu@intel.com sbd_error_t *new;
44*12004Sjiang.liu@intel.com
45*12004Sjiang.liu@intel.com new = GETSTRUCT(sbd_error_t, 1);
46*12004Sjiang.liu@intel.com new->e_code = e_code;
47*12004Sjiang.liu@intel.com
48*12004Sjiang.liu@intel.com if (fmt)
49*12004Sjiang.liu@intel.com (void) vsnprintf(new->e_rsc, sizeof (new->e_rsc), fmt, args);
50*12004Sjiang.liu@intel.com
51*12004Sjiang.liu@intel.com return (new);
52*12004Sjiang.liu@intel.com }
53*12004Sjiang.liu@intel.com
54*12004Sjiang.liu@intel.com void
sbd_err_log(sbd_error_t * ep,int ce)55*12004Sjiang.liu@intel.com sbd_err_log(sbd_error_t *ep, int ce)
56*12004Sjiang.liu@intel.com {
57*12004Sjiang.liu@intel.com char buf[32];
58*12004Sjiang.liu@intel.com char *fmt;
59*12004Sjiang.liu@intel.com char *txt;
60*12004Sjiang.liu@intel.com int i;
61*12004Sjiang.liu@intel.com sbd_etab_t *tp;
62*12004Sjiang.liu@intel.com
63*12004Sjiang.liu@intel.com if (!ep)
64*12004Sjiang.liu@intel.com return;
65*12004Sjiang.liu@intel.com
66*12004Sjiang.liu@intel.com if (ep->e_rsc[0] == '\0')
67*12004Sjiang.liu@intel.com fmt = "%s";
68*12004Sjiang.liu@intel.com else
69*12004Sjiang.liu@intel.com fmt = "%s: %s";
70*12004Sjiang.liu@intel.com
71*12004Sjiang.liu@intel.com for (tp = sbd_etab, i = 0; i < sbd_etab_len; i++, tp++)
72*12004Sjiang.liu@intel.com if (ep->e_code >= tp->t_base && ep->e_code <= tp->t_bnd)
73*12004Sjiang.liu@intel.com break;
74*12004Sjiang.liu@intel.com
75*12004Sjiang.liu@intel.com if (i < sbd_etab_len)
76*12004Sjiang.liu@intel.com txt = tp->t_text[ep->e_code - tp->t_base];
77*12004Sjiang.liu@intel.com else {
78*12004Sjiang.liu@intel.com (void) snprintf(buf, sizeof (buf), "error %d", ep->e_code);
79*12004Sjiang.liu@intel.com txt = buf;
80*12004Sjiang.liu@intel.com }
81*12004Sjiang.liu@intel.com
82*12004Sjiang.liu@intel.com cmn_err(ce, fmt, txt, ep->e_rsc);
83*12004Sjiang.liu@intel.com }
84*12004Sjiang.liu@intel.com
85*12004Sjiang.liu@intel.com void
sbd_err_clear(sbd_error_t ** ep)86*12004Sjiang.liu@intel.com sbd_err_clear(sbd_error_t **ep)
87*12004Sjiang.liu@intel.com {
88*12004Sjiang.liu@intel.com FREESTRUCT(*ep, sbd_error_t, 1);
89*12004Sjiang.liu@intel.com *ep = NULL;
90*12004Sjiang.liu@intel.com }
91*12004Sjiang.liu@intel.com
92*12004Sjiang.liu@intel.com void
sbd_err_set_c(sbd_error_t ** ep,int ce,int e_code,char * fmt,...)93*12004Sjiang.liu@intel.com sbd_err_set_c(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
94*12004Sjiang.liu@intel.com {
95*12004Sjiang.liu@intel.com sbd_error_t *tmp;
96*12004Sjiang.liu@intel.com va_list args;
97*12004Sjiang.liu@intel.com
98*12004Sjiang.liu@intel.com va_start(args, fmt);
99*12004Sjiang.liu@intel.com
100*12004Sjiang.liu@intel.com tmp = sbd_err_new(e_code, fmt, args);
101*12004Sjiang.liu@intel.com
102*12004Sjiang.liu@intel.com sbd_err_log(tmp, ce);
103*12004Sjiang.liu@intel.com
104*12004Sjiang.liu@intel.com if (*ep == NULL)
105*12004Sjiang.liu@intel.com *ep = tmp;
106*12004Sjiang.liu@intel.com else
107*12004Sjiang.liu@intel.com sbd_err_clear(&tmp);
108*12004Sjiang.liu@intel.com
109*12004Sjiang.liu@intel.com va_end(args);
110*12004Sjiang.liu@intel.com }
111*12004Sjiang.liu@intel.com
112*12004Sjiang.liu@intel.com void
sbd_err_set(sbd_error_t ** ep,int ce,int e_code,char * fmt,...)113*12004Sjiang.liu@intel.com sbd_err_set(sbd_error_t **ep, int ce, int e_code, char *fmt, ...)
114*12004Sjiang.liu@intel.com {
115*12004Sjiang.liu@intel.com sbd_error_t *tmp;
116*12004Sjiang.liu@intel.com va_list args;
117*12004Sjiang.liu@intel.com
118*12004Sjiang.liu@intel.com va_start(args, fmt);
119*12004Sjiang.liu@intel.com
120*12004Sjiang.liu@intel.com tmp = sbd_err_new(e_code, fmt, args);
121*12004Sjiang.liu@intel.com
122*12004Sjiang.liu@intel.com sbd_err_log(tmp, ce);
123*12004Sjiang.liu@intel.com
124*12004Sjiang.liu@intel.com *ep = tmp;
125*12004Sjiang.liu@intel.com
126*12004Sjiang.liu@intel.com va_end(args);
127*12004Sjiang.liu@intel.com }
128*12004Sjiang.liu@intel.com
129*12004Sjiang.liu@intel.com sbd_error_t *
drerr_new_v(int e_code,char * fmt,va_list args)130*12004Sjiang.liu@intel.com drerr_new_v(int e_code, char *fmt, va_list args)
131*12004Sjiang.liu@intel.com {
132*12004Sjiang.liu@intel.com return (sbd_err_new(e_code, fmt, args));
133*12004Sjiang.liu@intel.com }
134*12004Sjiang.liu@intel.com
135*12004Sjiang.liu@intel.com sbd_error_t *
drerr_new(int log,int e_code,char * fmt,...)136*12004Sjiang.liu@intel.com drerr_new(int log, int e_code, char *fmt, ...)
137*12004Sjiang.liu@intel.com {
138*12004Sjiang.liu@intel.com sbd_error_t *ep;
139*12004Sjiang.liu@intel.com va_list args;
140*12004Sjiang.liu@intel.com
141*12004Sjiang.liu@intel.com va_start(args, fmt);
142*12004Sjiang.liu@intel.com ep = sbd_err_new(e_code, fmt, args);
143*12004Sjiang.liu@intel.com va_end(args);
144*12004Sjiang.liu@intel.com
145*12004Sjiang.liu@intel.com if (log)
146*12004Sjiang.liu@intel.com sbd_err_log(ep, CE_WARN);
147*12004Sjiang.liu@intel.com
148*12004Sjiang.liu@intel.com return (ep);
149*12004Sjiang.liu@intel.com }
150*12004Sjiang.liu@intel.com
151*12004Sjiang.liu@intel.com void
drerr_set_c(int log,sbd_error_t ** ep,int e_code,char * fmt,...)152*12004Sjiang.liu@intel.com drerr_set_c(int log, sbd_error_t **ep, int e_code, char *fmt, ...)
153*12004Sjiang.liu@intel.com {
154*12004Sjiang.liu@intel.com sbd_error_t *err;
155*12004Sjiang.liu@intel.com va_list args;
156*12004Sjiang.liu@intel.com
157*12004Sjiang.liu@intel.com va_start(args, fmt);
158*12004Sjiang.liu@intel.com err = sbd_err_new(e_code, fmt, args);
159*12004Sjiang.liu@intel.com va_end(args);
160*12004Sjiang.liu@intel.com
161*12004Sjiang.liu@intel.com if (log)
162*12004Sjiang.liu@intel.com sbd_err_log(err, CE_WARN);
163*12004Sjiang.liu@intel.com
164*12004Sjiang.liu@intel.com if (*ep == NULL)
165*12004Sjiang.liu@intel.com *ep = err;
166*12004Sjiang.liu@intel.com else
167*12004Sjiang.liu@intel.com sbd_err_clear(&err);
168*12004Sjiang.liu@intel.com }
169*12004Sjiang.liu@intel.com
170*12004Sjiang.liu@intel.com
171*12004Sjiang.liu@intel.com /*
172*12004Sjiang.liu@intel.com * Memlist support.
173*12004Sjiang.liu@intel.com */
174*12004Sjiang.liu@intel.com void
dr_memlist_delete(struct memlist * mlist)175*12004Sjiang.liu@intel.com dr_memlist_delete(struct memlist *mlist)
176*12004Sjiang.liu@intel.com {
177*12004Sjiang.liu@intel.com register struct memlist *ml;
178*12004Sjiang.liu@intel.com
179*12004Sjiang.liu@intel.com for (ml = mlist; ml; ml = mlist) {
180*12004Sjiang.liu@intel.com mlist = ml->ml_next;
181*12004Sjiang.liu@intel.com FREESTRUCT(ml, struct memlist, 1);
182*12004Sjiang.liu@intel.com }
183*12004Sjiang.liu@intel.com }
184*12004Sjiang.liu@intel.com
185*12004Sjiang.liu@intel.com int
dr_memlist_intersect(struct memlist * al,struct memlist * bl)186*12004Sjiang.liu@intel.com dr_memlist_intersect(struct memlist *al, struct memlist *bl)
187*12004Sjiang.liu@intel.com {
188*12004Sjiang.liu@intel.com uint64_t astart, aend, bstart, bend;
189*12004Sjiang.liu@intel.com
190*12004Sjiang.liu@intel.com if ((al == NULL) || (bl == NULL))
191*12004Sjiang.liu@intel.com return (0);
192*12004Sjiang.liu@intel.com
193*12004Sjiang.liu@intel.com aend = al->ml_address + al->ml_size;
194*12004Sjiang.liu@intel.com bstart = bl->ml_address;
195*12004Sjiang.liu@intel.com bend = bl->ml_address + bl->ml_size;
196*12004Sjiang.liu@intel.com
197*12004Sjiang.liu@intel.com while (al && bl) {
198*12004Sjiang.liu@intel.com while (al && (aend <= bstart))
199*12004Sjiang.liu@intel.com if ((al = al->ml_next) != NULL)
200*12004Sjiang.liu@intel.com aend = al->ml_address + al->ml_size;
201*12004Sjiang.liu@intel.com if (al == NULL)
202*12004Sjiang.liu@intel.com return (0);
203*12004Sjiang.liu@intel.com
204*12004Sjiang.liu@intel.com if ((astart = al->ml_address) <= bstart)
205*12004Sjiang.liu@intel.com return (1);
206*12004Sjiang.liu@intel.com
207*12004Sjiang.liu@intel.com while (bl && (bend <= astart))
208*12004Sjiang.liu@intel.com if ((bl = bl->ml_next) != NULL)
209*12004Sjiang.liu@intel.com bend = bl->ml_address + bl->ml_size;
210*12004Sjiang.liu@intel.com if (bl == NULL)
211*12004Sjiang.liu@intel.com return (0);
212*12004Sjiang.liu@intel.com
213*12004Sjiang.liu@intel.com if ((bstart = bl->ml_address) <= astart)
214*12004Sjiang.liu@intel.com return (1);
215*12004Sjiang.liu@intel.com }
216*12004Sjiang.liu@intel.com
217*12004Sjiang.liu@intel.com return (0);
218*12004Sjiang.liu@intel.com }
219*12004Sjiang.liu@intel.com
220*12004Sjiang.liu@intel.com void
dr_memlist_coalesce(struct memlist * mlist)221*12004Sjiang.liu@intel.com dr_memlist_coalesce(struct memlist *mlist)
222*12004Sjiang.liu@intel.com {
223*12004Sjiang.liu@intel.com uint64_t end, nend;
224*12004Sjiang.liu@intel.com
225*12004Sjiang.liu@intel.com if ((mlist == NULL) || (mlist->ml_next == NULL))
226*12004Sjiang.liu@intel.com return;
227*12004Sjiang.liu@intel.com
228*12004Sjiang.liu@intel.com while (mlist->ml_next) {
229*12004Sjiang.liu@intel.com end = mlist->ml_address + mlist->ml_size;
230*12004Sjiang.liu@intel.com if (mlist->ml_next->ml_address <= end) {
231*12004Sjiang.liu@intel.com struct memlist *nl;
232*12004Sjiang.liu@intel.com
233*12004Sjiang.liu@intel.com nend = mlist->ml_next->ml_address +
234*12004Sjiang.liu@intel.com mlist->ml_next->ml_size;
235*12004Sjiang.liu@intel.com if (nend > end)
236*12004Sjiang.liu@intel.com mlist->ml_size += (nend - end);
237*12004Sjiang.liu@intel.com nl = mlist->ml_next;
238*12004Sjiang.liu@intel.com mlist->ml_next = mlist->ml_next->ml_next;
239*12004Sjiang.liu@intel.com if (nl) {
240*12004Sjiang.liu@intel.com FREESTRUCT(nl, struct memlist, 1);
241*12004Sjiang.liu@intel.com }
242*12004Sjiang.liu@intel.com if (mlist->ml_next)
243*12004Sjiang.liu@intel.com mlist->ml_next->ml_prev = mlist;
244*12004Sjiang.liu@intel.com } else {
245*12004Sjiang.liu@intel.com mlist = mlist->ml_next;
246*12004Sjiang.liu@intel.com }
247*12004Sjiang.liu@intel.com }
248*12004Sjiang.liu@intel.com }
249*12004Sjiang.liu@intel.com
250*12004Sjiang.liu@intel.com #ifdef DEBUG
251*12004Sjiang.liu@intel.com void
memlist_dump(struct memlist * mlist)252*12004Sjiang.liu@intel.com memlist_dump(struct memlist *mlist)
253*12004Sjiang.liu@intel.com {
254*12004Sjiang.liu@intel.com register struct memlist *ml;
255*12004Sjiang.liu@intel.com
256*12004Sjiang.liu@intel.com if (mlist == NULL)
257*12004Sjiang.liu@intel.com printf("memlist> EMPTY\n");
258*12004Sjiang.liu@intel.com else for (ml = mlist; ml; ml = ml->ml_next)
259*12004Sjiang.liu@intel.com printf("memlist> 0x%" PRIx64 ", 0x%" PRIx64 "\n",
260*12004Sjiang.liu@intel.com ml->ml_address, ml->ml_size);
261*12004Sjiang.liu@intel.com }
262*12004Sjiang.liu@intel.com #endif
263*12004Sjiang.liu@intel.com
264*12004Sjiang.liu@intel.com struct memlist *
dr_memlist_dup(struct memlist * mlist)265*12004Sjiang.liu@intel.com dr_memlist_dup(struct memlist *mlist)
266*12004Sjiang.liu@intel.com {
267*12004Sjiang.liu@intel.com struct memlist *hl = NULL, *tl, **mlp;
268*12004Sjiang.liu@intel.com
269*12004Sjiang.liu@intel.com if (mlist == NULL)
270*12004Sjiang.liu@intel.com return (NULL);
271*12004Sjiang.liu@intel.com
272*12004Sjiang.liu@intel.com mlp = &hl;
273*12004Sjiang.liu@intel.com tl = *mlp;
274*12004Sjiang.liu@intel.com for (; mlist; mlist = mlist->ml_next) {
275*12004Sjiang.liu@intel.com *mlp = GETSTRUCT(struct memlist, 1);
276*12004Sjiang.liu@intel.com (*mlp)->ml_address = mlist->ml_address;
277*12004Sjiang.liu@intel.com (*mlp)->ml_size = mlist->ml_size;
278*12004Sjiang.liu@intel.com (*mlp)->ml_prev = tl;
279*12004Sjiang.liu@intel.com tl = *mlp;
280*12004Sjiang.liu@intel.com mlp = &((*mlp)->ml_next);
281*12004Sjiang.liu@intel.com }
282*12004Sjiang.liu@intel.com *mlp = NULL;
283*12004Sjiang.liu@intel.com
284*12004Sjiang.liu@intel.com return (hl);
285*12004Sjiang.liu@intel.com }
286*12004Sjiang.liu@intel.com
287*12004Sjiang.liu@intel.com struct memlist *
dr_memlist_add_span(struct memlist * mlist,uint64_t base,uint64_t len)288*12004Sjiang.liu@intel.com dr_memlist_add_span(struct memlist *mlist, uint64_t base, uint64_t len)
289*12004Sjiang.liu@intel.com {
290*12004Sjiang.liu@intel.com struct memlist *ml, *tl, *nl;
291*12004Sjiang.liu@intel.com
292*12004Sjiang.liu@intel.com if (len == 0ull)
293*12004Sjiang.liu@intel.com return (NULL);
294*12004Sjiang.liu@intel.com
295*12004Sjiang.liu@intel.com if (mlist == NULL) {
296*12004Sjiang.liu@intel.com mlist = GETSTRUCT(struct memlist, 1);
297*12004Sjiang.liu@intel.com mlist->ml_address = base;
298*12004Sjiang.liu@intel.com mlist->ml_size = len;
299*12004Sjiang.liu@intel.com mlist->ml_next = mlist->ml_prev = NULL;
300*12004Sjiang.liu@intel.com
301*12004Sjiang.liu@intel.com return (mlist);
302*12004Sjiang.liu@intel.com }
303*12004Sjiang.liu@intel.com
304*12004Sjiang.liu@intel.com for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) {
305*12004Sjiang.liu@intel.com if (base < ml->ml_address) {
306*12004Sjiang.liu@intel.com if ((base + len) < ml->ml_address) {
307*12004Sjiang.liu@intel.com nl = GETSTRUCT(struct memlist, 1);
308*12004Sjiang.liu@intel.com nl->ml_address = base;
309*12004Sjiang.liu@intel.com nl->ml_size = len;
310*12004Sjiang.liu@intel.com nl->ml_next = ml;
311*12004Sjiang.liu@intel.com if ((nl->ml_prev = ml->ml_prev) != NULL)
312*12004Sjiang.liu@intel.com nl->ml_prev->ml_next = nl;
313*12004Sjiang.liu@intel.com ml->ml_prev = nl;
314*12004Sjiang.liu@intel.com if (mlist == ml)
315*12004Sjiang.liu@intel.com mlist = nl;
316*12004Sjiang.liu@intel.com } else {
317*12004Sjiang.liu@intel.com ml->ml_size = MAX((base + len),
318*12004Sjiang.liu@intel.com (ml->ml_address + ml->ml_size)) - base;
319*12004Sjiang.liu@intel.com ml->ml_address = base;
320*12004Sjiang.liu@intel.com }
321*12004Sjiang.liu@intel.com break;
322*12004Sjiang.liu@intel.com
323*12004Sjiang.liu@intel.com } else if (base <= (ml->ml_address + ml->ml_size)) {
324*12004Sjiang.liu@intel.com ml->ml_size = MAX((base + len),
325*12004Sjiang.liu@intel.com (ml->ml_address + ml->ml_size)) -
326*12004Sjiang.liu@intel.com MIN(ml->ml_address, base);
327*12004Sjiang.liu@intel.com ml->ml_address = MIN(ml->ml_address, base);
328*12004Sjiang.liu@intel.com break;
329*12004Sjiang.liu@intel.com }
330*12004Sjiang.liu@intel.com }
331*12004Sjiang.liu@intel.com if (ml == NULL) {
332*12004Sjiang.liu@intel.com nl = GETSTRUCT(struct memlist, 1);
333*12004Sjiang.liu@intel.com nl->ml_address = base;
334*12004Sjiang.liu@intel.com nl->ml_size = len;
335*12004Sjiang.liu@intel.com nl->ml_next = NULL;
336*12004Sjiang.liu@intel.com nl->ml_prev = tl;
337*12004Sjiang.liu@intel.com tl->ml_next = nl;
338*12004Sjiang.liu@intel.com }
339*12004Sjiang.liu@intel.com
340*12004Sjiang.liu@intel.com dr_memlist_coalesce(mlist);
341*12004Sjiang.liu@intel.com
342*12004Sjiang.liu@intel.com return (mlist);
343*12004Sjiang.liu@intel.com }
344*12004Sjiang.liu@intel.com
345*12004Sjiang.liu@intel.com struct memlist *
dr_memlist_del_span(struct memlist * mlist,uint64_t base,uint64_t len)346*12004Sjiang.liu@intel.com dr_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len)
347*12004Sjiang.liu@intel.com {
348*12004Sjiang.liu@intel.com uint64_t end;
349*12004Sjiang.liu@intel.com struct memlist *ml, *tl, *nlp;
350*12004Sjiang.liu@intel.com
351*12004Sjiang.liu@intel.com if (mlist == NULL)
352*12004Sjiang.liu@intel.com return (NULL);
353*12004Sjiang.liu@intel.com
354*12004Sjiang.liu@intel.com end = base + len;
355*12004Sjiang.liu@intel.com if ((end <= mlist->ml_address) || (base == end))
356*12004Sjiang.liu@intel.com return (mlist);
357*12004Sjiang.liu@intel.com
358*12004Sjiang.liu@intel.com for (tl = ml = mlist; ml; tl = ml, ml = nlp) {
359*12004Sjiang.liu@intel.com uint64_t mend;
360*12004Sjiang.liu@intel.com
361*12004Sjiang.liu@intel.com nlp = ml->ml_next;
362*12004Sjiang.liu@intel.com
363*12004Sjiang.liu@intel.com if (end <= ml->ml_address)
364*12004Sjiang.liu@intel.com break;
365*12004Sjiang.liu@intel.com
366*12004Sjiang.liu@intel.com mend = ml->ml_address + ml->ml_size;
367*12004Sjiang.liu@intel.com if (base < mend) {
368*12004Sjiang.liu@intel.com if (base <= ml->ml_address) {
369*12004Sjiang.liu@intel.com ml->ml_address = end;
370*12004Sjiang.liu@intel.com if (end >= mend)
371*12004Sjiang.liu@intel.com ml->ml_size = 0ull;
372*12004Sjiang.liu@intel.com else
373*12004Sjiang.liu@intel.com ml->ml_size = mend - ml->ml_address;
374*12004Sjiang.liu@intel.com } else {
375*12004Sjiang.liu@intel.com ml->ml_size = base - ml->ml_address;
376*12004Sjiang.liu@intel.com if (end < mend) {
377*12004Sjiang.liu@intel.com struct memlist *nl;
378*12004Sjiang.liu@intel.com /*
379*12004Sjiang.liu@intel.com * splitting an memlist entry.
380*12004Sjiang.liu@intel.com */
381*12004Sjiang.liu@intel.com nl = GETSTRUCT(struct memlist, 1);
382*12004Sjiang.liu@intel.com nl->ml_address = end;
383*12004Sjiang.liu@intel.com nl->ml_size = mend - nl->ml_address;
384*12004Sjiang.liu@intel.com if ((nl->ml_next = nlp) != NULL)
385*12004Sjiang.liu@intel.com nlp->ml_prev = nl;
386*12004Sjiang.liu@intel.com nl->ml_prev = ml;
387*12004Sjiang.liu@intel.com ml->ml_next = nl;
388*12004Sjiang.liu@intel.com nlp = nl;
389*12004Sjiang.liu@intel.com }
390*12004Sjiang.liu@intel.com }
391*12004Sjiang.liu@intel.com if (ml->ml_size == 0ull) {
392*12004Sjiang.liu@intel.com if (ml == mlist) {
393*12004Sjiang.liu@intel.com if ((mlist = nlp) != NULL)
394*12004Sjiang.liu@intel.com nlp->ml_prev = NULL;
395*12004Sjiang.liu@intel.com FREESTRUCT(ml, struct memlist, 1);
396*12004Sjiang.liu@intel.com if (mlist == NULL)
397*12004Sjiang.liu@intel.com break;
398*12004Sjiang.liu@intel.com ml = nlp;
399*12004Sjiang.liu@intel.com } else {
400*12004Sjiang.liu@intel.com if ((tl->ml_next = nlp) != NULL)
401*12004Sjiang.liu@intel.com nlp->ml_prev = tl;
402*12004Sjiang.liu@intel.com FREESTRUCT(ml, struct memlist, 1);
403*12004Sjiang.liu@intel.com ml = tl;
404*12004Sjiang.liu@intel.com }
405*12004Sjiang.liu@intel.com }
406*12004Sjiang.liu@intel.com }
407*12004Sjiang.liu@intel.com }
408*12004Sjiang.liu@intel.com
409*12004Sjiang.liu@intel.com return (mlist);
410*12004Sjiang.liu@intel.com }
411*12004Sjiang.liu@intel.com
412*12004Sjiang.liu@intel.com /*
413*12004Sjiang.liu@intel.com * add span without merging
414*12004Sjiang.liu@intel.com */
415*12004Sjiang.liu@intel.com struct memlist *
dr_memlist_cat_span(struct memlist * mlist,uint64_t base,uint64_t len)416*12004Sjiang.liu@intel.com dr_memlist_cat_span(struct memlist *mlist, uint64_t base, uint64_t len)
417*12004Sjiang.liu@intel.com {
418*12004Sjiang.liu@intel.com struct memlist *ml, *tl, *nl;
419*12004Sjiang.liu@intel.com
420*12004Sjiang.liu@intel.com if (len == 0ull)
421*12004Sjiang.liu@intel.com return (NULL);
422*12004Sjiang.liu@intel.com
423*12004Sjiang.liu@intel.com if (mlist == NULL) {
424*12004Sjiang.liu@intel.com mlist = GETSTRUCT(struct memlist, 1);
425*12004Sjiang.liu@intel.com mlist->ml_address = base;
426*12004Sjiang.liu@intel.com mlist->ml_size = len;
427*12004Sjiang.liu@intel.com mlist->ml_next = mlist->ml_prev = NULL;
428*12004Sjiang.liu@intel.com
429*12004Sjiang.liu@intel.com return (mlist);
430*12004Sjiang.liu@intel.com }
431*12004Sjiang.liu@intel.com
432*12004Sjiang.liu@intel.com for (tl = ml = mlist; ml; tl = ml, ml = ml->ml_next) {
433*12004Sjiang.liu@intel.com if (base < ml->ml_address) {
434*12004Sjiang.liu@intel.com nl = GETSTRUCT(struct memlist, 1);
435*12004Sjiang.liu@intel.com nl->ml_address = base;
436*12004Sjiang.liu@intel.com nl->ml_size = len;
437*12004Sjiang.liu@intel.com nl->ml_next = ml;
438*12004Sjiang.liu@intel.com if ((nl->ml_prev = ml->ml_prev) != NULL)
439*12004Sjiang.liu@intel.com nl->ml_prev->ml_next = nl;
440*12004Sjiang.liu@intel.com ml->ml_prev = nl;
441*12004Sjiang.liu@intel.com if (mlist == ml)
442*12004Sjiang.liu@intel.com mlist = nl;
443*12004Sjiang.liu@intel.com break;
444*12004Sjiang.liu@intel.com }
445*12004Sjiang.liu@intel.com }
446*12004Sjiang.liu@intel.com
447*12004Sjiang.liu@intel.com if (ml == NULL) {
448*12004Sjiang.liu@intel.com nl = GETSTRUCT(struct memlist, 1);
449*12004Sjiang.liu@intel.com nl->ml_address = base;
450*12004Sjiang.liu@intel.com nl->ml_size = len;
451*12004Sjiang.liu@intel.com nl->ml_next = NULL;
452*12004Sjiang.liu@intel.com nl->ml_prev = tl;
453*12004Sjiang.liu@intel.com tl->ml_next = nl;
454*12004Sjiang.liu@intel.com }
455*12004Sjiang.liu@intel.com
456*12004Sjiang.liu@intel.com return (mlist);
457*12004Sjiang.liu@intel.com }
458